lt.macros/behaviorマクロがどのように動くかのメモ
lt/macros.clj
lt.macros.clj抜粋
(defn- namify [type keyword]
(symbol (str "__" type "__" (.replace (name keyword) "." "__DOT__"))))
(defmacro behavior [name & {:keys [reaction] :as r}]
(if (and (seq? reaction) (= 'fn (first reaction)))
(let [[_ args & body] reaction]
`(do
(defn- ~(namify "BEH" name) ~args ~@body)
(lt.object/behavior* ~name ~@(apply concat (assoc r :reaction (namify "BEH" name))))))
`(lt.object/behavior* ~name ~@(apply concat r))))
-
:reaction
が(fn ... )
のような関数定義の場合- その関数を
defn-
で定義。関数名は__BEH__name
のような形 -
:reaction
にdefn-
で定義した関数を設定してlt.object/behavior*を呼ぶ。
- その関数を
-
:reaction
が存在しないor関数定義でない場合、lt.object/behavior*を呼ぶ。(引数はbehaviorに渡されたものそのまま)
lt/object.cljs
lt.object/behavior*の流れ
lt.object.cljs抜粋
(def behaviors (atom {}))
(defn add-behavior [beh]
(swap! behaviors assoc (:name beh) beh))
(defn make-behavior* [name & r]
(let [be (merge {:name name}
(apply hash-map r))]
be))
(defn store-behavior* [beh]
(add-behavior beh)
(:name beh))
(defn wrap-throttle [beh]
(if-let [thr (:throttle beh)]
(assoc beh :reaction (throttle thr (:reaction beh)))
beh))
(defn wrap-debounce [beh]
(if-let [thr (:debounce beh)]
(assoc beh :reaction (debounce thr (:reaction beh)))
beh))
(defn behavior* [name & r]
(-> (apply make-behavior* name r)
(wrap-throttle)
(wrap-debounce)
(store-behavior*)))
-
make-behavior*
で引数をマップに変換する -
wrap-throttle
でマップに:throttle
があったら、:reaction
の関数にthrottle
を適用した結果の関数を:reaction
に設定したマップに変換する -
wrap-debounce
も同様 - できたマップを、
store-behavior*
経由add-behavior
でatomのマップに追加する
throttle, debounceとは
ここらへんが参考になる。イベント処理の間引きを行うものらしい
http://blog.springdawn.info/post/40885154200/javascript-throttle-debounce
http://ktkne.st/elab/post/2012/strcount-throttle-debounce.html
behaviorができたら・・・
behaviorを定義しただけだと何も起こらない(?)
objectとbehaviorを(tag経由で?)結びつける