feat: new Style system, add optimization by preventing same property setted multiply
This commit is contained in:
parent
18538f0bbe
commit
3515baaa3a
6 changed files with 193 additions and 82 deletions
191
src/class.lua
191
src/class.lua
|
|
@ -1,6 +1,9 @@
|
|||
local module = {};
|
||||
local pack = table.pack;
|
||||
local match = string.match;
|
||||
|
||||
---@param shared quad_export
|
||||
---@return quad_module_class
|
||||
function module.init(shared)
|
||||
---@class quad_module_class
|
||||
local new = {__type = "quad_module_class"};
|
||||
|
|
@ -13,6 +16,9 @@ function module.init(shared)
|
|||
local mount = shared.mount; ---@type quad_module_mount
|
||||
local getHolder = mount.getHolder;
|
||||
local mountfunc = mount.mount;
|
||||
local style = shared.style; ---@type quad_module_style
|
||||
local styleList = style.styles;
|
||||
local parseStyles = style.parseStyles;
|
||||
local advancedTween = shared.tween; ---@type quad_module_tween
|
||||
local round = shared.round; ---@type quad_module_round
|
||||
|
||||
|
|
@ -84,9 +90,102 @@ function module.init(shared)
|
|||
end
|
||||
end
|
||||
|
||||
local function processQuadProperty(processedProperty,iprop,holder,item,className,index,value)
|
||||
if processedProperty[index] then return; end
|
||||
|
||||
local valueType = typeof(value);
|
||||
local indexType = typeof(index);
|
||||
|
||||
-- child
|
||||
if indexType == "string" and valueType == "table" and value.t == "reg" then -- register (bind to store event)
|
||||
processedProperty[index] = true; -- ignore next
|
||||
-- store binding
|
||||
local with = value.wfunc;
|
||||
local tstore = value.store;
|
||||
local rawKey = value.key;
|
||||
local tween = value.tvalue;
|
||||
local from = value.fvalue;
|
||||
local add = value.avalue;
|
||||
local set = tstore[rawKey];
|
||||
if set ~= nil or (rawKey:match(",") and with) then
|
||||
if add then
|
||||
set = set + add;
|
||||
end
|
||||
if from then
|
||||
set = from[set];
|
||||
end
|
||||
if with then
|
||||
set = with(tstore,set,value.key,item);
|
||||
end
|
||||
setProperty(item,index,set,className);
|
||||
else
|
||||
local dset = value.dvalue;
|
||||
if dset then
|
||||
setProperty(item,index,dset,className);
|
||||
end
|
||||
end
|
||||
|
||||
-- adding event function
|
||||
local function regFn(_,newValue,key)
|
||||
if add then
|
||||
newValue = newValue + add;
|
||||
end
|
||||
if from then
|
||||
newValue = from[newValue];
|
||||
end
|
||||
if with then
|
||||
newValue = with(tstore,newValue,key,item);
|
||||
end
|
||||
if tween then
|
||||
if not advancedTween then
|
||||
return warn "[QUAD] module 'AdvancedTween' needs to be loaded for tween properties but it is not found on 'src.libs'. you should adding that to src.libs directory";
|
||||
end
|
||||
local ended, onStepped;
|
||||
if tween.Ended then
|
||||
ended = function (...)
|
||||
tween.Ended(item,...);
|
||||
end
|
||||
end
|
||||
if tween.OnStepped then
|
||||
onStepped = function (...)
|
||||
tween.OnStepped(item,...);
|
||||
end
|
||||
end
|
||||
advancedTween.RunTween(item,tween,{[index] = newValue},ended,onStepped,setProperty,getProperty);
|
||||
else
|
||||
setProperty(item,index,newValue,className);
|
||||
end
|
||||
end
|
||||
value:register(regFn);
|
||||
|
||||
-- this is using hacky of roblox instance
|
||||
-- this is will keep reference from week table until
|
||||
-- inscance got GCed
|
||||
item:GetPropertyChangedSignal("ClassName"):Connect(regFn);
|
||||
elseif (valueType == "function" or valueType == "table") and indexType == "string" and bind(item,index,value,valueType) then -- connect event
|
||||
-- event binding
|
||||
elseif indexType == "string" then
|
||||
processedProperty[index] = true; -- ignore next
|
||||
-- prop set
|
||||
setProperty(item,index,value,className);
|
||||
elseif indexType == "number" and valueType == "table" and value.__type == "quad_style" then -- style
|
||||
-- style parsing
|
||||
for _,thisStyle in ipairs(parseStyles(value)) do
|
||||
for styleIndex,styleValue in pairs(thisStyle) do
|
||||
if type(styleValue) ~= "table" or styleValue.__type ~= "quad_style" then
|
||||
processQuadProperty(processedProperty,iprop,holder,item,className,styleIndex,styleValue);
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif indexType == "number" and valueType ~= "boolean" then -- object
|
||||
-- child object
|
||||
mountfunc(item,((iprop == 1) and value or value:Clone()),holder);
|
||||
end
|
||||
end
|
||||
|
||||
-- make object that from instance, class and more
|
||||
function new.make(ClassName,...) -- render object
|
||||
-- make thing
|
||||
-- make object from ClassName
|
||||
local item;
|
||||
local classOfClassName = type(ClassName);
|
||||
if classOfClassName == "string" then -- if classname is a string value, cdall instance.new for making new roblox instance
|
||||
|
|
@ -131,88 +230,13 @@ function module.init(shared)
|
|||
-- set property and adding child and binding functions
|
||||
local holder = getHolder(item); -- to __holder or holder or it self (for tabled)
|
||||
-- for iprop,prop in ipairs({...}) do
|
||||
local props = pack(...);
|
||||
for iprop = props.n,1,-1 do
|
||||
local prop = props[iprop];
|
||||
local propsListArray = pack(...);
|
||||
local processedProperty = {};
|
||||
for iprop = 1,propsListArray.n do
|
||||
local prop = propsListArray[iprop]
|
||||
if prop then
|
||||
for index,value in pairs(prop) do
|
||||
local valueType = typeof(value);
|
||||
local indexType = typeof(index);
|
||||
|
||||
-- child
|
||||
if indexType == "string" and valueType == "table" and value.t == "reg" then -- register (bind to store event)
|
||||
-- store binding
|
||||
local with = value.wfunc;
|
||||
local tstore = value.store;
|
||||
local rawKey = value.key;
|
||||
local tween = value.tvalue;
|
||||
local from = value.fvalue;
|
||||
local add = value.avalue;
|
||||
local set = tstore[rawKey];
|
||||
if set ~= nil or (rawKey:match(",") and with) then
|
||||
if add then
|
||||
set = set + add;
|
||||
end
|
||||
if from then
|
||||
set = from[set];
|
||||
end
|
||||
if with then
|
||||
set = with(tstore,set,value.key,item);
|
||||
end
|
||||
setProperty(item,index,set,ClassName);
|
||||
else
|
||||
local dset = value.dvalue;
|
||||
if dset then
|
||||
setProperty(item,index,dset,ClassName);
|
||||
end
|
||||
end
|
||||
|
||||
-- adding event function
|
||||
local function regFn(_,newValue,key)
|
||||
if add then
|
||||
newValue = newValue + add;
|
||||
end
|
||||
if from then
|
||||
newValue = from[newValue];
|
||||
end
|
||||
if with then
|
||||
newValue = with(tstore,newValue,key,item);
|
||||
end
|
||||
if tween then
|
||||
if not advancedTween then
|
||||
return warn "[QUAD] module 'AdvancedTween' needs to be loaded for tween properties but it is not found on 'src.libs'. you should adding that to src.libs directory";
|
||||
end
|
||||
local ended, onStepped;
|
||||
if tween.Ended then
|
||||
ended = function (...)
|
||||
tween.Ended(item,...);
|
||||
end
|
||||
end
|
||||
if tween.OnStepped then
|
||||
onStepped = function (...)
|
||||
tween.OnStepped(item,...);
|
||||
end
|
||||
end
|
||||
advancedTween.RunTween(item,tween,{[index] = newValue},ended,onStepped,setProperty,getProperty);
|
||||
else
|
||||
setProperty(item,index,newValue,ClassName);
|
||||
end
|
||||
end
|
||||
value:register(regFn);
|
||||
|
||||
-- this is using hacky of roblox instance
|
||||
-- this is will keep reference from week table until
|
||||
-- inscance got GCed
|
||||
item:GetPropertyChangedSignal("ClassName"):Connect(regFn);
|
||||
elseif (valueType == "function" or valueType == "table") and indexType == "string" and bind(item,index,value,valueType) then -- connect event
|
||||
-- event binding
|
||||
elseif indexType == "string" then
|
||||
-- prop set
|
||||
setProperty(item,index,value,ClassName);
|
||||
elseif indexType == "number" and valueType ~= "boolean" then -- object
|
||||
-- child object
|
||||
mountfunc(item,((iprop == 1) and value or value:Clone()),holder);
|
||||
end
|
||||
processQuadProperty(processedProperty,iprop,holder,item,ClassName,index,value);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -235,6 +259,11 @@ function module.init(shared)
|
|||
return function (nprop,...)
|
||||
nprop = nprop or {};
|
||||
nprop.Name = lastName;
|
||||
for styleName,styleObj in pairs(styleList) do
|
||||
if match(prop,styleName) then
|
||||
insert(nprop,styleObj);
|
||||
end
|
||||
end
|
||||
local item = make(ClassName,nprop,...,this);
|
||||
addObject(lastName,item);
|
||||
return item;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ local module = {};
|
|||
local unpack = table.unpack;
|
||||
local wrap = coroutine.wrap;
|
||||
|
||||
---@param shared quad_export
|
||||
---@return quad_module_event
|
||||
function module.init(shared)
|
||||
---@class quad_module_event
|
||||
local new = {__type = "quad_module_event"};
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
local module = {};
|
||||
|
||||
local require = require(script.require);
|
||||
local style = require "style";
|
||||
local event = require "event";
|
||||
local store = require "store";
|
||||
local class = require "class";
|
||||
|
|
@ -28,6 +29,7 @@ function module.init(id)
|
|||
this.require = require;
|
||||
this.round = type(round) == "table" and round; ---@type quad_module_round
|
||||
this.tween = type(advancedTween) == "table" and advancedTween; ---@type quad_module_tween
|
||||
this.style = style.init(this); ---@type quad_module_style
|
||||
this.event = event.init(this); ---@type quad_module_event
|
||||
this.store = store.init(this); ---@type quad_module_store
|
||||
this.mount = mount.init(this); ---@type quad_module_mount
|
||||
|
|
@ -36,7 +38,7 @@ function module.init(id)
|
|||
if id then
|
||||
idSpace[id] = this;
|
||||
end
|
||||
return this,this.round,this.class,this.mount,this.store,this.event,this.tween;
|
||||
return this,this.round,this.class,this.mount,this.store,this.event,this.tween,this.style;
|
||||
end
|
||||
|
||||
function module.uninit(id)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ local module = {};
|
|||
local insert = table.insert;
|
||||
local pack = table.pack;
|
||||
|
||||
---@param shared quad_export
|
||||
---@return quad_module_mount
|
||||
function module.init(shared)
|
||||
---@class quad_module_mount
|
||||
local new = {__type = "quad_module_mount"};
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ local function catch(...)
|
|||
end
|
||||
|
||||
local week = {__mode = "v"};
|
||||
|
||||
---@param shared quad_export
|
||||
---@return quad_module_store
|
||||
function module.init(shared)
|
||||
---@class quad_module_store
|
||||
local new = {__type = "quad_module_store"};
|
||||
|
|
|
|||
73
src/style.lua
Normal file
73
src/style.lua
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
local module = {};
|
||||
local insert = table.insert;
|
||||
|
||||
---@param shared quad_export
|
||||
---@return quad_module_style
|
||||
function module.init(shared)
|
||||
---@class quad_module_style
|
||||
local new = {__type = "quad_module_style"};
|
||||
|
||||
local styles = {};
|
||||
new.styles = styles;
|
||||
|
||||
---@class quad_style
|
||||
local styleClass = {__type = "quad_style"};
|
||||
styleClass.__index = styleClass;
|
||||
|
||||
function new.new(props)
|
||||
return setmetatable(props,styleClass);
|
||||
end
|
||||
local newStyle = new.new;
|
||||
|
||||
setmetatable(new,{
|
||||
---@return quad_style
|
||||
__call = function (_,styleTable)
|
||||
if type(styleTable) == "string" then
|
||||
return function (nstyleTable)
|
||||
local this = newStyle(nstyleTable);
|
||||
styles[styleTable] = this;
|
||||
return this;
|
||||
end
|
||||
end
|
||||
return newStyle(styleTable);
|
||||
end
|
||||
});
|
||||
|
||||
local function recursionStyleParse(style,parseTable)
|
||||
for _,value in ipairs(parseTable) do
|
||||
if value == style then
|
||||
warn("[Quad] infinity recursion detected on parsing style. ignored recursion");
|
||||
return;
|
||||
end
|
||||
end
|
||||
insert(parseTable,style);
|
||||
for key,value in pairs(style) do
|
||||
if type(key) == "number" and type(value) == "table" and value.__type == "quad_style" then
|
||||
recursionStyleParse(value,parseTable);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local parsed = {};
|
||||
function new.parseStyles(style)
|
||||
do -- check cache
|
||||
local cached = parsed[style];
|
||||
if cached then return cached; end
|
||||
end
|
||||
|
||||
-- type check
|
||||
if type(style) ~= "table" or style.__type ~= "quad_style" then
|
||||
error(("Unknown type type '%s:%s' got"):format(tostring(style),tostring(type(style))));
|
||||
end
|
||||
|
||||
local this = {}
|
||||
recursionStyleParse(style,this);
|
||||
|
||||
parsed[style] = this;
|
||||
return this;
|
||||
end
|
||||
|
||||
return new;
|
||||
end
|
||||
|
||||
return module;
|
||||
Loading…
Reference in a new issue