LightTable的结构(二)
这节主要研究下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的结构(二)的更多相关文章
- PostgreSQL的存储系统二:REDOLOG文件存储结构二
REDOLOG文件里的用户数据和数据文件里的用户数据存储结构相同 几个月前同事给台湾一家公司培训<pg9 ad admin>时,有个学员提及WAL里记录的内容为Query时的SQL语句(比 ...
- JAVA的选择结构(二)
1.switch选择结构: 语法: switch (key) { ...
- update_engine-整体结构(二)
在update_engine-整体结构(一)中分析UpdateEngineDaemon::OnInit()的整体情况.下面先分析在该方法中涉及的DaemonStateAndroid和BinderUpd ...
- java虚拟机规范(se8)——java虚拟机结构(二)
2.5 运行时数据区域 java虚拟机定义了多个用于程序执行期间的运行时数据区域.这些数据区域中一些随着java虚拟机的启动而创建,随着虚拟机的退出而销毁.其他的数据区域时和线程相关的.线程相关数据区 ...
- Flask从入门到精通之大型程序的结构二
一.程序包 程序包用来保存程序的所有代码.模板和静态文件.我们可以把这个包直接称为app(应用),如果有需求,也可使用一个程序专用名字.templates 和static 文件夹是程序包的一部分,因此 ...
- PLSQL中使用二维存储结构---二维数组
代码如下: --PLSQL中没有数组的概念 用TYPE 和Table of Record来代替多维数组--create by jenrry 20171028-- 1.0 建立存放列的测试表creat ...
- LightTable的结构(一)
LightTable使用clojurescript来生成js,然后使用 node-webkit 来处理UI clojurescript非常适合做抽象程度很高的页面和编辑逻辑结构设计, 最近会对整体进行 ...
- Linux目录结构(二)
Linux文件系统结的结构是树形结构,其入口从/开始,了解Linux文件系统的结构,对于我们需要掌握的基础知识点之一. 2.文件系统的组织结构简说: 当您使用Linux的时候,如果您通过ls -la ...
- java6循环结构二
public class jh_01_回顾与作业点评 { public static void main(String[] args) { int val = 12345; System.out.pr ...
随机推荐
- CSU 2018年12月月赛 F(2218): Finding prime numbers
Description xrdog has a number set. There are 95 numbers in this set. They all have something in com ...
- nginx网站标准配置
#nginx开启的进程数worker_processes 4; #4核CPU #定义全局错误日志定义类型,[debug|info|notice|warn|crit]error_log ...
- 【转】C语言中access函数
头文件:unistd.h 功 能: 确定文件或文件夹的访问权限.即,检查某个文件的存取方式,比如说是只读方式.只写方式等.如果指定的存取方式有效,则函数返回0,否则函数返回-1. 用 法: int a ...
- 创建Tensor
目录 创建Tensor numpy, list numpy list zeros, ones, fill zeros ones fill random 打乱idx后,a和b的索引不变 constant ...
- 87-Moving average of oscillator,移动平均振荡指标.(2015.7.4)
Moving average of oscillator 移动平均振荡指标 ~计算: OSMA = MACD-SIGNAL 注释:OSMA的值即为MACD中两个主要指标线的差值 ~思想: 该指标当作一 ...
- LeetCode(61) Rotate List
题目 Given a list, rotate the list to the right by k places, where k is non-negative. For example: Giv ...
- Spring AOP配置简单记录(注解及xml配置方式)
在了解spring aop中的关键字(如:连接点(JoinPoint).切入点(PointCut).切面(Aspact).织入(Weaving).通知(Advice).目标(Target)等)后进行了 ...
- iPhone安装ipa的方法(iTunes,PP助手)
1,通过iTunes: 将手机与电脑通过数据线连接,打开电脑中的iTunes,将ipa文件添加到资料库(ipa文件是iTunes能够识别的文件),方式如下图,然后安装,同步即可. 2,通过PP助手: ...
- xtu summer individual 5 A - To Add or Not to Add
To Add or Not to Add Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeFo ...
- xtu summer individual-4 D - Martian Strings
Martian Strings Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. ...