Mercurial > hg > indyvon
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 wrap: on
line diff
--- a/src/net/kryshen/indyvon/core.clj Mon Aug 23 21:24:33 2010 +0400 +++ b/src/net/kryshen/indyvon/core.clj Wed Aug 25 22:03:01 2010 +0400 @@ -138,10 +138,12 @@ (defn- ^Graphics2D apply-theme "Set graphics' color and font to match theme. Modifies and returns the first argument." - [^Graphics2D graphics theme] + ([] + (apply-theme *graphics* *theme*)) + ([^Graphics2D graphics theme] (doto graphics (.setColor (:fore-color theme)) - (.setFont (:font theme)))) + (.setFont (:font theme))))) (defn- ^Graphics2D create-graphics ([] @@ -243,7 +245,7 @@ (defn context-draw! "Sets up layer context, draws layer and commits event dispatcher." ([layer graphics event-dispatcher update-fn width height] - (draw! layer nil graphics event-dispatcher update-fn width height)) + (context-draw! layer nil graphics event-dispatcher update-fn width height)) ([layer component ^Graphics2D graphics event-dispatcher update-fn width height] (binding [*graphics* graphics @@ -257,6 +259,7 @@ *width* width *height* height *clip* (Rectangle2D$Double. 0 0 width height)] + (apply-theme) (render! layer) (commit event-dispatcher))))
--- a/src/net/kryshen/indyvon/demo.clj Mon Aug 23 21:24:33 2010 +0400 +++ b/src/net/kryshen/indyvon/demo.clj Wed Aug 25 22:03:01 2010 +0400 @@ -21,7 +21,7 @@ (render! [layer] (with-handlers layer (doto *graphics* - (.setColor Color/RED) + (.setColor (rand-nth [Color/RED Color/ORANGE])) (.fillRect 0 0 *width* *height*)) (:mouse-entered e (println e)) (:mouse-exited e (println e)) @@ -30,6 +30,8 @@ (def layer1b (border layer1 2 3)) +(def layer1c (async-layer layer1 20 30)) + (def layer2 (reify Layer @@ -39,7 +41,7 @@ (.fillRect 0 0 *width* *height*)) (with-rotate 0.5 0 0 (draw! layer1b 30 25)) - (draw! layer1 55 5)) + (draw! layer1c 55 5)) (layer-size [layer] (Size. 70 65)))) (def layer3 @@ -71,7 +73,7 @@ (reify Layer (render! [layer] - (*update*) + ;;(*update*) (doto *graphics* (.setColor (rand-nth [Color/BLACK Color/BLUE Color/RED])) (.drawLine 0 0 *width* *height*))
--- a/src/net/kryshen/indyvon/layers.clj Mon Aug 23 21:24:33 2010 +0400 +++ b/src/net/kryshen/indyvon/layers.clj Wed Aug 25 22:03:01 2010 +0400 @@ -177,46 +177,56 @@ "Creates layer that draws the content asynchroniously in an offscreen buffer." [content width height] - ;; TODO: dynamic size. - (let [executor (ThreadPoolExecutor. 1 1 0 TimeUnit/SECONDS + (let [executor (ThreadPoolExecutor. (int 1) (int 1) (long 0) TimeUnit/SECONDS (ArrayBlockingQueue. 1) (ThreadPoolExecutor$DiscardOldestPolicy.)) - buffers (ref [nil nil]) + buffers (ref nil) updated (ref false) + update-fn (ref nil) create-buffer #(BufferedImage. width height BufferedImage/TYPE_INT_ARGB) draw-offscreen (fn draw-offscreen [] - (let [b (dosync (let [b (peek @buffers)] + ;;(Thread/sleep 3000) + (let [^Image b (dosync + (let [b (peek @buffers)] (alter buffers pop) b))] - ;; TODO: use operational event dispatcher. - (context-draw! (.getGraphics b) - dummy-event-dispatcher - #(.execute executor draw-offscreen) - width height) - (dosync - (alter buffers conj b) - (ref-set updated true))))] + (try + ;; TODO: use operational event dispatcher. + (context-draw! content + (.getGraphics b) + dummy-event-dispatcher + #(.execute executor draw-offscreen) + width height) + (finally + (dosync + (alter buffers conj b) + (ref-set updated true)))) + (update-fn)))] (reify Layer (render! [layer] + (when-not @buffers + ;; TODO: dynamic size, recreate buffers when size increases. + (let [new-buffers [(create-buffer) (create-buffer)]] + (dosync + (ref-set buffers new-buffers) + (ref-set update-fn *update*))) + (.execute executor draw-offscreen)) (let [buffer (dosync + (ref-set update-fn *update*) (if @updated - (do (peek @buffers) - (alter buffers pop) - (ref-set updated false)) - (do (first @buffers) - (alter buffers next))))] - (when buffer - (.drawImage *graphics* buffer)) - (let [new-buffer (or buffer (create-buffer))] - (dosync - (alter buffers #(cons new-buffer %))) - (when (not buffer) - ;; No cached image to draw. - ;; TODO: draw immediately. - (.execute executor draw-offscreen))))) + (let [b (peek @buffers)] + (alter buffers pop) + (ref-set updated false) + b) + (let [b (first @buffers)] + (alter buffers subvec 1) + b)))] + (.drawImage *graphics* ^Image buffer 0 0 nil) + (dosync + (alter buffers #(vec (cons buffer %)))))) (layer-size [layer] (Size. width height)))))