码迷,mamicode.com
首页 > 其他好文 > 详细

LightTable的结构(二)

时间:2014-11-24 06:21:58      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:des   blog   io   ar   os   使用   sp   java   on   

这节主要研究下object的一个属性,behaviors

定义一个behavior需要提供name,trigger,reaction

(behavior ::on-close-destroy
          :triggers #{:close}
          :reaction (fn [this]
                      (object/raise this :destroy)))

在创建object的时候传入

(object/object* ::user.hello
                :tags [:user.hello]
                :behaviors [::on-close-destroy]
                :init (fn [this]
                        (hello-panel this)))

在object/object*和object/create的时候都可以传入behavior

 

那么怎么触发behavior呢

(object/raise app :closing)

 

(defn raise*
  ([obj reactions args] (raise* obj reactions args nil))
  ([obj reactions args trigger]
   (doseq [r reactions
           :let [func (:reaction (->behavior r))
                 args (if (coll? r)
                        (concat (rest r) args)
                        args)
                 meta (if (coll? r)
                        (meta r)
                        {})]
           :when func]
     (try
     (with-time
       (binding [*behavior-meta* meta]
         (apply func obj args))
       (when-not (= trigger :object.behavior.time)
         (raise obj :object.behavior.time r time trigger)))
       (catch js/Error e
         (safe-report-error (str "Invalid behavior: " (-> (->behavior r) :name)))
         (safe-report-error e)
         )
       (catch js/global.Error e
         (safe-report-error (str "Invalid behavior: " (-> (->behavior r) :name)))
         (safe-report-error e)
         )))))

(defn raise [obj k & args]
  (let [reactions (-> @obj :listeners k)]
    (raise* obj reactions args k)))

可以看出,object/raise会从obj的:listeners中获取对应trigger的reactions

object/raise*中,对这些reactions进行执行,那么behavior是如何变成:listener的呢,注意到 object/handle-redef 会使用update-listeners

(defn handle-redef [odef]
  (let [id (::type odef)]
    (doseq [o (instances-by-type id)
            :let [o (deref o)
                  args (:args o)
                  old (:content o)
                  behs (set (:behaviors o))
                  inst (@instances (->id o))
                  neue (when (:init odef)
                         (apply (:init odef) inst args))
                  neue (if (vector? neue)
                         (crate/html neue)
                         neue)]]
      (merge! inst {:tags (set/union (:tags o) (:tags odef))
                                      :behaviors (set/union behs (set (:behaviors odef)))
                                      :content neue})
      (merge! inst (update-listeners inst))
      (when (and old neue)
        (replace-with old neue))
      (raise inst :redef))
    id))

(defn object* [name & r]
  (-> (apply make-object* name r)
      (store-object*)
      (handle-redef)))

update-listeners利用->triggers将behavior转换成对应的 trigger,存入:listeners

(defn update-listeners
  ([obj] (update-listeners obj nil))
  ([obj instants]
   (let [cur @obj
         behs (set (concat (:behaviors cur) (tags->behaviors (:tags cur))))
         trigs (->triggers behs)
         ;;We need to load new JS files here because they may define the behaviors that we‘re meant to
         ;;capture. If we have a load, then load and recalculate the triggers to pick up those newly
         ;;defined behaviors
         trigs (if (:object.instant-load trigs)
                 (do
                   (raise* obj (:object.instant-load trigs) nil :object.instant-load)
                   (->triggers behs))
                 trigs)
         trigs (if instants
                 trigs
                 (dissoc trigs :object.instant :object.instant-load))]
     ;;deref again in case :object.instant-load made any updates
     (assoc @obj :listeners trigs))))
(defn ->triggers [behs]
  (let [result (atom (transient {}))]
    (doseq [beh behs
            t (:triggers (->behavior beh))]
      (swap! result assoc! t (conj (or (get @result t) ‘()) beh)))
    (persistent! @result)))

  

 

 

--------------------------------------

注:

获取Ref, Atom 和Agent对应的value @ref (deref ref)  

LightTable的结构(二)

标签:des   blog   io   ar   os   使用   sp   java   on   

原文地址:http://www.cnblogs.com/TLightSky/p/4117826.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!