initial commit
This commit is contained in:
Executable
+109
@@ -0,0 +1,109 @@
|
||||
(ns reagent.impl.batching
|
||||
(:refer-clojure :exclude [flush])
|
||||
(:require [reagent.debug :refer-macros [dbg]]
|
||||
[reagent.interop :refer-macros [.' .!]]
|
||||
[reagent.ratom :as ratom]
|
||||
[reagent.impl.util :refer [is-client]]
|
||||
[clojure.string :as string]))
|
||||
|
||||
;;; Update batching
|
||||
|
||||
(defonce mount-count 0)
|
||||
|
||||
(defn next-mount-count []
|
||||
(set! mount-count (inc mount-count)))
|
||||
|
||||
(defn fake-raf [f]
|
||||
(js/setTimeout f 16))
|
||||
|
||||
(def next-tick
|
||||
(if-not is-client
|
||||
fake-raf
|
||||
(let [w js/window]
|
||||
(or (.' w :requestAnimationFrame)
|
||||
(.' w :webkitRequestAnimationFrame)
|
||||
(.' w :mozRequestAnimationFrame)
|
||||
(.' w :msRequestAnimationFrame)
|
||||
fake-raf))))
|
||||
|
||||
(defn compare-mount-order [c1 c2]
|
||||
(- (.' c1 :cljsMountOrder)
|
||||
(.' c2 :cljsMountOrder)))
|
||||
|
||||
(defn run-queue [a]
|
||||
;; sort components by mount order, to make sure parents
|
||||
;; are rendered before children
|
||||
(.sort a compare-mount-order)
|
||||
(dotimes [i (alength a)]
|
||||
(let [c (aget a i)]
|
||||
(when (.' c :cljsIsDirty)
|
||||
(.' c forceUpdate)))))
|
||||
|
||||
(defn run-funs [a]
|
||||
(dotimes [i (alength a)]
|
||||
((aget a i))))
|
||||
|
||||
(deftype RenderQueue [^:mutable queue ^:mutable scheduled?
|
||||
^:mutable after-render]
|
||||
Object
|
||||
(queue-render [this c]
|
||||
(.push queue c)
|
||||
(.schedule this))
|
||||
(add-after-render [_ f]
|
||||
(.push after-render f))
|
||||
(schedule [this]
|
||||
(when-not scheduled?
|
||||
(set! scheduled? true)
|
||||
(next-tick #(.run-queue this))))
|
||||
(run-queue [_]
|
||||
(let [q queue aq after-render]
|
||||
(set! queue (array))
|
||||
(set! after-render (array))
|
||||
(set! scheduled? false)
|
||||
(run-queue q)
|
||||
(run-funs aq))))
|
||||
|
||||
(def render-queue (RenderQueue. (array) false (array)))
|
||||
|
||||
(defn flush []
|
||||
(.run-queue render-queue))
|
||||
|
||||
(defn queue-render [c]
|
||||
(.! c :cljsIsDirty true)
|
||||
(.queue-render render-queue c))
|
||||
|
||||
(defn mark-rendered [c]
|
||||
(.! c :cljsIsDirty false))
|
||||
|
||||
(defn do-after-flush [f]
|
||||
(.add-after-render render-queue f))
|
||||
|
||||
(defn do-later [f]
|
||||
(do-after-flush f)
|
||||
(.schedule render-queue))
|
||||
|
||||
;; Render helper
|
||||
|
||||
(defn is-reagent-component [c]
|
||||
(some-> c (.' :props) (.' :argv)))
|
||||
|
||||
(defn run-reactively [c run]
|
||||
(assert (is-reagent-component c))
|
||||
(mark-rendered c)
|
||||
(let [rat (.' c :cljsRatom)]
|
||||
(if (nil? rat)
|
||||
(let [res (ratom/capture-derefed run c)
|
||||
derefed (ratom/captured c)]
|
||||
(when (not (nil? derefed))
|
||||
(.! c :cljsRatom
|
||||
(ratom/make-reaction run
|
||||
:auto-run #(queue-render c)
|
||||
:derefed derefed)))
|
||||
res)
|
||||
(ratom/run rat))))
|
||||
|
||||
(defn dispose [c]
|
||||
(some-> (.' c :cljsRatom)
|
||||
ratom/dispose!)
|
||||
(mark-rendered c))
|
||||
|
||||
Reference in New Issue
Block a user