Fix indents, method names
This commit is contained in:
parent
83bb7ee817
commit
46da90f5f8
9 changed files with 553 additions and 531 deletions
431
src/class.lua
431
src/class.lua
|
|
@ -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
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check class name
|
||||||
|
ClassName = ClassName or item.ClassName
|
||||||
|
-- check is ImageLabel or ImageButton
|
||||||
|
local isImage = (ClassName == "ImageLabel" or ClassName == "ImageButton")
|
||||||
|
|
||||||
|
-- Round Image
|
||||||
|
if index == "RoundSize" and isImage then
|
||||||
if not round then
|
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");
|
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);
|
round.SetRound(item,value)
|
||||||
elseif index == "UIRoundSize" or index == "uiRoundSize" or index == "UiRoundSize" then
|
-- UIRound
|
||||||
local uiCorner = (ClassName == "UICorner" and item) or item:FindFirstChildOfClass("UICorner") or InstanceNewWithName("UICorner",item,"_quad_round");
|
elseif index == "Corner" then
|
||||||
uiCorner.CornerRadius = UDim.new(0,value);
|
local uiCorner = (ClassName == "UICorner" and item) or item:FindFirstChildOfClass("UICorner") or InstanceNewWithName("UICorner",item,"_quad_round")
|
||||||
elseif index == "PaddingAll" or index == "paddingAll" then
|
uiCorner.CornerRadius = UDim.new(0,value)
|
||||||
local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding") or InstanceNewWithName("UIPadding",item,"_quad_padding");
|
-- PaddingAll
|
||||||
target.PaddingLeft = value;
|
elseif index == "PaddingAll" then
|
||||||
target.PaddingRight = value;
|
local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding") or InstanceNewWithName("UIPadding",item,"_quad_padding")
|
||||||
target.PaddingTop = value;
|
target.PaddingLeft = value
|
||||||
target.PaddingBottom = value;
|
target.PaddingRight = value
|
||||||
elseif index == "PaddingAllOffset" or index == "paddingAllOffset" then
|
target.PaddingTop = value
|
||||||
local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding") or InstanceNewWithName("UIPadding",item,"_quad_padding");
|
target.PaddingBottom = value
|
||||||
local padding = UDim.new(0,value);
|
-- PaddingAll with Offset
|
||||||
target.PaddingLeft = padding;
|
elseif index == "PaddingAllOffset" then
|
||||||
target.PaddingRight = padding;
|
local target = (ClassName == "UIPadding" and item) or item:FindFirstChildOfClass("UIPadding") or InstanceNewWithName("UIPadding",item,"_quad_padding")
|
||||||
target.PaddingTop = padding;
|
local padding = UDim.new(0,value)
|
||||||
target.PaddingBottom = padding;
|
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
|
||||||
|
|
|
||||||
120
src/event.lua
120
src/event.lua
|
|
@ -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
|
|
||||||
|
|
||||||
return new;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return module;
|
return module
|
||||||
26
src/init.lua
26
src/init.lua
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -8,28 +8,28 @@ local IsRoblox = version and version() or nil
|
||||||
|
|
||||||
local module = {}
|
local module = {}
|
||||||
function module.BindStep(StepFunction)
|
function module.BindStep(StepFunction)
|
||||||
if IsRoblox then
|
if IsRoblox then
|
||||||
if module.Connection then
|
if module.Connection then
|
||||||
error("Function was binded already")
|
error("Function was binded already")
|
||||||
end
|
end
|
||||||
local RunService = game:GetService("RunService")
|
local RunService = game:GetService("RunService")
|
||||||
if RunService:IsStudio() and (not RunService:IsRunning()) and RunService:IsEdit() then
|
if RunService:IsStudio() and (not RunService:IsRunning()) and RunService:IsEdit() then
|
||||||
module.Connection = RunService.Heartbeat:Connect(StepFunction)
|
module.Connection = RunService.Heartbeat:Connect(StepFunction)
|
||||||
else
|
else
|
||||||
-- RunService:BindToRenderStep("advancedTween",1,StepFunction)
|
-- RunService:BindToRenderStep("advancedTween",1,StepFunction)
|
||||||
module.Connection = RunService.RenderStepped:Connect(StepFunction)
|
module.Connection = RunService.RenderStepped:Connect(StepFunction)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- do something here
|
-- do something here
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function module.UnbindAll()
|
function module.UnbindAll()
|
||||||
if not module.Connection then
|
if not module.Connection then
|
||||||
error("Function was not binded yet")
|
error("Function was not binded yet")
|
||||||
end
|
end
|
||||||
module.Connection:Disconnect()
|
module.Connection:Disconnect()
|
||||||
module.Connection = nil
|
module.Connection = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
return module
|
return module
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,9 @@ module.EasingFunction = module.EasingFunctions
|
||||||
------------------------------------
|
------------------------------------
|
||||||
-- 이중 선형, Alpha 를 받아서 값을 구해옴
|
-- 이중 선형, Alpha 를 받아서 값을 구해옴
|
||||||
local function Lerp(start,goal,alpha)
|
local function Lerp(start,goal,alpha)
|
||||||
if alpha == 1 then return goal end
|
if alpha == 1 then return goal end
|
||||||
if alpha == 0 then return start end
|
if alpha == 0 then return start end
|
||||||
return start + ((goal - start) * alpha)
|
return start + ((goal - start) * alpha)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 기본적으로 로블록스가 Lerp 를 지원하는 Class
|
-- 기본적으로 로블록스가 Lerp 를 지원하는 Class
|
||||||
|
|
|
||||||
103
src/mount.lua
103
src/mount.lua
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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 = {}
|
||||||
|
|
||||||
|
|
@ -38,7 +38,7 @@ function customSignal:Connect(func)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
insert(self.connection,func)
|
insert(self.connection,func)
|
||||||
return customConnection.new(self,func)
|
return customConnection.new(self,func)
|
||||||
end
|
end
|
||||||
local function onceWaitter(targetFunction)
|
local function onceWaitter(targetFunction)
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
290
src/store.lua
290
src/store.lua
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue