diff --git a/src/class.lua b/src/class.lua index e2aa9c0..12422ba 100644 --- a/src/class.lua +++ b/src/class.lua @@ -12,6 +12,7 @@ function module.init(shared) local event = shared.event; ---@type quad_module_event local bind = event.bind; local store = shared.store; ---@type quad_module_store + local initStoreRegisterBinding = store.__initStoreRegisterBinding; local addObject = store.addObject; local storeNew = store.new; local mount = shared.mount; ---@type quad_module_mount @@ -98,45 +99,17 @@ function module.init(shared) local indexType = typeof(index); -- child - if indexType == "string" and valueType == "table" and value.t == "reg" then -- register (bind to store event) + if indexType == "string" and valueType == "table" and value.__type == "quad_register" then -- register (bind to store event) processedProperty[index] = true; -- ignore next - -- store binding - local with = value.wfunc; - local tstore = value.store; - local rawKey = value.key; - local tween = value.tvalue; - local from = value.fvalue; - local add = value.avalue; - local set = tstore[rawKey]; - if set ~= nil or (rawKey:match(",") and with) then - if add then - set = set + add; - end - if from then - set = from[set]; - end - if with then - set = with(tstore,set,value.key,item); - end - setProperty(item,index,set,className); - else - local dset = value.dvalue; - if dset then - setProperty(item,index,dset,className); - end + -- store reading + do + local setValue = value:calcWithDefault(item); + setProperty(item,index,setValue,className); end - -- adding event function + -- adding event function (bindding) local function regFn(_,newValue,key) - if add then - newValue = newValue + add; - end - if from then - newValue = from[newValue]; - end - if with then - newValue = with(tstore,newValue,key,item); - end + local setValue,tween = value:calcWithNewValue(item,newValue,key); if tween then if not advancedTween then return warn "[QUAD] module 'AdvancedTween' needs to be loaded for tween properties but it is not found on 'src.libs'. you should adding that to src.libs directory"; @@ -152,9 +125,9 @@ function module.init(shared) tween.OnStepped(item,...); end end - advancedTween.RunTween(item,tween,{[index] = newValue},ended,onStepped,setProperty,getProperty); + advancedTween.RunTween(item,tween,{[index] = setValue},ended,onStepped,setProperty,getProperty); else - setProperty(item,index,newValue,className); + setProperty(item,index,setValue,className); end end value:register(regFn); @@ -300,7 +273,7 @@ function module.init(shared) --- make new object function this.new(prop) -- make metatable - prop = storeNew(prop); + prop = storeNew(prop,nil); local parent = prop and (prop.Parent or prop.parent); local self = {__prop = prop; __parent = parent}; local init = this.init; @@ -308,6 +281,7 @@ function module.init(shared) init(self,prop); end setmetatable(self,this); + initStoreRegisterBinding(prop,this); -- render that local object = self:render(prop); diff --git a/src/store.lua b/src/store.lua index 10bf2f0..1a7ef00 100644 --- a/src/store.lua +++ b/src/store.lua @@ -134,6 +134,51 @@ function module.init(shared) add = function (s,value) return setmetatable({avalue = value},{__index = s}); end; + -- return init data + calcWithDefault = function (s,withItem) + local with = s.wfunc; + local tstore = s.store; + local rawKey = s.key; + local tween = s.tvalue or s.dtvalue; + local from = s.fvalue; + local add = s.avalue; + local set = tstore[rawKey]; + if set ~= nil or (rawKey:match(",") and with) then + if add then + set = set + add; + end + if from then + set = from[set]; + end + if with then + set = with(tstore,set,rawKey,withItem); + end + return set,tween; + else + local dset = s.dvalue; + if dset ~= nil then + return dset,tween; + end + warn "[Quad] no default value found."; + end + end; + calcWithNewValue = function(s,withItem,newValue,key) + local with = s.wfunc; + local tstore = s.store; + local tween = s.tvalue or s.dtvalue; + local from = s.fvalue; + local add = s.avalue; + if add then + newValue = newValue + add; + end + if from then + newValue = from[newValue]; + end + if with then + newValue = with(tstore,newValue,key,withItem); + end + return newValue,tween; + end }; registerClass.__index = registerClass; @@ -148,6 +193,11 @@ function module.init(shared) return store[key]; end function store:__newindex(key,value) + -- if got register, just copy data to self and connect + if type(value) == "table" and value.__type == "quad_register" then + warn "[Quad] adding register value on store is only allowed when init store. set value request was ignored"; + return; + end self.__self[key] = value; local event = self.__evt[key]; if event then @@ -156,17 +206,49 @@ function module.init(shared) end end end + -- init bindings + function new.__initStoreRegisterBinding(self,withItem) + local selfTweens = self.__tweens; + local selfValues = self.__self; + for key,item in pairs(selfValues) do + if type(item) == "table" and item.__type == "quad_register" then + -- fetch data from origin + do + local tstore = item.store; + for tkey in item.key:gmatch("^[,]") do + selfValues[tkey] = tstore[tkey]; + end + end + + -- calc value + do + local setValue,tween = item:calcWithDefault(withItem); + selfValues[key] = setValue; + selfTweens[key] = tween; + end + + -- make event connection + item:register(function (_,newValue,eventKey) + -- !HOLD IT SELF TO PREVENT THIS REGISTER BEGIN REMOVED FROM MEMORY + local setValue = item:calcWithNewValue(withItem,newValue,eventKey); + self[key] = setValue; + end); + end + end + end + -- create register function store:__call(key,func) local last = self.__self[key]; if last and type(last) == "table" and getmetatable(last) == registerClass then return last; end local register = self.__reg[key]; + local tweens = self.__tweens; if not register then register = setmetatable({ key = key; store = self; - t = "reg"; + dtvalue = tweens and tweens[key]; },registerClass); self.__reg[key] = register; end @@ -184,22 +266,22 @@ function module.init(shared) end end function new.new(self,id) - if id then - local old = storeIdSpace[id]; - if old then - return old; - end - end local this = setmetatable( - {__self = self or {},__evt = {},__reg = setmetatable({},week)},store + { + __self = self or {}, -- real value storage + __evt = {}, -- changed event handler functions (dict of array) + __reg = setmetatable({},week), -- save registers + __tweens = {} -- tweens (if inited with register, save tween and use as default tween data) + },store ); - if id then + if id then -- save in id space storeIdSpace[id] = this; end return this; end + local storeNew = new.new; function new.getStore(id) - return storeIdSpace[id] or new.new({},id); + return storeIdSpace[id] or storeNew({},id); end return new;