初始化提交
This commit is contained in:
22
Content/Lua/Core/PWClass.lua
Normal file
22
Content/Lua/Core/PWClass.lua
Normal file
@ -0,0 +1,22 @@
|
||||
local PWClass = {}
|
||||
|
||||
local function MetaCall(cls, ...)
|
||||
local inst = {
|
||||
__CLASS = cls
|
||||
}
|
||||
cls.ctor(inst, ...)
|
||||
return setmetatable(inst, cls)
|
||||
end
|
||||
|
||||
function PWClass.derive(name, base)
|
||||
local cls = {
|
||||
__CLASS_NAME = name
|
||||
}
|
||||
cls.__index = cls
|
||||
return setmetatable(cls, {
|
||||
__call = MetaCall
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
return PWClass
|
||||
164
Content/Lua/Core/Reactive.lua
Normal file
164
Content/Lua/Core/Reactive.lua
Normal file
@ -0,0 +1,164 @@
|
||||
local Module = {}
|
||||
local ReactiveWatcherMeta = {}
|
||||
local ReactivePropertyMeta = {}
|
||||
local reactive_watcher_stack = {}
|
||||
local auto_run_watcher_mapping = {}
|
||||
local triggered_watchers = {} -- 由SetProperty激活的watcher列表
|
||||
|
||||
local function CreateReactiveWatcher(auto_run)
|
||||
local watcher = rawget(auto_run_watcher_mapping, auto_run)
|
||||
if watcher == nil then
|
||||
watcher = {
|
||||
auto_run = auto_run,
|
||||
properties = {},
|
||||
}
|
||||
rawset(auto_run_watcher_mapping, auto_run, watcher)
|
||||
setmetatable(watcher, ReactiveWatcherMeta)
|
||||
end
|
||||
return watcher
|
||||
end
|
||||
|
||||
|
||||
local function PushWatcher(watcher)
|
||||
table.insert(reactive_watcher_stack, watcher)
|
||||
end
|
||||
|
||||
|
||||
local function PeekWatcher()
|
||||
local watcher_stack_deepth = #reactive_watcher_stack
|
||||
if watcher_stack_deepth > 0 then
|
||||
return reactive_watcher_stack[watcher_stack_deepth]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function PopWatcher()
|
||||
local watcher = PeekWatcher()
|
||||
if watcher then
|
||||
table.remove(reactive_watcher_stack)
|
||||
end
|
||||
return watcher
|
||||
end
|
||||
|
||||
|
||||
local function AddPropertyToWatcher(watcher, property, key)
|
||||
local properties = watcher.properties
|
||||
local keys = properties[property] or {}
|
||||
keys[key] = true
|
||||
properties[property] = keys
|
||||
end
|
||||
|
||||
|
||||
local function ClearAllPropertiesOfWatcher(watcher)
|
||||
local properties = watcher.properties
|
||||
for property, keys in pairs(properties) do
|
||||
local property_watchers = property.watchers
|
||||
for key, state in pairs(keys) do
|
||||
if state == true then
|
||||
local key_watchers = property_watchers[key]
|
||||
key_watchers[watcher] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
rawset(watcher, "properties", {})
|
||||
end
|
||||
|
||||
local function RunFunctionOfWatcher(watcher)
|
||||
local auto_run = watcher.auto_run
|
||||
assert(auto_run ~= nil, "can't find auto run function")
|
||||
ClearAllPropertiesOfWatcher(watcher) -- 解绑所有的binding,由auto_run重新生成
|
||||
PushWatcher(watcher)
|
||||
auto_run()
|
||||
local poped_watcher = PopWatcher()
|
||||
assert(watcher == poped_watcher, "fatal")
|
||||
end
|
||||
|
||||
|
||||
local function GetReactiveProperty(property, key)
|
||||
local meta = property.meta
|
||||
local property_watchers = property.watchers
|
||||
local current_watcher = PeekWatcher()
|
||||
if current_watcher ~= nil then
|
||||
local key_watchers = property_watchers[key] or {}
|
||||
key_watchers[current_watcher] = true
|
||||
property_watchers[key] = key_watchers
|
||||
AddPropertyToWatcher(current_watcher, property, key)
|
||||
end
|
||||
return rawget(meta, key)
|
||||
end
|
||||
|
||||
|
||||
local function SetReactiveProperty(property, key, value)
|
||||
local meta = property.meta
|
||||
local property_watchers = property.watchers
|
||||
rawset(meta, key, value)
|
||||
local key_watchers = property_watchers[key] or {}
|
||||
for watcher, state in pairs(key_watchers) do
|
||||
if state == true then
|
||||
triggered_watchers[watcher] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
ReactiveWatcherMeta.__index = ReactiveWatcherMeta
|
||||
ReactivePropertyMeta.__index = GetReactiveProperty
|
||||
ReactivePropertyMeta.__newindex = SetReactiveProperty
|
||||
|
||||
|
||||
-- 销毁Reactive Watcher
|
||||
function ReactiveWatcherMeta:Destroy()
|
||||
ClearAllPropertiesOfWatcher(self)
|
||||
auto_run_watcher_mapping[self.auto_run] = nil
|
||||
self.auto_run = nil
|
||||
end
|
||||
|
||||
function ReactivePropertyMeta:Destroy()
|
||||
local watchers = rawget(self, "watchers")
|
||||
return watchers
|
||||
end
|
||||
|
||||
|
||||
-- 创建auto_run的watcher, 并运行auto_run函数
|
||||
function Module.Watcher(auto_run)
|
||||
local watcher = CreateReactiveWatcher(auto_run)
|
||||
RunFunctionOfWatcher(watcher)
|
||||
return watcher
|
||||
end
|
||||
|
||||
function Module.ReactiveProperty(data)
|
||||
local Property = {
|
||||
meta = data or {},
|
||||
watchers = {},
|
||||
}
|
||||
return setmetatable(Property, ReactivePropertyMeta)
|
||||
end
|
||||
|
||||
function Module.RawGet(property, key)
|
||||
local meta = rawget(property, "meta")
|
||||
return rawget(meta, key)
|
||||
end
|
||||
|
||||
function Module.RawSet(property, key, value)
|
||||
local meta = rawget(property, "meta")
|
||||
rawset(meta, key, value)
|
||||
end
|
||||
|
||||
function Module.Process()
|
||||
local limit = 64
|
||||
while next(triggered_watchers) and limit > 0 do
|
||||
local triggered_list = {}
|
||||
for w, state in pairs(triggered_watchers) do
|
||||
if state == true then table.insert(triggered_list, w) end
|
||||
end
|
||||
for _, w in ipairs(triggered_list) do
|
||||
limit = limit - 1
|
||||
triggered_watchers[w] = nil
|
||||
RunFunctionOfWatcher(w)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Module
|
||||
Reference in New Issue
Block a user