changeset 114:dac8ff197a6a

The repaint function can be used to pass a state to the next paint iteration.
author Mikhail Kryshen <mikhail@kryshen.net>
date Fri, 04 Nov 2011 04:14:50 +0300
parents 38576aca70d8
children d7ff88fa680f
files src/net/kryshen/indyvon/core.clj
diffstat 1 files changed, 25 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/net/kryshen/indyvon/core.clj	Fri Nov 04 00:18:11 2011 +0300
+++ b/src/net/kryshen/indyvon/core.clj	Fri Nov 04 04:14:50 2011 +0300
@@ -50,6 +50,9 @@
 (def ^:dynamic *scene*
   "Encloses state that should be retained between repaints.")
 
+(def ^:dynamic *states*
+  "Transient scene states, a map.")
+
 (def ^:dynamic *event-dispatcher*)
 
 (def ^:dynamic ^AffineTransform *initial-transform*
@@ -252,9 +255,15 @@
       (add-observer scene target (fn [w _] (update w))))))
 
 (defn repaint
-  "Repaint the current scene."
-  []
-  (update *scene*))
+  "Requests repaint of the current scene. If handle and state are
+  specified, the handle will be associated with the state in the
+  *states* map for the next paint iteration."
+  ([]
+     (update *scene*))
+  ([handle state]
+     (let [scene *scene*]
+       (swap! (:next-state scene) assoc handle state)
+       (update scene))))
 
 ;;
 ;; Rendering
@@ -651,7 +660,7 @@
 ;; Scene
 ;;
 
-(defrecord Scene [layer event-dispatcher component])
+(defrecord Scene [layer event-dispatcher component next-state])
 
 (defn make-scene
   ([layer]
@@ -659,7 +668,16 @@
   ([layer event-dispatcher]
      (make-scene layer event-dispatcher nil))
   ([layer event-dispatcher component]
-     (->Scene layer event-dispatcher component)))
+     (->Scene layer event-dispatcher component (atom nil))))
+
+(defn- get-and-set!
+  "Atomically sets the value of atom to newval and returns the old
+  value."
+  [atom newval]
+  (loop [v @atom]
+    (if (compare-and-set! atom v newval)
+      v
+      (recur @atom))))
 
 (defn draw-scene!
   [scene ^Graphics2D graphics width height]
@@ -675,7 +693,8 @@
   ;; (.setRenderingHint graphics
   ;;                    RenderingHints/KEY_TEXT_ANTIALIASING
   ;;                    RenderingHints/VALUE_TEXT_ANTIALIAS_ON)
-  (binding [*scene* scene
+  (binding [*states* (get-and-set! (:next-state scene) nil)
+            *scene* scene
             *graphics* graphics
             *font-context* (.getFontRenderContext graphics)
             *initial-transform* (.getTransform graphics)