Mercurial > hg > indyvon
changeset 60:7e456697924d
Asynchronous drawing (continue).
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Mon, 23 Aug 2010 21:24:33 +0400 |
parents | b68de6a43f29 |
children | 88bb47e3a401 |
files | src/net/kryshen/indyvon/component.clj src/net/kryshen/indyvon/core.clj src/net/kryshen/indyvon/layers.clj |
diffstat | 3 files changed, 59 insertions(+), 47 deletions(-) [+] |
line diff
1.1 --- a/src/net/kryshen/indyvon/component.clj Mon Aug 23 14:06:13 2010 +0400 1.2 +++ b/src/net/kryshen/indyvon/component.clj Mon Aug 23 21:24:33 2010 +0400 1.3 @@ -21,22 +21,11 @@ 1.4 [^Component component layer ^Graphics2D graphics event-dispatcher] 1.5 (let [size (.getSize component) 1.6 width (.width size) 1.7 - height (.height size)] 1.8 + height (.height size) 1.9 + update-fn #(.repaint component)] 1.10 (.clearRect graphics 0 0 width height) 1.11 - ;; Setup the root layer context (move to core?). 1.12 - (binding [*graphics* graphics 1.13 - *font-context* (.getFontRenderContext graphics) 1.14 - *initial-transform* (.getTransform graphics) 1.15 - *inverse-initial-transform* 1.16 - (-> graphics .getTransform .createInverse) 1.17 - *target* component 1.18 - *event-dispatcher* event-dispatcher 1.19 - *update* #(.repaint component) 1.20 - *width* width 1.21 - *height* height 1.22 - *clip* (Rectangle2D$Double. 0 0 width height)] 1.23 - (render! layer) 1.24 - (commit event-dispatcher)))) 1.25 + (context-draw! layer component graphics event-dispatcher update-fn 1.26 + width height))) 1.27 1.28 (defn preferred-size [component layer] 1.29 (binding [*target* component
2.1 --- a/src/net/kryshen/indyvon/core.clj Mon Aug 23 14:06:13 2010 +0400 2.2 +++ b/src/net/kryshen/indyvon/core.clj Mon Aug 23 21:24:33 2010 +0400 2.3 @@ -19,7 +19,9 @@ 2.4 2.5 (def ^FontRenderContext *font-context*) 2.6 2.7 -(def ^Component *target*) 2.8 +(def ^{:tag Component 2.9 + :doc "Target AWT component, may be nil if drawing off-screen."} 2.10 + *target*) 2.11 2.12 (def *width*) 2.13 2.14 @@ -238,6 +240,26 @@ 2.15 ([layer x y width height] 2.16 (with-bounds* x y width height render! layer))) 2.17 2.18 +(defn context-draw! 2.19 + "Sets up layer context, draws layer and commits event dispatcher." 2.20 + ([layer graphics event-dispatcher update-fn width height] 2.21 + (draw! layer nil graphics event-dispatcher update-fn width height)) 2.22 + ([layer component ^Graphics2D graphics event-dispatcher update-fn 2.23 + width height] 2.24 + (binding [*graphics* graphics 2.25 + *font-context* (.getFontRenderContext graphics) 2.26 + *initial-transform* (.getTransform graphics) 2.27 + *inverse-initial-transform* 2.28 + (-> graphics .getTransform .createInverse) 2.29 + *target* component 2.30 + *update* update-fn 2.31 + *event-dispatcher* event-dispatcher 2.32 + *width* width 2.33 + *height* height 2.34 + *clip* (Rectangle2D$Double. 0 0 width height)] 2.35 + (render! layer) 2.36 + (commit event-dispatcher)))) 2.37 + 2.38 (defn draw-anchored! 2.39 "Draws layer. Location is relative to the layer's anchor point for 2.40 the specified alignment." 2.41 @@ -261,6 +283,13 @@ 2.42 java.awt.event.MouseEvent/MOUSE_PRESSED :mouse-pressed 2.43 java.awt.event.MouseEvent/MOUSE_RELEASED :mouse-released}) 2.44 2.45 +(def dummy-event-dispatcher 2.46 + (reify 2.47 + EventDispatcher 2.48 + (listen! [this component]) 2.49 + (create-dispatcher [this handle handlers] this) 2.50 + (commit [this]))) 2.51 + 2.52 (defrecord DispatcherNode [handle handlers parent 2.53 ^Shape clip ^AffineTransform transform 2.54 bindings]
3.1 --- a/src/net/kryshen/indyvon/layers.clj Mon Aug 23 14:06:13 2010 +0400 3.2 +++ b/src/net/kryshen/indyvon/layers.clj Mon Aug 23 21:24:33 2010 +0400 3.3 @@ -173,16 +173,6 @@ 3.4 height (if (pos? height) height 1)] 3.5 (Size. width height)))))) 3.6 3.7 -;; (defn- validate-buffer [^Image image restore-fn] 3.8 -;; (if (and image 3.9 -;; (>= (.getWidth image nil) *width*) 3.10 -;; (>= (.getHeight image nil) *height*)) 3.11 -;; image 3.12 -;; ;;(let [image (BufferedImage. *width* *height* BufferedImage/TYPE_INT_ARGB)] 3.13 -;; (let [image (.createImage *target* *width* *height*)] 3.14 -;; (restore-fn image) 3.15 -;; image))) 3.16 - 3.17 (defn async-layer 3.18 "Creates layer that draws the content asynchroniously in an 3.19 offscreen buffer." 3.20 @@ -191,38 +181,42 @@ 3.21 (let [executor (ThreadPoolExecutor. 1 1 0 TimeUnit/SECONDS 3.22 (ArrayBlockingQueue. 1) 3.23 (ThreadPoolExecutor$DiscardOldestPolicy.)) 3.24 - buffers (ref 3.25 - [(BufferedImage. width height BufferedImage/TYPE_INT_ARGB) 3.26 - (BufferedImage. width height BufferedImage/TYPE_INT_ARGB)]) 3.27 + buffers (ref [nil nil]) 3.28 updated (ref false) 3.29 + create-buffer 3.30 + #(BufferedImage. width height BufferedImage/TYPE_INT_ARGB) 3.31 draw-offscreen 3.32 - (fn [] 3.33 - (let [b (dosync (let [b (peek @buffers)] 3.34 - (alter buffers pop) 3.35 - b))] 3.36 - ;; TODO: set complete layer context. 3.37 - (binding [*graphics* (.getGraphics b) 3.38 - *width* width 3.39 - *height* height 3.40 - ;; !!! 3.41 - *update* #(.execute executor draw-offscreen)] 3.42 - (render! content)) 3.43 - (dosync 3.44 - (alter buffers conj b) 3.45 - (ref-set updated true))))] 3.46 + (fn draw-offscreen [] 3.47 + (let [b (dosync (let [b (peek @buffers)] 3.48 + (alter buffers pop) 3.49 + b))] 3.50 + ;; TODO: use operational event dispatcher. 3.51 + (context-draw! (.getGraphics b) 3.52 + dummy-event-dispatcher 3.53 + #(.execute executor draw-offscreen) 3.54 + width height) 3.55 + (dosync 3.56 + (alter buffers conj b) 3.57 + (ref-set updated true))))] 3.58 (reify 3.59 Layer 3.60 (render! [layer] 3.61 - (let [b (dosync 3.62 + (let [buffer (dosync 3.63 (if @updated 3.64 (do (peek @buffers) 3.65 (alter buffers pop) 3.66 (ref-set updated false)) 3.67 (do (first @buffers) 3.68 (alter buffers next))))] 3.69 - (.drawImage *graphics* b) 3.70 - (dosync 3.71 - (alter buffers #(cons b %))))) 3.72 + (when buffer 3.73 + (.drawImage *graphics* buffer)) 3.74 + (let [new-buffer (or buffer (create-buffer))] 3.75 + (dosync 3.76 + (alter buffers #(cons new-buffer %))) 3.77 + (when (not buffer) 3.78 + ;; No cached image to draw. 3.79 + ;; TODO: draw immediately. 3.80 + (.execute executor draw-offscreen))))) 3.81 (layer-size [layer] 3.82 (Size. width height))))) 3.83