changeset 162:4aa8979938ee

Faster dynamic bindings.
author Mikhail Kryshen <mikhail@kryshen.net>
date Mon, 24 Nov 2014 02:09:13 +0300
parents acda6344bcb7
children dc3ed475c6d6
files src/indyvon/core.clj
diffstat 1 files changed, 30 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/indyvon/core.clj	Sat Nov 22 03:49:31 2014 +0300
+++ b/src/indyvon/core.clj	Mon Nov 24 02:09:13 2014 +0300
@@ -338,6 +338,24 @@
        (swap! (:next-state scene) assoc handle state)
        (update scene))))
 
+(defmacro binding-fast
+  "Faster alternative to core/binding. Works only with vars that are
+  already thread-bound. Uses set! instead of push-thread-bindings and
+  pop-thread-bindings."
+  [bindings & body]
+  {:pre [(vector? bindings)
+         (even? (count bindings))]}
+  (let [bindings (partition 2 bindings)
+        var-syms (map first bindings)
+        var-vals (map second bindings)
+        syms (map (comp gensym name) var-syms)]
+    `(let [~@(mapcat vector syms var-syms)]
+       (try
+         ~@(map #(list `set! %1 %2) var-syms var-vals)
+         ~@body
+         (finally
+           ~@(map #(list `set! %1 %2) var-syms syms))))))
+
 ;;
 ;; Rendering
 ;;
@@ -446,10 +464,10 @@
   (let [graphics (create-graphics)]
     (try
       (.translate graphics (double x) (double y))
-      (binding [*width* w
-                *height* h
-                *input-clip* (Rectangle2D$Double. 0.0 0.0 w h)
-                *graphics* graphics]
+      (binding-fast [*width* w
+                     *height* h
+                     *input-clip* (Rectangle2D$Double. 0.0 0.0 w h)
+                     *graphics* graphics]
         (apply f args))
       (finally
        (.dispose graphics)))))
@@ -464,11 +482,11 @@
         (try
           (.clip graphics bounds)
           (.translate graphics x y)
-          (binding [*width* w
-                    *height* h
-                    *clip* clip
-                    *input-clip* nil
-                    *graphics* graphics]
+          (binding-fast [*width* w
+                         *height* h
+                         *clip* clip
+                         *input-clip* nil
+                         *graphics* graphics]
             (apply f args))
           (finally
            (.dispose graphics)))))))
@@ -565,7 +583,7 @@
   ([view]
      (let [graphics (create-graphics)]
        (try
-         (binding [*graphics* graphics]
+         (binding-fast [*graphics* graphics]
            (render! view))
          (finally
           (.dispose graphics)))))
@@ -602,8 +620,8 @@
 
 (defn with-handlers*
   [handle handlers f & args]
-  (binding [*event-dispatcher* (create-dispatcher
-                                *event-dispatcher* handle handlers)]
+  (binding-fast [*event-dispatcher* (create-dispatcher
+                                     *event-dispatcher* handle handlers)]
     (apply f args)))
 
 (defmacro with-handlers