博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LightTable的结构(二)
阅读量:6007 次
发布时间:2019-06-20

本文共 3863 字,大约阅读时间需要 12 分钟。

这节主要研究下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)  

转载于:https://www.cnblogs.com/TLightSky/p/4117826.html

你可能感兴趣的文章
Linux pipe函数
查看>>
图片标注工具LabelImg使用教程
查看>>
(原創) 如何設計一個數位相框? (SOC) (Quartus II) (SOPC Builder) (Nios II) (TRDB-LTM) (DE2-70)...
查看>>
/etc/profile文件内容
查看>>
量词 匹配优先与忽略优先
查看>>
一页纸IT项目管理:大道至简的实用管理沟通工具
查看>>
汽车知识:车内异味的清除方法
查看>>
IE6 7下绝对定位引发浮动元素神秘消失
查看>>
android - ADT本地配置、sdk配置
查看>>
I.MX6 dhcpcd 需要指定网卡
查看>>
js递归原理之return
查看>>
浏览器的回流和重绘及其优化方式
查看>>
gulp+browser-sync实现前端自动化刷新
查看>>
python学习笔记 --- 来看看 random_state 这个参数
查看>>
基于angular2实现用户登录并信息持久化的一些理解(三)
查看>>
新框架 - 收藏集 - 掘金
查看>>
JQuery坑,说说哪些大家都踩过的坑
查看>>
高性能迷你React框架anu在低版本IE的实践
查看>>
windows中用cmd 删除文件夹以及文件夹里面的所有内容
查看>>
中国在两年内赶超美国AI?李开复:不一定
查看>>