Mercurial > hg > indyvon
changeset 95:df9dedc80485
Atomic add-observer.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Thu, 03 Mar 2011 03:20:23 +0300 |
parents | 649d12b6c9ec |
children | fbedad9bd6de |
files | src/net/kryshen/indyvon/core.clj |
diffstat | 1 files changed, 24 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/net/kryshen/indyvon/core.clj Thu Mar 03 03:13:14 2011 +0300 +++ b/src/net/kryshen/indyvon/core.clj Thu Mar 03 03:20:23 2011 +0300 @@ -1,5 +1,5 @@ ;; -;; Copyright 2010 Mikhail Kryshen <mikhail@kryshen.net> +;; Copyright 2010, 2011 Mikhail Kryshen <mikhail@kryshen.net> ;; ;; This file is part of Indyvon. ;; @@ -23,7 +23,8 @@ (java.awt.geom AffineTransform Point2D$Double Rectangle2D$Double Area) (java.awt.event MouseListener MouseMotionListener) (java.awt.font FontRenderContext) - (com.google.common.collect MapMaker))) + java.util.concurrent.ConcurrentMap + com.google.common.collect.MapMaker)) ;; ;; Layer context @@ -141,9 +142,28 @@ ;; The mechanism used by layers to request repaints ;; -(def ^java.util.Map observers +(def ^ConcurrentMap observers (-> (MapMaker.) (.weakKeys) (.makeMap))) +(defn- cm-replace! + "Wrap ConcurrentMap replace method to treat nil value as absent + mapping. Use with maps that does not support nil values." + [^ConcurrentMap cmap key old new] + (if (nil? old) + (nil? (.putIfAbsent cmap key new)) + (.replace cmap key old new))) + +(defn- cm-swap! + "Atomically swaps the value associated with key in ConcurrentMap + to be (apply f current-value args). Returns the new value." + [cmap key f & args] + (loop [] + (let [old (.get cmap key) + new (apply f old args)] + (if (cm-replace! cmap key old new) + new + (recur))))) + (defn add-observer "Add observer fn for the target. Watcher identifies the group of observers and could be used to remove the group. Watcher is weakly @@ -152,7 +172,7 @@ watcher and target arguments and any additional arguments specified in update call." [watcher target f] - (.put observers watcher (assoc-cons (.get observers watcher) target f)) + (cm-swap! observers watcher assoc-cons target f) nil) (defn remove-observers