changeset 61:88bb47e3a401

Asynchronous drawing (first working version).
author Mikhail Kryshen <mikhail@kryshen.net>
date Wed, 25 Aug 2010 22:03:01 +0400
parents 7e456697924d
children 44a7acf60c16
files src/net/kryshen/indyvon/core.clj src/net/kryshen/indyvon/demo.clj src/net/kryshen/indyvon/layers.clj
diffstat 3 files changed, 47 insertions(+), 32 deletions(-) [+]
line diff
     1.1 --- a/src/net/kryshen/indyvon/core.clj	Mon Aug 23 21:24:33 2010 +0400
     1.2 +++ b/src/net/kryshen/indyvon/core.clj	Wed Aug 25 22:03:01 2010 +0400
     1.3 @@ -138,10 +138,12 @@
     1.4  (defn- ^Graphics2D apply-theme
     1.5    "Set graphics' color and font to match theme.
     1.6     Modifies and returns the first argument."
     1.7 -  [^Graphics2D graphics theme]
     1.8 +  ([]
     1.9 +     (apply-theme *graphics* *theme*))
    1.10 +  ([^Graphics2D graphics theme]
    1.11    (doto graphics
    1.12      (.setColor (:fore-color theme))
    1.13 -    (.setFont (:font theme))))
    1.14 +    (.setFont (:font theme)))))
    1.15  
    1.16  (defn- ^Graphics2D create-graphics
    1.17    ([]
    1.18 @@ -243,7 +245,7 @@
    1.19  (defn context-draw!
    1.20    "Sets up layer context, draws layer and commits event dispatcher."
    1.21    ([layer graphics event-dispatcher update-fn width height]
    1.22 -     (draw! layer nil graphics event-dispatcher update-fn width height))
    1.23 +     (context-draw! layer nil graphics event-dispatcher update-fn width height))
    1.24    ([layer component ^Graphics2D graphics event-dispatcher update-fn
    1.25      width height]
    1.26       (binding [*graphics* graphics
    1.27 @@ -257,6 +259,7 @@
    1.28                 *width* width
    1.29                 *height* height
    1.30                 *clip* (Rectangle2D$Double. 0 0 width height)]
    1.31 +       (apply-theme)
    1.32         (render! layer)
    1.33         (commit event-dispatcher))))
    1.34  
     2.1 --- a/src/net/kryshen/indyvon/demo.clj	Mon Aug 23 21:24:33 2010 +0400
     2.2 +++ b/src/net/kryshen/indyvon/demo.clj	Wed Aug 25 22:03:01 2010 +0400
     2.3 @@ -21,7 +21,7 @@
     2.4        (render! [layer]
     2.5           (with-handlers layer
     2.6             (doto *graphics*
     2.7 -             (.setColor Color/RED)
     2.8 +             (.setColor (rand-nth [Color/RED Color/ORANGE]))
     2.9               (.fillRect 0 0 *width* *height*))
    2.10             (:mouse-entered e (println e))
    2.11             (:mouse-exited e (println e))
    2.12 @@ -30,6 +30,8 @@
    2.13  
    2.14  (def layer1b (border layer1 2 3))
    2.15  
    2.16 +(def layer1c (async-layer layer1 20 30))
    2.17 +
    2.18  (def layer2
    2.19       (reify
    2.20        Layer
    2.21 @@ -39,7 +41,7 @@
    2.22             (.fillRect 0 0 *width* *height*))
    2.23           (with-rotate 0.5 0 0
    2.24             (draw! layer1b 30 25))
    2.25 -         (draw! layer1 55 5))
    2.26 +         (draw! layer1c 55 5))
    2.27        (layer-size [layer] (Size. 70 65))))
    2.28  
    2.29  (def layer3
    2.30 @@ -71,7 +73,7 @@
    2.31       (reify
    2.32        Layer
    2.33        (render! [layer]
    2.34 -         (*update*)
    2.35 +         ;;(*update*)
    2.36           (doto *graphics*
    2.37             (.setColor (rand-nth [Color/BLACK Color/BLUE Color/RED]))
    2.38             (.drawLine 0 0 *width* *height*))
     3.1 --- a/src/net/kryshen/indyvon/layers.clj	Mon Aug 23 21:24:33 2010 +0400
     3.2 +++ b/src/net/kryshen/indyvon/layers.clj	Wed Aug 25 22:03:01 2010 +0400
     3.3 @@ -177,46 +177,56 @@
     3.4    "Creates layer that draws the content asynchroniously in an
     3.5     offscreen buffer."
     3.6    [content width height]
     3.7 -  ;; TODO: dynamic size.
     3.8 -  (let [executor (ThreadPoolExecutor. 1 1 0 TimeUnit/SECONDS
     3.9 +  (let [executor (ThreadPoolExecutor. (int 1) (int 1) (long 0) TimeUnit/SECONDS
    3.10                     (ArrayBlockingQueue. 1)
    3.11                     (ThreadPoolExecutor$DiscardOldestPolicy.))
    3.12 -        buffers (ref [nil nil])
    3.13 +        buffers (ref nil)
    3.14          updated (ref false)
    3.15 +        update-fn (ref nil)
    3.16          create-buffer
    3.17            #(BufferedImage. width height BufferedImage/TYPE_INT_ARGB)
    3.18          draw-offscreen
    3.19            (fn draw-offscreen []
    3.20 -            (let [b (dosync (let [b (peek @buffers)]
    3.21 +            ;;(Thread/sleep 3000)
    3.22 +            (let [^Image b (dosync
    3.23 +                            (let [b (peek @buffers)]
    3.24                                (alter buffers pop)
    3.25                                b))]
    3.26 -              ;; TODO: use operational event dispatcher.
    3.27 -              (context-draw! (.getGraphics b)
    3.28 -                             dummy-event-dispatcher
    3.29 -                             #(.execute executor draw-offscreen)
    3.30 -                             width height)
    3.31 -              (dosync
    3.32 -               (alter buffers conj b)
    3.33 -               (ref-set updated true))))]
    3.34 +              (try
    3.35 +                ;; TODO: use operational event dispatcher.
    3.36 +                (context-draw! content
    3.37 +                               (.getGraphics b)
    3.38 +                               dummy-event-dispatcher
    3.39 +                               #(.execute executor draw-offscreen)
    3.40 +                               width height)
    3.41 +                (finally
    3.42 +                 (dosync
    3.43 +                  (alter buffers conj b)
    3.44 +                  (ref-set updated true))))
    3.45 +                (update-fn)))]
    3.46      (reify
    3.47       Layer
    3.48       (render! [layer]
    3.49 +        (when-not @buffers
    3.50 +          ;; TODO: dynamic size, recreate buffers when size increases.
    3.51 +          (let [new-buffers [(create-buffer) (create-buffer)]]
    3.52 +            (dosync
    3.53 +             (ref-set buffers new-buffers)
    3.54 +             (ref-set update-fn *update*)))
    3.55 +          (.execute executor draw-offscreen))
    3.56          (let [buffer (dosync
    3.57 +                 (ref-set update-fn *update*)
    3.58                   (if @updated
    3.59 -                   (do (peek @buffers)
    3.60 -                       (alter buffers pop)
    3.61 -                       (ref-set updated false))
    3.62 -                   (do (first @buffers)
    3.63 -                       (alter buffers next))))]
    3.64 -          (when buffer
    3.65 -            (.drawImage *graphics* buffer))
    3.66 -          (let [new-buffer (or buffer (create-buffer))]
    3.67 -            (dosync
    3.68 -             (alter buffers #(cons new-buffer %)))
    3.69 -            (when (not buffer)
    3.70 -              ;; No cached image to draw.
    3.71 -              ;; TODO: draw immediately.
    3.72 -              (.execute executor draw-offscreen)))))
    3.73 +                   (let [b (peek @buffers)]
    3.74 +                     (alter buffers pop)
    3.75 +                     (ref-set updated false)
    3.76 +                     b)
    3.77 +                   (let [b (first @buffers)]
    3.78 +                     (alter buffers subvec 1)
    3.79 +                     b)))]
    3.80 +          (.drawImage *graphics* ^Image buffer 0 0 nil)
    3.81 +          (dosync
    3.82 +           (alter buffers #(vec (cons buffer %))))))
    3.83       (layer-size [layer]
    3.84          (Size. width height)))))
    3.85