LightTable使用clojurescript来生成js,然后使用 来处理UI
clojurescript非常适合做抽象程度很高的页面和编辑逻辑结构设计,
最近会对整体进行分析整理一个大题的结构图
程序的入口在lt.objs.app@init
可以看到init做了几件事情进行初始化
(defn init []
(object/raise app :deploy)
(object/raise app :pre-init)
(object/raise app :init)
(object/raise app :post-init)
(object/raise app :show))
而操作的对象,app的初始化在:
(object/object* ::app
:tags #{:app :window}
:delays 0
:init (fn [this]
(ctx/in! :app this)))
(def app (object/create ::app))
app是object/object*和object/create一起生成的
(defn object* [name & r]
(-> (apply make-object* name r)
(store-object*)
(handle-redef)))
(defn make-object* [name & r]
(let [obj (merge {:behaviors #{} :tags #{} :triggers [] :listeners {} ::type name :children {}}
(apply hash-map r))]
obj))
(defn store-object* [obj]
(add obj)
obj)
(defn add [obj]
(swap! object-defs assoc (::type obj) obj))
(defn create [obj-name & args]
(let [obj (if (keyword? obj-name)
(@object-defs obj-name)
obj-name)
id (or (::id obj) (swap! obj-id inc))
inst (atom (assoc (dissoc obj :init)
::id id
:args args
:behaviors (set (:behaviors obj))
:tags (set (conj (:tags obj) :object))))
inst (store-inst inst)
_ (merge! inst (update-listeners inst))
content (when (:init obj)
(apply (:init obj) inst args))
content (if (vector? content)
(crate/html content)
content)
final (merge! inst {:content content})]
(add-watch inst ::change (fn [_ _ _ _]
(raise inst :object.change)))
(raise* inst (trigger->behaviors :object.instant (:tags @inst)) nil)
(raise inst :init)
inst))
object/object*生成了一个hash-map的对象,对象包含了behavior,tag之类的属性,每个object对应一个唯一的名字,存在object-defs这个atom对象里,这个object-defs用于记录所有的类对象的定义
object/create中,先是通过(@object-defs obj-name)来获取object,然后对object做一些创建的工作,
inst是instance的缩写,采用了类似javascript里的clone的方式来创建一个object的instance