mirror of
https://github.com/status-im/reagent.git
synced 2025-02-14 21:08:27 +00:00
Add rswap!
Works just like swap!, except that it allows recursive swaps on the same atom, and it always returns nil.
This commit is contained in:
parent
8e7624ea45
commit
e11c881aa7
@ -277,6 +277,27 @@ another cursor) these cursors are equivalent:
|
||||
|
||||
;; Utilities
|
||||
|
||||
(defn rswap!
|
||||
"Swaps the value of a to be (apply f current-value-of-atom args).
|
||||
|
||||
rswap! works like swap!, except that recursive calls to rswap! on
|
||||
the same atom are allowed – and it always returns nil."
|
||||
[a f & args]
|
||||
{:pre [(satisfies? IAtom a)
|
||||
(ifn? f)]}
|
||||
(if a.rswapping
|
||||
(-> (or a.rswapfs (set! a.rswapfs (array)))
|
||||
(.push #(apply f % args)))
|
||||
(do (set! a.rswapping true)
|
||||
(try (swap! a (fn [state]
|
||||
(loop [s (apply f state args)]
|
||||
(if-some [sf (some-> a.rswapfs .shift)]
|
||||
(recur (sf s))
|
||||
s))))
|
||||
(finally
|
||||
(set! a.rswapping false)))))
|
||||
nil)
|
||||
|
||||
(defn next-tick
|
||||
"Run f using requestAnimationFrame or equivalent."
|
||||
[f]
|
||||
|
@ -265,3 +265,27 @@
|
||||
(set! rv/silent false)
|
||||
(dispose c)
|
||||
(is (= runs (running)))))
|
||||
|
||||
(deftest test-rswap
|
||||
(let [a (atom {:foo 1})]
|
||||
(r/rswap! a update-in [:foo] inc)
|
||||
(is (= (:foo @a) 2))
|
||||
(r/rswap! a #(assoc %1 :foo %2) 3)
|
||||
(is (= (:foo @a) 3))
|
||||
(r/rswap! a #(assoc %1 :foo %3) 0 4)
|
||||
(is (= (:foo @a) 4))
|
||||
(r/rswap! a #(assoc %1 :foo %4) 0 0 5)
|
||||
(is (= (:foo @a) 5))
|
||||
(r/rswap! a #(assoc %1 :foo %5) 0 0 0 6)
|
||||
(is (= (:foo @a) 6))
|
||||
(let [disp (atom nil)
|
||||
f (fn [o v]
|
||||
(assert (= v :add))
|
||||
(if (< (:foo o) 10)
|
||||
(do
|
||||
(@disp v)
|
||||
(update-in o [:foo] inc))
|
||||
o))
|
||||
_ (reset! disp #(r/rswap! a f %))]
|
||||
(@disp :add)
|
||||
(is (= (:foo @a) 10)))))
|
||||
|
Loading…
x
Reference in New Issue
Block a user