Skip to content

Commit

Permalink
group listener notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
dehli committed Jun 14, 2024
1 parent de1ec0c commit 5b06de5
Showing 1 changed file with 34 additions and 2 deletions.
36 changes: 34 additions & 2 deletions core/src/refx/subs.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,38 @@
(doseq [[_ sub] @sub-cache]
(dispose! sub)))

(defonce ^:private listeners-state
(atom {:counter 0 :pending (sorted-map)}))

(defn- invoke-listener
"This function is responsible for ensuring that signal listeners
(from DynamicSubs) are called before triggering regular listeners
(eg: added via use-sub hook). Listeners are triggered in the order they
were registered. This function ensures that one db update will only trigger
a single render."
[listener-key listener-fn]
(swap! listeners-state (fn [state]
(cond-> (update state :counter inc)
(not (signal? listener-key))
(update :pending assoc listener-key listener-fn))))

(when (signal? listener-key)
(listener-fn))

(interop/next-tick
(fn []
(let [listener-fns (atom {})]
(swap! listeners-state (fn [state]
(let [{:keys [counter pending] :as new-state}
(update state :counter dec)]
(if (zero? counter)
(do
(reset! listener-fns pending)
(assoc new-state :pending (sorted-map)))
new-state))))
(doseq [[_ f] @listener-fns]
(f))))))

(deftype Listeners [^:mutable listeners]
Object
(empty? [_] (empty? listeners))
Expand All @@ -84,8 +116,8 @@
(remove [_ k]
(set! listeners (dissoc listeners k)))
(notify [_]
(doseq [[_ f] listeners]
(f))))
(doseq [[k f] listeners]
(invoke-listener k f))))

(defn- make-listeners []
(Listeners. nil))
Expand Down

0 comments on commit 5b06de5

Please sign in to comment.