diff --git a/src/reagent/ratom.clj b/src/reagent/ratom.clj index b14ced4..47dbeca 100644 --- a/src/reagent/ratom.clj +++ b/src/reagent/ratom.clj @@ -12,3 +12,31 @@ :auto-run true)] (deref co#) co#)) + +(defmacro with-resource [bindings & body] + (assert (vector? bindings)) + (let [v (gensym "res-v") + init (gensym "res-init-v") + bs (into [] (map-indexed (fn [i x] + (if (even? i) + x + (let [pos (-> (/ i 2) int)] + `(if ~init + (aget ~v ~pos) + (aset ~v ~pos ~x))))) + bindings)) + [forms destroy] (let [fin (last body)] + (if (and (list? fin) + (= 'finally (first fin))) + [(butlast body) `(fn [] ~@(rest fin))] + [body nil]))] + `(let [o# (cljs.core/js-obj) + ~v (reagent.ratom/get-cached-values (quote ~v) o#) + ~init (if (true? (.-init ~v)) + true + (do + (set! (.-init ~v) true) + false))] + (let ~bs + (set! (.-destroy o#) ~destroy) + ~@forms)))) diff --git a/src/reagent/ratom.cljs b/src/reagent/ratom.cljs index 9d7a759..db7f7f9 100644 --- a/src/reagent/ratom.cljs +++ b/src/reagent/ratom.cljs @@ -6,6 +6,8 @@ (declare ^:dynamic *ratom-context*) +(defn reactive? [] (some? *ratom-context*)) + (defonce ^boolean debug false) (defonce ^boolean silent false) @@ -109,7 +111,7 @@ (defonce cached-reactions {}) -(defn- cached-reaction [f key obj] +(defn- cached-reaction [f key obj destroy] (if-some [r (get cached-reactions key)] (-deref r) (if (some? *ratom-context*) @@ -117,12 +119,19 @@ f :on-dispose (fn [] (set! cached-reactions (dissoc cached-reactions key)) - (set! (.-reaction obj) nil))) + (when (some? obj) + (set! (.-reaction obj) nil)) + (when (some-> destroy .-destroy) + (.destroy destroy)))) v (-deref r)] (set! cached-reactions (assoc cached-reactions key r)) - (set! (.-reaction obj) r) + (when (some? obj) + (set! (.-reaction obj) r)) v) - (f)))) + (let [res (f)] + (when (some-> destroy .-destroy) + (.destroy destroy)) + res)))) (deftype Monitor [f key ^:mutable reaction] IReactiveAtom @@ -131,7 +140,7 @@ (-deref [this] (if-some [r reaction] (-deref r) - (cached-reaction f key this))) + (cached-reaction f key this nil))) IEquiv (-equiv [o other] @@ -190,7 +199,7 @@ (let [f (if (satisfies? IDeref ratom) #(get-in @ratom path) #(ratom path))] - (cached-reaction f [::cursor ratom path] this)))] + (cached-reaction f [::cursor ratom path] this nil)))] (._set-state this oldstate newstate) newstate)) @@ -244,6 +253,15 @@ +;;; with-resource support + +(defn get-cached-values [key destroy] + (cached-reaction #(let [o #js{}] + (set! (.-values o) #js[]) + o) + key nil destroy)) + + ;;;; reaction (defprotocol IDisposable @@ -422,7 +440,6 @@ (-hash [this] (goog/getUid this))) - ;;; Queueing ;; Gets set up from batching