Fix indents, method names

This commit is contained in:
Qwreey 2023-02-17 01:26:57 +09:00
parent 83bb7ee817
commit 46da90f5f8
9 changed files with 553 additions and 531 deletions

View file

@ -1,323 +1,343 @@
local module = {}; local module = {}
local pack = table.pack; local pack = table.pack
local match = string.match; local match = string.match
local insert = table.insert; local insert = table.insert
local gsub = string.gsub local gsub = string.gsub
---@param shared quad_export ---@param shared quad_export
---@return quad_module_class ---@return quad_module_class
function module.init(shared) function module.init(shared)
local warn = shared.warn; local warn = shared.warn
---@class quad_module_class ---@class quad_module_class
local new = {__type = "quad_module_class"}; local new = {__type = "quad_module_class"}
local InstanceNew = Instance.new; local InstanceNew = Instance.new
local event = shared.Event; ---@type quad_module_event local event = shared.Event ---@type quad_module_event
local bind = event.Bind; local bind = event.Bind
local store = shared.Store; ---@type quad_module_store local store = shared.Store ---@type quad_module_store
local initStoreRegisterBinding = store.__initStoreRegisterBinding; local initStoreRegisterBinding = store.__initStoreRegisterBinding
local addObject = store.AddObject; local addObject = store.AddObject
local storeNew = store.New; local storeNew = store.New
local mount = shared.Mount; ---@type quad_module_mount local mount = shared.Mount ---@type quad_module_mount
local getHolder = mount.GetHolder; local getHolder = mount.GetHolder
local mountfunc = mount.Mount; local mountfunc = mount.Mount
local style = shared.Style; ---@type quad_module_style local style = shared.Style ---@type quad_module_style
local styleList = style.Styles; local styleList = style.Styles
local parseStyles = style.ParseStyles; local parseStyles = style.ParseStyles
local advancedTween = shared.Tween; ---@type quad_module_tween local advancedTween = shared.Tween ---@type quad_module_tween
local round = shared.Round; ---@type quad_module_round local round = shared.Round ---@type quad_module_round
local function InstanceNewWithName(classname,parent,name) local function InstanceNewWithName(classname,parent,name)
local item = InstanceNew(classname,parent); local item = InstanceNew(classname,parent)
item.Name = name; item.Name = name
return item; return item
end end
local function GetProperty(item,index,ClassName) local function GetProperty(item,index,ClassName)
if type(item) == "table" then return item[index]; end if type(item) == "table" then return item[index] end
ClassName = ClassName or item.ClassName; ClassName = ClassName or item.ClassName
local isImage = (ClassName == "ImageLabel" or ClassName == "ImageButton"); local isImage = (ClassName == "ImageLabel" or ClassName == "ImageButton")
if (index == "RoundSize" or index == "roundSize") and isImage then if (index == "RoundSize") and isImage then
if not round then if not round then
error("module 'round' needs to be loaded for get image round size but it is not found on 'src.libs'. you should adding that to src.libs directory"); error("module 'round' needs to be loaded for get image round size but it is not found on 'src.libs'. you should adding that to src.libs directory")
end end
return round.GetRound(item); return round.GetRound(item)
elseif index == "UiRoundSize" or index == "uiRoundSize" or index == "UIRoundSize" then elseif index == "Corner" then
local target = (ClassName == "UICorner" and item) or item:FindFirstChildOfClass("UICorner"); local target = (ClassName == "UICorner" and item) or item:FindFirstChildOfClass("UICorner")
return (target and target.CornerRadius.Offset) or 0; return (target and target.CornerRadius.Offset) or 0
elseif index == "PaddingAll" or index == "paddingAll" then elseif index == "PaddingAll" then
local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding"); local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding")
return (target and target.PaddingLeft) or UDim.new(0,0); return (target and target.PaddingLeft) or UDim.new(0,0)
elseif index == "PaddingAllOffset" or index == "paddingAllOffset" then elseif index == "PaddingAllOffset" then
local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding"); local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding")
return (target and target.PaddingLeft.Offset) or 0; return (target and target.PaddingLeft.Offset) or 0
elseif index == "Scale" then elseif index == "Scale" then
local target = (ClassName == "UIScale" and item) or item:FindFirstChildOfClass("UIScale"); local target = (ClassName == "UIScale" and item) or item:FindFirstChildOfClass("UIScale")
return (target and target.Scale) or 1; return (target and target.Scale) or 1
end end
return item[index]; return item[index]
end end
new.GetProperty = GetProperty new.GetProperty = GetProperty
local function SetProperty(item,index,value,ClassName) local function SetProperty(item,index,value,ClassName)
if type(item) == "table" then item[index] = value; return; end -- if it is not a roblox instance, just call __index
ClassName = ClassName or item.ClassName; if type(item) == "table" then
local isImage = (ClassName == "ImageLabel" or ClassName == "ImageButton"); item[index] = value
if (index == "RoundSize" or index == "roundSize") and isImage then return
if not round then
error("[QUAD] module 'round' needs to be loaded for set image round size but it is not found on 'src.libs'. you should adding that to src.libs directory");
end end
round.SetRound(item,value);
elseif index == "UIRoundSize" or index == "uiRoundSize" or index == "UiRoundSize" then -- check class name
local uiCorner = (ClassName == "UICorner" and item) or item:FindFirstChildOfClass("UICorner") or InstanceNewWithName("UICorner",item,"_quad_round"); ClassName = ClassName or item.ClassName
uiCorner.CornerRadius = UDim.new(0,value); -- check is ImageLabel or ImageButton
elseif index == "PaddingAll" or index == "paddingAll" then local isImage = (ClassName == "ImageLabel" or ClassName == "ImageButton")
local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding") or InstanceNewWithName("UIPadding",item,"_quad_padding");
target.PaddingLeft = value; -- Round Image
target.PaddingRight = value; if index == "RoundSize" and isImage then
target.PaddingTop = value; if not round then
target.PaddingBottom = value; error("[QUAD] module 'round' needs to be loaded for set image round size but it is not found on 'src.libs'. you should adding that to src.libs directory")
elseif index == "PaddingAllOffset" or index == "paddingAllOffset" then end
local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding") or InstanceNewWithName("UIPadding",item,"_quad_padding"); round.SetRound(item,value)
local padding = UDim.new(0,value); -- UIRound
target.PaddingLeft = padding; elseif index == "Corner" then
target.PaddingRight = padding; local uiCorner = (ClassName == "UICorner" and item) or item:FindFirstChildOfClass("UICorner") or InstanceNewWithName("UICorner",item,"_quad_round")
target.PaddingTop = padding; uiCorner.CornerRadius = UDim.new(0,value)
target.PaddingBottom = padding; -- PaddingAll
elseif index == "PaddingAll" then
local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding") or InstanceNewWithName("UIPadding",item,"_quad_padding")
target.PaddingLeft = value
target.PaddingRight = value
target.PaddingTop = value
target.PaddingBottom = value
-- PaddingAll with Offset
elseif index == "PaddingAllOffset" then
local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding") or InstanceNewWithName("UIPadding",item,"_quad_padding")
local padding = UDim.new(0,value)
target.PaddingLeft = padding
target.PaddingRight = padding
target.PaddingTop = padding
target.PaddingBottom = padding
-- Scale
elseif index == "Scale" then elseif index == "Scale" then
local target = (ClassName == "UIScale" and item) or item:FindFirstChildOfClass("UIScale") or InstanceNewWithName("UIScale",item,"_quad_scale"); local target = (ClassName == "UIScale" and item) or item:FindFirstChildOfClass("UIScale") or InstanceNewWithName("UIScale",item,"_quad_scale")
target.Scale = value; target.Scale = value
else else
item[index] = value; -- set property -- other, just set property
item[index] = value
end end
end end
new.SetProperty = SetProperty new.SetProperty = SetProperty
local function RawGetProperty(item,index) local function RawGetProperty(item,index)
return item[index]; return item[index]
end end
local function PcallGetProperty(item,index) local function PcallGetProperty(item,index)
local ok,err = pcall(RawGetProperty,item,index); local ok,err = pcall(RawGetProperty,item,index)
if ok then return err; end if ok then return err end
return nil; return nil
end end
local function ProcessQuadProperty(processedProperty,iprop,holder,item,className,index,value) local function ProcessQuadProperty(processedProperty,iprop,holder,item,className,index,value)
if processedProperty[index] then return; end if processedProperty[index] then
return
end
local valueType = typeof(value); local valueType = typeof(value)
local indexType = typeof(index); local indexType = typeof(index)
local quadType = valueType == "table" and PcallGetProperty(value,"__type") local quadType = valueType == "table" and PcallGetProperty(value,"__type")
if indexType == "string" and quadType == "quad_register" then if indexType == "string" and quadType == "quad_register" then
-- register (bind to store event) -- register (bind to store event)
processedProperty[index] = true; -- ignore next processedProperty[index] = true -- ignore next
-- store reading -- store reading
do do
local setValue = value:calcWithDefault(item); local setValue = value:calcWithDefault(item)
if setValue == nil then if setValue == nil then
warn "[Quad] register return value must not be nil, but got nil. did you inited values before?"; warn "[Quad] register return value must not be nil, but got nil. did you inited values before?"
end end
SetProperty(item,index,setValue,className); SetProperty(item,index,setValue,className)
end end
-- adding handle function (bindding) -- adding handle function (bindding)
local function regFn(_,newValue,key) local function regFn(_,newValue,key)
local setValue,tween = value:calcWithNewValue(item,newValue,key); local setValue,tween = value:calcWithNewValue(item,newValue,key)
if tween then if tween then
if not advancedTween 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"; 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"
end end
local ended, onStepped; local ended, onStepped
if tween.Ended then if tween.Ended then
ended = function (...) ended = function (...)
tween.Ended(item,...); tween.Ended(item,...)
end end
end end
if tween.OnStepped then if tween.OnStepped then
onStepped = function (...) onStepped = function (...)
tween.OnStepped(item,...); tween.OnStepped(item,...)
end end
end end
advancedTween.RunTween(item,tween,{[index] = setValue},ended,onStepped,SetProperty,GetProperty); advancedTween.RunTween(item,tween,{[index] = setValue},ended,onStepped,SetProperty,GetProperty)
else else
SetProperty(item,index,setValue,className); SetProperty(item,index,setValue,className)
end end
end end
value:register(regFn); value:register(regFn)
-- this is using hacky of roblox instance -- this is using hacky of roblox instance
-- this is will keep reference from week table until -- this is will keep reference from week table until
-- inscance got GCed -- inscance got GCed
item:GetPropertyChangedSignal("ClassName"):Connect(regFn); item:GetPropertyChangedSignal("ClassName"):Connect(regFn)
elseif (valueType == "function" or valueType == "table") and indexType == "string" and bind(item,index,value,valueType) then -- connect event elseif (valueType == "function" or valueType == "table") and indexType == "string" and bind(item,index,value,valueType) then -- connect event
-- event binding -- event binding
elseif indexType == "string" then elseif indexType == "string" then
processedProperty[index] = true; -- ignore next processedProperty[index] = true -- ignore next
-- prop set -- prop set
SetProperty(item,index,value,className); SetProperty(item,index,value,className)
elseif indexType == "number" and valueType == "table" and quadType == "quad_style" then -- style elseif indexType == "number" and valueType == "table" and quadType == "quad_style" then -- style
-- style parsing -- style parsing
for _,thisStyle in ipairs(parseStyles(value)) do for _,thisStyle in ipairs(parseStyles(value)) do
if not processedProperty[thisStyle] then if not processedProperty[thisStyle] then
processedProperty[thisStyle] = true; processedProperty[thisStyle] = true
for styleIndex,styleValue in pairs(thisStyle) do for styleIndex,styleValue in pairs(thisStyle) do
if type(styleValue) ~= "table" or pcall(styleValue,"__type") ~= "quad_style" then if type(styleValue) ~= "table" or pcall(styleValue,"__type") ~= "quad_style" then
ProcessQuadProperty(processedProperty,iprop,holder,item,className,styleIndex,styleValue); ProcessQuadProperty(processedProperty,iprop,holder,item,className,styleIndex,styleValue)
end end
end end
end end
end end
elseif indexType == "number" and valueType ~= "boolean" then -- object elseif indexType == "number" and valueType ~= "boolean" then -- object
-- child object -- child object
mountfunc(item,((iprop == 1) and value or value:Clone()),holder); mountfunc(item,((iprop == 1) and value or value:Clone()),holder)
end end
end end
-- make object that from instance, class and more -- make object that from instance, class and more
function new.make(ClassName,...) -- render object function new.Make(ClassName,...) -- render object
-- make object from ClassName -- make object from ClassName
local item; local item
local classOfClassName = type(ClassName); local classOfClassName = type(ClassName)
if classOfClassName == "string" then -- if classname is a string value, cdall instance.new for making new roblox instance if classOfClassName == "string" then -- if classname is a string value, cdall instance.new for making new roblox instance
item = InstanceNew(ClassName); item = InstanceNew(ClassName)
elseif classOfClassName == "function" then -- if classname is a function value, call it for making new object (OOP object) elseif classOfClassName == "function" then -- if classname is a function value, call it for making new object (OOP object)
item = ClassName(); item = ClassName()
elseif classOfClassName == "table" then -- if classname is a calss what is included new function, call it for making new object (object) elseif classOfClassName == "table" then -- if classname is a calss what is included new function, call it for making new object (object)
local func = ClassName.new or ClassName.New or ClassName.__new; local func = ClassName.new or ClassName.New or ClassName.__new
if ClassName.__noSetup then -- if is support initing props if ClassName.__noSetup then -- if is support initing props
local childs,props,parsed,binds = {},pack(...),{},{}; local childs,props,parsed,binds = {},pack(...),{},{}
for iprop = props.n,1,-1 do for iprop = props.n,1,-1 do
local prop = props[iprop]; local prop = props[iprop]
if prop then if prop then
for i,v in pairs(prop) do for i,v in pairs(prop) do
if type(i) == "number" then if type(i) == "number" then
childs[i] = ((iprop == 1) and v or v:Clone()); childs[i] = ((iprop == 1) and v or v:Clone())
elseif bind(i) then elseif bind(i) then
binds[i] = v; binds[i] = v
else else
parsed[i] = v; parsed[i] = v
end end
end end
end end
end end
item = func(parsed); item = func(parsed)
local holder = getHolder(item); local holder = getHolder(item)
for _,v in ipairs(childs) do for _,v in ipairs(childs) do
mountfunc(item,v,holder); mountfunc(item,v,holder)
end end
for i,v in pairs(binds) do for i,v in pairs(binds) do
bind(item,i,v); bind(item,i,v)
end end
return item; return item
end end
item = func(); item = func()
end end
if not item then -- if cannot make new object, ignore this call if not item then -- if cannot make new object, ignore this call
local str = tostring(ClassName); local str = tostring(ClassName)
warn(("[Quad] fail to make item '%s', did you forget to checking the class '%s' is exist?"):format(str,str)); warn(("[Quad] fail to make item '%s', did you forget to checking the class '%s' is exist?"):format(str,str))
end end
-- set property and adding child and binding functions -- set property and adding child and binding functions
local holder = getHolder(item); -- to __holder or holder or it self (for tabled) local holder = getHolder(item) -- to __holder or holder or it self (for tabled)
-- for iprop,prop in ipairs({...}) do -- for iprop,prop in ipairs({...}) do
local propsListArray = pack(...); local propsListArray = pack(...)
local processedProperty = {}; local processedProperty = {}
for iprop = 1,propsListArray.n do for iprop = 1,propsListArray.n do
local prop = propsListArray[iprop] local prop = propsListArray[iprop]
if prop then if prop then
for index,value in pairs(prop) do for index,value in pairs(prop) do
if type(index) ~= "number" then if type(index) ~= "number" then
ProcessQuadProperty(processedProperty,iprop,holder,item,ClassName,index,value); ProcessQuadProperty(processedProperty,iprop,holder,item,ClassName,index,value)
end end
end end
for index,value in ipairs(prop) do for index,value in ipairs(prop) do
ProcessQuadProperty(processedProperty,iprop,holder,item,ClassName,index,value); ProcessQuadProperty(processedProperty,iprop,holder,item,ClassName,index,value)
end end
end end
end end
return item; return item
end end
local make = new.make; local make = new.Make
-- import quad object -- import quad object
function new.import(ClassName,defaultProperties) -- make new quad class object function new.Import(ClassName,defaultProperties) -- make new quad class object
if type(ClassName) == "userdata" and ClassName.ClassName == "ModuleScript" then if type(ClassName) == "userdata" and ClassName.ClassName == "ModuleScript" then
ClassName = require(ClassName); ClassName = require(ClassName)
end end
local this = defaultProperties or {}; local this = defaultProperties or {}
setmetatable(this,{ setmetatable(this,{
__type = "quad_imported_class", __type = "quad_imported_class",
__call = function (self,prop,...) __call = function (self,prop,...)
local propType = type(prop); local propType = type(prop)
if propType == "string" then if propType == "string" then
local lastName = prop; local lastName = prop
return function (nprop,...) return function (nprop,...)
nprop = nprop or {}; nprop = nprop or {}
nprop.Name = gsub(gsub(match(lastName,"[^,]+")," +$",""),"^ +",""); nprop.Name = gsub(gsub(match(lastName,"[^,]+")," +$",""),"^ +","")
for styleName,styleObj in pairs(styleList) do for styleName,styleObj in pairs(styleList) do
if match(prop,styleName) then if match(prop,styleName) then
insert(nprop,styleObj); insert(nprop,styleObj)
end end
end end
local item = make(ClassName,nprop,...,this); local item = make(ClassName,nprop,...,this)
addObject(lastName,item); addObject(lastName,item)
return item; return item
end; end
elseif propType == "nil" then elseif propType == "nil" then
return make(ClassName,this); return make(ClassName,this)
end end
return make(ClassName,prop,...,this); return make(ClassName,prop,...,this)
end; end
}); })
return this; return this
end end
-- set module calling function -- set module calling function
setmetatable(new,{ setmetatable(new,{
__call = function (self,...) __call = function (self,...)
return new.import(...); return new.Import(...)
end; end
}); })
-- make class -- make class
function new.extend() function new.Extend()
local this = {__type = "quad_extend"}; local this = {__type = "quad_extend"}
--- make new object --- make new object
function this.new(prop) function this.New(prop)
-- make metatable -- make metatable
prop = storeNew(prop,nil); prop = storeNew(prop,nil)
local parent = prop and (prop.Parent or prop.parent); local parent = prop and (prop.Parent or prop.parent)
local self = {__prop = prop; __parent = parent,__propertyChangedSignals = {}}; local self = {
local init = this.init; __prop = prop;
__parent = parent;
__propertyChangedSignals = {};
}
local init = this.Init
if init then if init then
init(self,prop); init(self,prop)
end end
setmetatable(self,this); setmetatable(self,this)
initStoreRegisterBinding(prop,this); initStoreRegisterBinding(prop,this)
-- render that -- render that
local object = self:render(prop); local object = self:Render(prop)
rawset(self,"__object",object); rawset(self,"__object",object)
rawset(self,"__holder",object); rawset(self,"__holder",object)
if parent then if parent then
rawset(self,"__parent",parent); rawset(self,"__parent",parent)
mountfunc(self,parent) mountfunc(self,parent)
end end
-- prevent gc -- prevent gc
((type(object) == "table" and object.__object) or object) ((type(object) == "table" and object.__object) or object)
:GetPropertyChangedSignal "ClassName":Connect(function() :GetPropertyChangedSignal "ClassName":Connect(function()
return self; return self
end); end)
--after render --after render
local afterRender = this.afterRender; local afterRender = this.AfterRender
if afterRender then if afterRender then
afterRender(self,object); afterRender(self,object)
end end
return self; return self
end end
function this:GetPropertyChangedSignal(propertyName) function this:GetPropertyChangedSignal(propertyName)
@ -333,126 +353,123 @@ function module.init(shared)
end end
--- re-render object (if some props chaged, call this to render again) --- re-render object (if some props chaged, call this to render again)
function this:update() -- swap object function this:Update() -- swap object
local object = rawget(self,"__object"); -- get last instance local object = rawget(self,"__object") -- get last instance
local parent = object and object.Parent; -- date parent local parent = object and object.Parent -- date parent
if not object then if not object then
parent = rawget(self,"__parent"); parent = rawget(self,"__parent")
end end
local lastObject = object; local lastObject = object
if lastObject then if lastObject then
lastObject.Parent = nil; lastObject.Parent = nil
end end
object = self:render(self.__prop); -- new instance object = self:Render(self.__prop) -- new instance
rawset(self,"__holder",object); rawset(self,"__holder",object)
rawset(self,"__object",object); rawset(self,"__object",object)
object.Parent = getHolder(parent); -- update parent object.Parent = getHolder(parent) -- update parent
-- restore childs -- restore childs
local child = rawget(self,"__child"); local child = rawget(self,"__child")
if child then if child then
for _,v in pairs(child) do for _,v in pairs(child) do
if v then if v then
v.Parent = object; v.Parent = object
end end
end end
end end
-- prevnet gc -- prevnet gc
((type(object) == "table" and object.__object) or object):GetPropertyChangedSignal "ClassName":Connect(function() ((type(object) == "table" and object.__object) or object):GetPropertyChangedSignal "ClassName":Connect(function()
return self; return self
end); end)
if lastObject then -- remove old instance if lastObject then -- remove old instance
self:Destroy(lastObject); self:Destroy(lastObject)
end end
--after render --after render
local afterRender = this.afterRender; local afterRender = this.AfterRender
if afterRender then if afterRender then
afterRender(self,object); afterRender(self,object)
end end
end end
-- define destroy method -- define destroy method
function this:Destroy(object) function this:Destroy(object)
local unload = rawget(self,"unload"); local unload = this.Unload
object = object or rawget(self,"__object"); object = object or rawget(self,"__object")
if object then if object then
if unload then if unload then
unload(self,object); unload(self,object)
else else
local destroy = (object.Destroy or object.destroy); local destroy = (object.Destroy or object.destroy)
if destroy then if destroy then
pcall(destroy,object); pcall(destroy,object)
end end
end end
end end
self = nil; self = nil
end end
--- link to new --- link to new
function this.__call(self,...) function this.__call(self,...)
return (self.new or self.New or self.__new)(...); return (self.new or self.New or self.__new)(...)
end; end
-- indexer (getter) -- indexer (getter)
function this:__index(k) function this:__index(k)
if k == "destroy" then local getter = this.Getter[k]
return self.Destroy;
end
local getter = this.getter[k];
if getter then if getter then
return getter(self,rawget(self,"__object")); return getter(self,rawget(self,"__object"))
end end
-- from this (have more priority) -- from this (have more priority)
local fromThis = this[k]; local fromThis = this[k]
if fromThis then if fromThis then
return fromThis; return fromThis
end end
-- from prop, not start with '_' (private value) -- from prop, not start with '_' (private value)
if k:sub(1,1) ~= "_" then if k:sub(1,1) ~= "_" then
return self.__prop[k]; return self.__prop[k]
end end
end end
--- new indexer (setter) --- new indexer (setter)
function this:__newindex(k,v) function this:__newindex(k,v)
-- from setter -- from setter
local setter = this.setter[k]; local setter = this.Setter[k]
if setter then if setter then
return setter(self,v,rawget(self,"__object")); return setter(self,v,rawget(self,"__object"))
end end
-- is private (self value) -- is private (self value)
if k == "holder" or k:sub(1,1) == "_" then if k == "holder" or k:sub(1,1) == "_" then
return rawset(self,k,v); return rawset(self,k,v)
end end
-- prop update -- prop update
self.__prop[k] = v; self.__prop[k] = v
if this.updateTriggers[k] then if this.UpdateTriggers[k] then
self:update(); self:Update()
end end
end end
this.getter = {}; this.Getter = {}
this.setter = { this.Setter = {
Parent = function(self,parent,object) Parent = function(self,parent,object)
rawset(self,"__parent",parent); rawset(self,"__parent",parent)
if object then if object then
object.Parent = getHolder(parent); object.Parent = getHolder(parent)
end end
end; end
}; }
this.updateTriggers = {}; this.UpdateTriggers = {}
this.__noSetup = true; this.__noSetup = true
return this; return this
end end
return new; return new
end end
return module; return module

View file

@ -1,139 +1,101 @@
local module = {}; local module = {}
local unpack = table.unpack; local unpack = table.unpack
local wrap = coroutine.wrap; local wrap = coroutine.wrap
---@param shared quad_export ---@param shared quad_export
---@return quad_module_event ---@return quad_module_event
function module.init(shared) function module.init(shared)
local warn = shared.warn; local warn = shared.warn
---@class quad_module_event ---@class quad_module_event
local new = {__type = "quad_module_event"}; local new = {__type = "quad_module_event"}
local prefix = "Event::"; local prefix = "Event::"
local special = { local special = {
["Property::(.+)"] = function (this,func,property) ["Property::(.+)"] = function (this,func,property)
this:GetPropertyChangedSignal(property):Connect(function() this:GetPropertyChangedSignal(property):Connect(function()
func(this,this[property]); func(this,this[property])
end); end)
end; end;
["CreatedSync::"] = function (this,func) ["CreatedSync::"] = function (this,func)
func(this); func(this)
end; end;
["CreatedAsync::"] = function (this,func) ["CreatedAsync::"] = function (this,func)
wrap(func)(this); wrap(func)(this)
end; end;
}; }
local prefixLen = #prefix; local prefixLen = #prefix
setmetatable(new,{ setmetatable(new,{
__call = function(self,eventName) __call = function(self,eventName)
return prefix .. eventName; return prefix .. eventName
end; end;
__index = function(self,key) __index = function(self,key)
if key == "createdSync" then if key == "createdSync" then
warn "[Quad] event.createdSync is deprecated. Use event.created instead" warn "[Quad] event.createdSync is deprecated. Use event.created instead"
return self.created; return self.created
end end
end; end;
}); })
-- try binding, if key dose match with anything, ignore call -- try binding, if key dose match with anything, ignore call
function new.bind(this,key,func,typefunc) function new.Bind(this,key,func,typefunc)
if not key then if not key then
key = this; key = this
this = nil; this = nil
end end
-- if is advanced binding (self setted) -- if is advanced binding (self setted)
typefunc = typefunc or type(func); typefunc = typefunc or type(func)
local self; local self
if typefunc == "table" then if typefunc == "table" then
local t = func; local t = func
self = t.self; self = t.self
func = t.func; func = t.func
if not self then self = t[1]; end if not self then self = t[1] end
if not func then func = t[2]; end if not func then func = t[2] end
end end
-- check prefix -- check prefix
if key:sub(1,prefixLen) ~= prefix then if key:sub(1,prefixLen) ~= prefix then
return; return
end end
key = key:sub(prefixLen + 1,-1); key = key:sub(prefixLen + 1,-1)
-- find special bindings -- find special bindings
for specKey,specFunc in pairs(special) do for specKey,specFunc in pairs(special) do
local find = {key:match(specKey)}; local find = {key:match(specKey)}
if #find ~= 0 then if #find ~= 0 then
if func then if func then
specFunc(this,func,unpack(find)); specFunc(this,func,unpack(find))
end end
return true; return true
end end
end end
-- binding normal events -- binding normal events
if this then if this then
local event = this[key]; local event = this[key]
if event then if event then
if func then if func then
event:Connect(function(...) event:Connect(function(...)
func(self or this,...); func(self or this,...)
end); end)
end end
return true; return true
end end
end end
end end
-- property changed binding -- property changed binding
local prefixProperty = prefix .. "Property::"; local prefixProperty = prefix .. "Property::"
function new.prop(name) function new.Prop(name)
return prefixProperty .. name; return prefixProperty .. name
end end
-- when created binding -- when created binding
new.createdAsync = prefix .. "CreatedAsync::"; new.CreatedAsync = prefix .. "CreatedAsync::"
new.created = prefix .. "CreatedSync::"; new.Created = prefix .. "CreatedSync::"
-- roblox connections disconnecter return new
local insert = table.insert;
local idSpace = {};
local disconnecterClass = {__type = "quad_disconnecter"};
function disconnecterClass:add(connection)
insert(self,connection);
end
function disconnecterClass:disconnect()
for i,v in pairs(self) do
pcall(v.Disconnect,v);
self[i] = nil;
end
end
function disconnecterClass:destroy()
local id = self.id;
if id then
idSpace[id] = nil;
end
for i,v in pairs(self) do
pcall(v.Disconnect,v);
self[i] = nil;
end
end
disconnecterClass.__index = disconnecterClass;
function new.disconnecter(id)
if id then
local old = idSpace[id];
if old then
return old;
end
end
local this = setmetatable({id = id},disconnecterClass);
if id then
idSpace[id] = this;
end
return this;
end end
return new; return module
end
return module;

View file

@ -1,5 +1,5 @@
---@class quad ---@class quad
local module = {}; local module = {}
local IS_TEST = true local IS_TEST = true
local VER = "1.14" .. (IS_TEST and "B" or "") local VER = "1.14" .. (IS_TEST and "B" or "")
@ -7,19 +7,19 @@ if IS_TEST then
warn("You are using BETA version of quad now. Many features may change in the future and unstable. AS USING BETA VERSION OF QUAD, YOU SHOULD KNOW IT WILL BUGGY SOMETIME. still on development - you can ignore this message if have no issue. if you have issue on using quad, please report issue on github. VERSION: "..VER) warn("You are using BETA version of quad now. Many features may change in the future and unstable. AS USING BETA VERSION OF QUAD, YOU SHOULD KNOW IT WILL BUGGY SOMETIME. still on development - you can ignore this message if have no issue. if you have issue on using quad, please report issue on github. VERSION: "..VER)
end end
local require = require(script.require); local require = require(script.require)
local style = require "style"; local style = require "style"
local event = require "event"; local event = require "event"
local store = require "store"; local store = require "store"
local class = require "class"; local class = require "class"
local mount = require "mount"; local mount = require "mount"
-- local lang = require "lang"; -- local lang = require "lang"
-- submodule -- submodule
local _,advancedTween = pcall(require,"libs.AdvancedTween"); local _,advancedTween = pcall(require,"libs.AdvancedTween")
local _,round = pcall(require,"libs.round"); local _,round = pcall(require,"libs.round")
local idSpace = {}; local idSpace = {}
---@return quad_export this ---@return quad_export this
---@return quad_module_round round ---@return quad_module_round round
@ -63,7 +63,7 @@ end
function module.Uninit(id) function module.Uninit(id)
pcall(cleanup,idSpace[id]) pcall(cleanup,idSpace[id])
idSpace[id] = nil; idSpace[id] = nil
end end
return module; return module

View file

@ -1,97 +1,102 @@
local module = {}; local module = {}
local insert = table.insert; local insert = table.insert
local pack = table.pack; local pack = table.pack
---@param shared quad_export ---@param shared quad_export
---@return quad_module_mount ---@return quad_module_mount
function module.init(shared) function module.init(shared)
local warn = shared.warn; local warn = shared.warn
---@class quad_module_mount ---@class quad_module_mount
local new = {__type = "quad_module_mount"}; local new = {__type = "quad_module_mount"}
local mountClass = {__type = "quad_mount"}; -- get Holder object
mountClass.__index = mountClass; local function getHolder(item)
function mountClass:unmount() return (type(item) == "table") and (item._holder or item.holder or item.__holder) or item
end
new.GetHolder = getHolder
-- mount class
local mountClass = {__type = "quad_mount"}
mountClass.__index = mountClass
function mountClass:Unmount()
local this = self.this local this = self.this
local typeThis = type(this); local typeThis = type(this)
if typeThis == "userdata" then if typeThis == "userdata" then
this:Destroy(); this:Destroy()
elseif typeThis == "table" then elseif typeThis == "table" then
pcall(function() pcall(function()
this.Parent = nil; this.Parent = nil
end); end)
local destroyThis = this.Destroy; local destroyThis = this.Destroy
if destroyThis then if destroyThis then
pcall(destroyThis,this); pcall(destroyThis,this)
end end
--if sef.to when --if sef.to when
-- todo for remove child on parent -- todo for remove child on parent
end end
end end
function new.getHolder(item) -- mount function
return (type(item) == "table") and (item._holder or item.holder or item.__holder) or item; local function mount(to,this,holder)
end local thisObject = this
local getHolder = new.getHolder;
-- we should add plugin support
function new.mount(to,this,holder)
local thisObject = this;
if type(this) == "table" then if type(this) == "table" then
thisObject = rawget(this,"__object"); thisObject = rawget(this,"__object")
local parent = rawget(this,"__parent"); local parent = rawget(this,"__parent")
if type(parent) == "table" then if type(parent) == "table" then
local parentChild = rawget(parent,"__child"); local parentChild = rawget(parent,"__child")
if parentChild then if parentChild then
for i,v in pairs(parentChild) do for i,v in pairs(parentChild) do
if v == this then if v == this then
parentChild[i] = nil; parentChild[i] = nil
end end
end end
end end
end end
rawset(this,"__parent",to); rawset(this,"__parent",to)
end end
if thisObject then if thisObject then
thisObject.Parent = holder or getHolder(to); thisObject.Parent = holder or getHolder(to)
else else
this.Parent = holder or getHolder(to); this.Parent = holder or getHolder(to)
end end
if type(to) == "table" then if type(to) == "table" then
local child = rawget(to,"__child"); local child = rawget(to,"__child")
if not child then if not child then
child = {}; child = {}
rawset(to,"__child",child); rawset(to,"__child",child)
end end
insert(child,this); insert(child,this)
end end
return setmetatable({to = to,this = this},mountClass); return setmetatable({to = to,this = this},mountClass)
end end
local mount = new.mount; new.Mount = mount
local mountsClass = {__type = "quad_mounts"}; -- mount(s) class
mountsClass.__index = mountsClass; local mountsClass = {__type = "quad_mounts"}
function mountsClass:unmount() mountsClass.__index = mountsClass
function mountsClass:Unmount()
for _,v in ipairs(self) do for _,v in ipairs(self) do
v:unmount(); v:unmount()
end end
end end
-- handle __call
setmetatable(new,{ setmetatable(new,{
__call = function (self,to,...) __call = function (self,to,...)
if select("#",...) == 1 then if select("#",...) == 1 then
return new.mount(to,...); return mount(to,...)
end end
local mounts = {}; local mounts = {}
local items = pack(...); local items = pack(...)
for _,item in ipairs(items) do for _,item in ipairs(items) do
insert(mounts,mount(to,item)); insert(mounts,mount(to,item))
end end
setmetatable(mounts,mountsClass); setmetatable(mounts,mountsClass)
return mounts; return mounts
end; end
}); })
return new; return new
end end
return module; return module

View file

@ -2,30 +2,30 @@
-- now, we can call modules with string path -- now, we can call modules with string path
if (not workspace) and (not game) and (not script) then if (not workspace) and (not game) and (not script) then
return; return
end end
return function (query) return function (query)
local typeQuery = type(query); local typeQuery = type(query)
if typeQuery == "string" then if typeQuery == "string" then
local object = script.Parent; local object = script.Parent
query = query:gsub("/","."); query = query:gsub("/",".")
-- local index = 0; -- local index = 0
query:gsub("[^%.]+",function (this) query:gsub("[^%.]+",function (this)
-- index = index + 1; -- index = index + 1
-- if index == 1 and this == "src" then -- if index == 1 and this == "src" then
-- return; -- return
-- end -- end
local lastObject = object; local lastObject = object
object = object[this]; object = object[this]
if not object then if not object then
object = lastObject.libs object = lastObject.libs
error(("[Quad] (require) object %s was not found from this worktree, require failed"):format(query)); error(("[Quad] (require) object %s was not found from this worktree, require failed"):format(query))
end end
end); end)
return require(object); return require(object)
elseif typeQuery == "userdata" then elseif typeQuery == "userdata" then
return require(query); return require(query)
end
end end
end;

View file

@ -14,7 +14,7 @@ end
local customSignal = {} local customSignal = {}
customSignal.__index = customSignal customSignal.__index = customSignal
function customSignal:emit(...) function customSignal:Fire(...)
local waitting = self.waitting local waitting = self.waitting
self.waitting = {} self.waitting = {}
@ -54,3 +54,41 @@ function this.new(...)
customSignal.new(...) customSignal.new(...)
end end
this.customSignal = customSignal this.customSignal = customSignal
-- roblox connections disconnecter
local insert = table.insert
local idSpace = {}
local disconnecterClass = {__type = "quad_disconnecter"}
function disconnecterClass:Add(connection)
insert(self,connection)
end
function disconnecterClass:Disconnect()
for i,v in pairs(self) do
pcall(v.Disconnect,v)
self[i] = nil
end
end
function disconnecterClass:Destroy()
local id = self.id
if id then
idSpace[id] = nil
end
for i,v in pairs(self) do
pcall(v.Disconnect,v)
self[i] = nil
end
end
function disconnecterClass.New(id)
if id then
local old = idSpace[id];
if old then
return old;
end
end
local this = setmetatable({id = id},disconnecterClass);
if id then
idSpace[id] = this;
end
return this;
end
disconnecterClass.__index = disconnecterClass

View file

@ -1,97 +1,97 @@
local module = {}; local module = {}
--[[ --[[
this feature allows get object without making some created callback and local var this feature allows get object without making some created callback and local var
but, it can't allows mulit id and object but, it can't allows mulit id and object
this feature should be upgraded this feature should be upgraded
]] ]]
local wrap = coroutine.wrap; local wrap = coroutine.wrap
local insert = table.insert; local insert = table.insert
local remove = table.remove; local remove = table.remove
local gmatch = string.gmatch; local gmatch = string.gmatch
local gsub = string.gsub; local gsub = string.gsub
local match = string.match; local match = string.match
local function catch(...) local function catch(...)
local passed,err = pcall(...); local passed,err = pcall(...)
if not passed then if not passed then
warn ("[QUAD] Error occured while operating async task\n" .. tostring(err)); warn ("[QUAD] Error occured while operating async task\n" .. tostring(err))
end end
end end
local week = {__mode = "v"}; local week = {__mode = "v"}
---@param shared quad_export ---@param shared quad_export
---@return quad_module_store ---@return quad_module_store
function module.init(shared) function module.init(shared)
local warn = shared.warn; local warn = shared.warn
---@class quad_module_store ---@class quad_module_store
local new = {__type = "quad_module_store"}; local new = {__type = "quad_module_store"}
local items = {}; local items = {}
new.items = items new.items = items
-- id space (array of object) -- id space (array of object)
local objectListClass = {__type = "quad_objectlist"}; local objectListClass = {__type = "quad_objectlist"}
function objectListClass:each(func) function objectListClass:each(func)
local index = 1; local index = 1
for i,v in pairs(self) do for i,v in pairs(self) do
wrap(catch)(func,index,v); wrap(catch)(func,index,v)
index = index + 1; index = index + 1
end end
end end
function objectListClass:eachSync(func) function objectListClass:eachSync(func)
local index = 1; local index = 1
for _,v in pairs(self) do for _,v in pairs(self) do
local ret = func(index,v); local ret = func(index,v)
index = index + 1; index = index + 1
if ret then if ret then
break; break
end end
end end
end end
function objectListClass:remove(indexOrItem) function objectListClass:remove(indexOrItem)
local thisType = type(indexOrItem); local thisType = type(indexOrItem)
if thisType == "number" then if thisType == "number" then
return remove(self,indexOrItem),indexOrItem; return remove(self,indexOrItem),indexOrItem
else else
for i,v in pairs(self) do for i,v in pairs(self) do
if v == indexOrItem then if v == indexOrItem then
return remove(self,i),i; return remove(self,i),i
end end
end end
end end
end end
function objectListClass:isEmpty() function objectListClass:isEmpty()
if next(self) then return true; end if next(self) then return true end
return false; return false
end end
function objectListClass.__new() function objectListClass.__new()
return setmetatable({},objectListClass); return setmetatable({},objectListClass)
end end
function objectListClass:__newIndex(key,value) -- props setter function objectListClass:__newIndex(key,value) -- props setter
self:each(function (this) self:each(function (this)
this[key] = value; this[key] = value
end); end)
end end
objectListClass.__mode = "kv"; -- week link for gc objectListClass.__mode = "kv" -- week link for gc
objectListClass.__index = objectListClass; objectListClass.__index = objectListClass
-- get object array with id (objSpace) -- get object array with id (objSpace)
function new.getObjects(ids) function new.getObjects(ids)
if match(ids,",") then if match(ids,",") then
local list = items[ids]; local list = items[ids]
if list then return list; end if list then return list end
list = objectListClass.__new(); list = objectListClass.__new()
items[ids] = list; items[ids] = list
return list; return list
else else
local list = objectListClass.__new(); local list = objectListClass.__new()
for id in gmatch(ids,"[^,]+") do -- split by , for id in gmatch(ids,"[^,]+") do -- split by ,
id = gsub(gsub(id,"^ +","")," +$",""); id = gsub(gsub(id,"^ +","")," +$","")
local idItem = items[id]; local idItem = items[id]
if idItem then if idItem then
for _,item in pairs(idItem) do for _,item in pairs(idItem) do
insert(list,item); insert(list,item)
end end
end end
end end
@ -100,227 +100,227 @@ function module.init(shared)
end end
-- get first object with id (not array) -- get first object with id (not array)
function new.getObject(id) function new.getObject(id)
local item = items[id]; local item = items[id]
return item and item[next(item)]; return item and item[next(item)]
end end
--TODO: if item is exist already, ignore this call --TODO: if item is exist already, ignore this call
-- adding object with id -- adding object with id
function new.addObject(ids,object) function new.addObject(ids,object)
for id in gmatch(ids,"[^,]+") do -- split by , for id in gmatch(ids,"[^,]+") do -- split by ,
-- remove trailing, heading spaces -- remove trailing, heading spaces
id = gsub(gsub(id,"^ +","")," +$",""); id = gsub(gsub(id,"^ +","")," +$","")
local array = items[id]; local array = items[id]
if not array then if not array then
array = objectListClass.__new(); array = objectListClass.__new()
items[id] = array; items[id] = array
end end
insert(array, object); insert(array, object)
end end
end end
local registerClass = { local registerClass = {
__type = "quad_register"; __type = "quad_register";
register = function (s,efunc) register = function (s,efunc)
local self = s.store; local self = s.store
local events = self.__evt; local events = self.__evt
for key in s.key:gmatch("[^,]+") do for key in s.key:gmatch("[^,]+") do
key = key:gsub("^ +",""):gsub(" +$",""); key = key:gsub("^ +",""):gsub(" +$","")
local event = events[key]; local event = events[key]
if not event then if not event then
event = setmetatable({},week); event = setmetatable({},week)
events[key] = event; events[key] = event
end end
insert(event,efunc); insert(event,efunc)
end end
end; end;
with = function (s,wfunc) with = function (s,wfunc)
-- s.wfunc = wfunc; -- s.wfunc = wfunc
-- return s; -- return s
return setmetatable({wfunc = wfunc},{__index = s}); return setmetatable({wfunc = wfunc},{__index = s})
end; end;
default = function (s,dvalue) default = function (s,dvalue)
-- s.dvalue = dvalue; -- s.dvalue = dvalue
-- return s; -- return s
return setmetatable({dvalue = dvalue},{__index = s}); return setmetatable({dvalue = dvalue},{__index = s})
end; end;
tween = function (s,tvalue) tween = function (s,tvalue)
-- s.tvalue = tvalue; -- s.tvalue = tvalue
-- return s; -- return s
return setmetatable({tvalue = tvalue},{__index = s}); return setmetatable({tvalue = tvalue},{__index = s})
end; end;
---@deprecated ---@deprecated
from = function (s,fvalue) from = function (s,fvalue)
warn "[QUAD] register:from() is deprecated. Use register:add(t:table|function) instead"; warn "[QUAD] register:from() is deprecated. Use register:add(t:table|function) instead"
-- s.fvalue = fvalue; -- s.fvalue = fvalue
-- return s; -- return s
return setmetatable({fvalue = fvalue},{__index = s}); return setmetatable({fvalue = fvalue},{__index = s})
end; end;
add = function (s,avalue) add = function (s,avalue)
-- s.avalue = avalue; -- s.avalue = avalue
-- return s; -- return s
return setmetatable({avalue = avalue},{__index = s}); return setmetatable({avalue = avalue},{__index = s})
end; end;
-- return init data -- return init data
calcWithDefault = function (s,withItem) calcWithDefault = function (s,withItem)
local with = s.wfunc; local with = s.wfunc
local tstore = s.store; local tstore = s.store
local rawKey = s.key; local rawKey = s.key
local tween = s.tvalue or tstore.__tweens[rawKey]; local tween = s.tvalue or tstore.__tweens[rawKey]
local from = s.fvalue; local from = s.fvalue
local add = s.avalue; local add = s.avalue
local set = tstore[rawKey]; local set = tstore[rawKey]
if set ~= nil or (rawKey:match(",") and with) then if set ~= nil or (rawKey:match(",") and with) then
if add then if add then
set = set + add; set = set + add
end end
if from then if from then
set = from[set]; set = from[set]
end end
if with then if with then
set = with(tstore,set,rawKey,withItem); set = with(tstore,set,rawKey,withItem)
end end
return set,tween; return set,tween
else else
local dset = s.dvalue; local dset = s.dvalue
if dset ~= nil then if dset ~= nil then
return dset,tween; return dset,tween
end end
warn "[Quad] no default value found."; warn "[Quad] no default value found."
end end
end; end;
calcWithNewValue = function(s,withItem,newValue,key) calcWithNewValue = function(s,withItem,newValue,key)
local with = s.wfunc; local with = s.wfunc
local tstore = s.store; local tstore = s.store
local rawKey = s.key; local rawKey = s.key
local tween = s.tvalue or tstore.__tweens[rawKey]; local tween = s.tvalue or tstore.__tweens[rawKey]
local from = s.fvalue; local from = s.fvalue
local add = s.avalue; local add = s.avalue
if add then if add then
newValue = newValue + add; newValue = newValue + add
end end
if from then if from then
newValue = from[newValue]; newValue = from[newValue]
end end
if with then if with then
newValue = with(tstore,newValue,key,withItem); newValue = with(tstore,newValue,key,withItem)
end end
return newValue,tween; return newValue,tween
end end
}; }
registerClass.__index = registerClass; registerClass.__index = registerClass
-- bindable store object -- bindable store object
local store = {__type = "quad_store"}; local store = {__type = "quad_store"}
local storeIdSpace = {}; local storeIdSpace = {}
function store:__index(key) function store:__index(key)
local this = self.__self[key]; local this = self.__self[key]
if this ~= nil then if this ~= nil then
return this; return this
end end
return store[key]; return store[key]
end end
function store:__newindex(key,value) function store:__newindex(key,value)
-- if got register, just copy data to self and connect -- if got register, just copy data to self and connect
if type(value) == "table" and value.__type == "quad_register" then 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"; -- warn "[Quad] adding register value on store is only allowed when init store. set value request was ignored"
local selfValues = self.__self; local selfValues = self.__self
local selfTweens = self.__tweens; local selfTweens = self.__tweens
-- fetch data from origin -- fetch data from origin
do do
local tstore = value.store; local tstore = value.store
for tkey in value.key:gmatch("^[,]") do for tkey in value.key:gmatch("^[,]") do
if not selfValues[tkey] then if not selfValues[tkey] then
selfValues[tkey] = tstore[tkey]; selfValues[tkey] = tstore[tkey]
end end
end end
end end
-- calc value -- calc value
do do
local setValue,tween = value:calcWithDefault(self); local setValue,tween = value:calcWithDefault(self)
selfValues[key] = setValue; selfValues[key] = setValue
selfTweens[key] = tween; selfTweens[key] = tween
end end
-- make event connection -- make event connection
value:register(function (_,newValue,eventKey) value:register(function (_,newValue,eventKey)
-- !HOLD IT SELF TO PREVENT THIS REGISTER BEGIN REMOVED FROM MEMORY -- !HOLD IT SELF TO PREVENT THIS REGISTER BEGIN REMOVED FROM MEMORY
local setValue = value:calcWithNewValue(self,newValue,eventKey); local setValue = value:calcWithNewValue(self,newValue,eventKey)
self[key] = setValue; self[key] = setValue
end); end)
return; return
end end
self.__self[key] = value; self.__self[key] = value
local event = self.__evt[key]; local event = self.__evt[key]
if event then if event then
for _,v in pairs(event) do -- NO ipairs here for _,v in pairs(event) do -- NO ipairs here
wrap(catch)(v,store,value,key); wrap(catch)(v,store,value,key)
end end
end end
end end
-- init bindings -- init bindings
function new.__initStoreRegisterBinding(self,withItem) function new.__initStoreRegisterBinding(self,withItem)
local selfTweens = self.__tweens; local selfTweens = self.__tweens
local selfValues = self.__self; local selfValues = self.__self
local selfKeep = self.__keep; local selfKeep = self.__keep
for key,item in pairs(selfValues) do for key,item in pairs(selfValues) do
if type(item) == "table" and item.__type == "quad_register" then if type(item) == "table" and item.__type == "quad_register" then
-- fetch data from origin -- fetch data from origin
do do
local tstore = item.store; local tstore = item.store
for tkey in item.key:gmatch("^[,]") do for tkey in item.key:gmatch("^[,]") do
if not selfValues[tkey] then if not selfValues[tkey] then
selfValues[tkey] = tstore[tkey]; selfValues[tkey] = tstore[tkey]
end end
end end
end end
-- calc value -- calc value
do do
local setValue,tween = item:calcWithDefault(withItem); local setValue,tween = item:calcWithDefault(withItem)
selfValues[key] = setValue; selfValues[key] = setValue
selfTweens[key] = tween; selfTweens[key] = tween
end end
-- make event connection -- make event connection
local function regFn(_,newValue,eventKey) local function regFn(_,newValue,eventKey)
-- !HOLD IT SELF TO PREVENT THIS REGISTER BEGIN REMOVED FROM MEMORY -- !HOLD IT SELF TO PREVENT THIS REGISTER BEGIN REMOVED FROM MEMORY
local setValue = item:calcWithNewValue(withItem,newValue,eventKey); local setValue = item:calcWithNewValue(withItem,newValue,eventKey)
self[key] = setValue; self[key] = setValue
end end
item:register(regFn); item:register(regFn)
insert(selfKeep,item); insert(selfKeep,item)
insert(selfKeep,regFn); insert(selfKeep,regFn)
end end
end end
end end
-- create register -- create register
function store:__call(key,func) function store:__call(key,func)
local last = self.__self[key]; local last = self.__self[key]
if last and type(last) == "table" and getmetatable(last) == registerClass then if last and type(last) == "table" and getmetatable(last) == registerClass then
return last; return last
end end
local register = self.__reg[key]; local register = self.__reg[key]
if not register then if not register then
register = setmetatable({ register = setmetatable({
key = key; key = key;
store = self; store = self;
},registerClass); },registerClass)
self.__reg[key] = register; self.__reg[key] = register
end end
if func then if func then
register.register(func); register.register(func)
end end
return register; return register
end end
function store:default(key,value) function store:default(key,value)
if self[key] == nil then if self[key] == nil then
self[key] = value; self[key] = value
return; return
end end
end end
function new.new(self,id) function new.new(self,id)
@ -332,18 +332,18 @@ function module.init(shared)
__tweens = {}, -- tweens (if inited with register, save tween and use as default tween data) __tweens = {}, -- tweens (if inited with register, save tween and use as default tween data)
__keep = {} -- store data which should not be destoryed __keep = {} -- store data which should not be destoryed
},store },store
); )
if id then -- save in id space if id then -- save in id space
storeIdSpace[id] = this; storeIdSpace[id] = this
end end
return this; return this
end end
local storeNew = new.new; local storeNew = new.new
function new.getStore(id) function new.getStore(id)
return storeIdSpace[id] or storeNew({},id); return storeIdSpace[id] or storeNew({},id)
end end
return new; return new
end end
return module; return module