Mercurial > hg > indyvon
changeset 85:e718a69f7d99
Observers: use weak keys, renamed some fns.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Fri, 01 Oct 2010 18:45:17 +0400 |
parents | b04bdeec5700 |
children | 069ea63803a2 |
files | project.clj src/net/kryshen/indyvon/async.clj src/net/kryshen/indyvon/component.clj src/net/kryshen/indyvon/core.clj |
diffstat | 4 files changed, 41 insertions(+), 34 deletions(-) [+] |
line diff
1.1 --- a/project.clj Wed Sep 08 04:40:05 2010 +0400 1.2 +++ b/project.clj Fri Oct 01 18:45:17 2010 +0400 1.3 @@ -2,7 +2,8 @@ 1.4 :description "INteractive DYnamic VisualizatiON library" 1.5 ;;:warn-on-reflection true 1.6 :dependencies [[org.clojure/clojure "1.2.0"] 1.7 - [org.clojure/clojure-contrib "1.2.0"]] 1.8 + [org.clojure/clojure-contrib "1.2.0"] 1.9 + [com.google.guava/guava "r07"]] 1.10 :dev-dependencies [[swank-clojure/swank-clojure "1.2.1"]] 1.11 :namespaces [net.kryshen.indyvon.core 1.12 net.kryshen.indyvon.async
2.1 --- a/src/net/kryshen/indyvon/async.clj Wed Sep 08 04:40:05 2010 +0400 2.2 +++ b/src/net/kryshen/indyvon/async.clj Fri Oct 01 18:45:17 2010 +0400 2.3 @@ -127,7 +127,7 @@ 2.4 Layer 2.5 (render! [layer] 2.6 (repaint-on-update layer) 2.7 - (add-context-observer content (fn [_] (draw-offscreen-async layer))) 2.8 + (add-context-observer content (fn [_ _] (draw-offscreen-async layer))) 2.9 (when-not @buffers 2.10 ;; TODO: dynamic size, recreate buffers when size increases. 2.11 (let [new-buffers (repeatedly 2 (partial create-buffer layer))]
3.1 --- a/src/net/kryshen/indyvon/component.clj Wed Sep 08 04:40:05 2010 +0400 3.2 +++ b/src/net/kryshen/indyvon/component.clj Fri Oct 01 18:45:17 2010 +0400 3.3 @@ -44,7 +44,12 @@ 3.4 (let [s (root-size layer (font-context this) this)] 3.5 (Dimension. (:width s) (:height s)))))] 3.6 (.setBackground panel (:back-color *theme*)) 3.7 - (add-observer panel layer (fn [_] (.repaint panel))) 3.8 + (add-observer panel layer (fn [w _] 3.9 + ;; Use the first observer argument 3.10 + ;; instead of closing over panel to 3.11 + ;; allow the panel and associated 3.12 + ;; observer to be gc'd. 3.13 + (.repaint ^Component w))) 3.14 (listen! event-dispatcher panel) 3.15 panel))) 3.16
4.1 --- a/src/net/kryshen/indyvon/core.clj Wed Sep 08 04:40:05 2010 +0400 4.2 +++ b/src/net/kryshen/indyvon/core.clj Fri Oct 01 18:45:17 2010 +0400 4.3 @@ -22,7 +22,8 @@ 4.4 (java.awt Graphics2D RenderingHints Component Color Font Shape) 4.5 (java.awt.geom AffineTransform Point2D$Double Rectangle2D$Double Area) 4.6 (java.awt.event MouseListener MouseMotionListener) 4.7 - (java.awt.font FontRenderContext))) 4.8 + (java.awt.font FontRenderContext) 4.9 + (com.google.common.collect MapMaker))) 4.10 4.11 ;; 4.12 ;; Layer context 4.13 @@ -135,43 +136,43 @@ 4.14 (defn- assoc-cons [m key val] 4.15 (->> (get m key) (cons val) (assoc m key))) 4.16 4.17 -(defn- assoc-in-cons [m keys val] 4.18 - (->> (get-in m keys) (cons val) (assoc-in m keys))) 4.19 - 4.20 ;; 4.21 ;; Observers 4.22 +;; The mechanism used by layers to request repaints 4.23 ;; 4.24 4.25 -(def observers (atom nil)) 4.26 +(def ^java.util.Map observers 4.27 + (-> (MapMaker.) (.weakKeys) (.makeMap))) 4.28 4.29 -;; TODO: groups should be weakly referenced. 4.30 (defn add-observer 4.31 - "Add observer fn for the target to the specified group." 4.32 - [group target f] 4.33 - (swap! observers assoc-in-cons [group target] f) 4.34 + "Add observer fn for the target. Watcher identifies the group of 4.35 + observers and could be used to remove the group. Watcher is weakly 4.36 + referenced, all associated observers will be removed when the 4.37 + wathcer is removed by gc. The observer fn will be called with 4.38 + watcher and target arguments and any additional arguments specified 4.39 + in update call." 4.40 + [watcher target f] 4.41 + (.put observers watcher (assoc-cons (.get observers watcher) target f)) 4.42 nil) 4.43 4.44 -(defn remove-observer-group 4.45 - "Remove group of observers." 4.46 - [group] 4.47 - (swap! observers dissoc group) 4.48 +(defn remove-observers 4.49 + "Remove group of observers associated with the specified watcher." 4.50 + [watcher] 4.51 + (.remove observers watcher) 4.52 nil) 4.53 4.54 -(defn- replace-observer-group* 4.55 - [observers old-id new-id] 4.56 - (let [group (get observers old-id)] 4.57 - (assoc (dissoc observers old-id) 4.58 - new-id group))) 4.59 - 4.60 -(defn- replace-observer-group 4.61 - [old-id new-id] 4.62 - (swap! observers replace-observer-group* old-id new-id)) 4.63 +(defn- replace-observers-watcher 4.64 + [old-watcher new-watcher] 4.65 + (if-let [old (.remove observers old-watcher)] 4.66 + (.put observers new-watcher old)) 4.67 + nil) 4.68 4.69 (defn update 4.70 "Notify observers." 4.71 [target & args] 4.72 - (doseq [f (reduce #(concat %1 (get %2 target)) nil (vals @observers))] 4.73 - (apply f target args))) 4.74 + (doseq [entry observers 4.75 + f (get (val entry) target)] 4.76 + (apply f (key entry) target args))) 4.77 4.78 (defn add-context-observer 4.79 "Observer registered with this function will be automatically 4.80 @@ -185,7 +186,7 @@ 4.81 [target] 4.82 (let [root *root*] 4.83 (if (not= root target) 4.84 - (add-observer root target (fn [_] (update root)))))) 4.85 + (add-observer root target (fn [w _] (update w)))))) 4.86 4.87 (defn repaint 4.88 "Repaint the current scene." 4.89 @@ -347,15 +348,15 @@ 4.90 (apply-theme) 4.91 (with-color (:back-color *theme*) 4.92 (.fillRect graphics 0 0 width height)) 4.93 - (let [tmp-group (Object.)] 4.94 - ;; Keep current context observers until the rendering is complete. 4.95 - ;; Some observers may be invoked twice if they appear in both 4.96 - ;; groups until tmp-group is removed. 4.97 - (replace-observer-group layer tmp-group) 4.98 + (let [tmp-watcher (Object.)] 4.99 + ;; Keep current context observers until the rendering is 4.100 + ;; complete. Some observers may be invoked twice if they 4.101 + ;; appear in both groups until tmp-watcher is removed. 4.102 + (replace-observers-watcher layer tmp-watcher) 4.103 (try 4.104 (render! layer) 4.105 (finally 4.106 - (remove-observer-group tmp-group) 4.107 + (remove-observers tmp-watcher) 4.108 (commit event-dispatcher))))))) 4.109 4.110 (defn root-size