Make next-tick more predictable, add after-render

This commit is contained in:
Dan Holmsand 2015-10-11 22:08:42 +02:00
parent edf001cb62
commit 78fffe263e
4 changed files with 49 additions and 28 deletions

View File

@ -44,7 +44,7 @@
_ (assert (string? path))] _ (assert (string? path))]
(when-some [h history] (when-some [h history]
(.setToken h x) (.setToken h x)
(r/next-tick #(set! js/document.body.scrollTop 0)) (r/after-render #(set! js/document.body.scrollTop 0))
state) state)
(recur state [:set-page x])))) (recur state [:set-page x]))))

View File

@ -309,9 +309,18 @@ another cursor) these cursors are equivalent:
nil) nil)
(defn next-tick (defn next-tick
"Run f using requestAnimationFrame or equivalent." "Run f using requestAnimationFrame or equivalent.
f will be called just before components are rendered."
[f] [f]
(batch/next-tick f)) (batch/do-before-flush f))
(defn after-render
"Run f using requestAnimationFrame or equivalent.
f will be called just after components are rendered."
[f]
(batch/do-after-render f))
(defn partial (defn partial
"Works just like clojure.core/partial, except that it is an IFn, and "Works just like clojure.core/partial, except that it is an IFn, and

View File

@ -39,36 +39,49 @@
(.! c :cljsIsDirty false) (.! c :cljsIsDirty false)
(.' c forceUpdate))))) (.' c forceUpdate)))))
(defn run-funs [a]
(dotimes [i (alength a)]
((aget a i))))
;; Set from ratom.cljs ;; Set from ratom.cljs
(defonce ratom-flush identity) (defonce ratom-flush identity)
(deftype RenderQueue [^:mutable queue ^:mutable ^boolean scheduled? (deftype RenderQueue [^:mutable ^boolean scheduled?]
^:mutable after-render]
Object Object
(queue-render [this c] (enqueue [this k f]
(.push queue c) (assert (some? f))
(when (nil? (aget this k))
(aset this k (array)))
(.push (aget this k) f)
(.schedule this)) (.schedule this))
(add-after-render [_ f]
(.push after-render f)) (run-funs [this k]
(when-some [fs (aget this k)]
(aset this k nil)
(dotimes [i (alength fs)]
((aget fs i)))))
(schedule [this] (schedule [this]
(when-not scheduled? (when-not scheduled?
(set! scheduled? true) (set! scheduled? true)
(next-tick #(.run-queue this)))) (next-tick #(.run-queue this))))
(run-queue [_]
(ratom-flush)
(let [q queue
aq after-render]
(set! queue (array))
(set! after-render (array))
(set! scheduled? false)
(run-queue q)
(run-funs aq))))
(defonce render-queue (RenderQueue. (array) false (array))) (queue-render [this c]
(.enqueue this "componentQueue" c))
(add-before-flush [this f]
(.enqueue this "beforeFlush" f))
(add-after-render [this f]
(.enqueue this "afterRender" f))
(run-queue [this]
(set! scheduled? false)
(.run-funs this "beforeFlush")
(ratom-flush)
(when-some [cs (aget this "componentQueue")]
(aset this "componentQueue" nil)
(run-queue cs))
(.run-funs this "afterRender")))
(defonce render-queue (RenderQueue. false))
(defn flush [] (defn flush []
(.run-queue render-queue)) (.run-queue render-queue))
@ -80,12 +93,11 @@
(defn mark-rendered [c] (defn mark-rendered [c]
(.! c :cljsIsDirty false)) (.! c :cljsIsDirty false))
(defn do-after-flush [f] (defn do-before-flush [f]
(.add-after-render render-queue f)) (.add-before-flush render-queue f))
(defn do-later [f] (defn do-after-render [f]
(do-after-flush f) (.add-after-render render-queue f))
(.schedule render-queue))
(defn schedule [] (defn schedule []
(when (false? (.-scheduled? render-queue)) (when (false? (.-scheduled? render-queue))

View File

@ -161,7 +161,7 @@
;; wants to keep the value unchanged ;; wants to keep the value unchanged
(when-not (.' this :cljsInputDirty) (when-not (.' this :cljsInputDirty)
(.! this :cljsInputDirty true) (.! this :cljsInputDirty true)
(batch/do-later #(input-set-value this))) (batch/do-after-render #(input-set-value this)))
res)) res))
(defn input-render-setup [this jsprops] (defn input-render-setup [this jsprops]