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 module = {};
|
||||||
local pack = table.pack;
|
local pack = table.pack;
|
||||||
|
local match = string.match;
|
||||||
|
|
||||||
|
---@param shared quad_export
|
||||||
|
---@return quad_module_class
|
||||||
function module.init(shared)
|
function module.init(shared)
|
||||||
---@class quad_module_class
|
---@class quad_module_class
|
||||||
local new = {__type = "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 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 styleList = style.styles;
|
||||||
|
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
|
||||||
|
|
||||||
|
|
@ -84,9 +90,102 @@ function module.init(shared)
|
||||||
end
|
end
|
||||||
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
|
-- make object that from instance, class and more
|
||||||
function new.make(ClassName,...) -- render object
|
function new.make(ClassName,...) -- render object
|
||||||
-- make thing
|
-- 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
|
||||||
|
|
@ -131,88 +230,13 @@ function module.init(shared)
|
||||||
-- 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 props = pack(...);
|
local propsListArray = pack(...);
|
||||||
for iprop = props.n,1,-1 do
|
local processedProperty = {};
|
||||||
local prop = props[iprop];
|
for iprop = 1,propsListArray.n do
|
||||||
|
local prop = propsListArray[iprop]
|
||||||
if prop then
|
if prop then
|
||||||
for index,value in pairs(prop) do
|
for index,value in pairs(prop) do
|
||||||
local valueType = typeof(value);
|
processQuadProperty(processedProperty,iprop,holder,item,ClassName,index,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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -235,6 +259,11 @@ function module.init(shared)
|
||||||
return function (nprop,...)
|
return function (nprop,...)
|
||||||
nprop = nprop or {};
|
nprop = nprop or {};
|
||||||
nprop.Name = lastName;
|
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);
|
local item = make(ClassName,nprop,...,this);
|
||||||
addObject(lastName,item);
|
addObject(lastName,item);
|
||||||
return item;
|
return item;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ local module = {};
|
||||||
local unpack = table.unpack;
|
local unpack = table.unpack;
|
||||||
local wrap = coroutine.wrap;
|
local wrap = coroutine.wrap;
|
||||||
|
|
||||||
|
---@param shared quad_export
|
||||||
|
---@return quad_module_event
|
||||||
function module.init(shared)
|
function module.init(shared)
|
||||||
---@class quad_module_event
|
---@class quad_module_event
|
||||||
local new = {__type = "quad_module_event"};
|
local new = {__type = "quad_module_event"};
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
local module = {};
|
local module = {};
|
||||||
|
|
||||||
local require = require(script.require);
|
local require = require(script.require);
|
||||||
|
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";
|
||||||
|
|
@ -28,6 +29,7 @@ function module.init(id)
|
||||||
this.require = require;
|
this.require = require;
|
||||||
this.round = type(round) == "table" and round; ---@type quad_module_round
|
this.round = type(round) == "table" and round; ---@type quad_module_round
|
||||||
this.tween = type(advancedTween) == "table" and advancedTween; ---@type quad_module_tween
|
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.event = event.init(this); ---@type quad_module_event
|
||||||
this.store = store.init(this); ---@type quad_module_store
|
this.store = store.init(this); ---@type quad_module_store
|
||||||
this.mount = mount.init(this); ---@type quad_module_mount
|
this.mount = mount.init(this); ---@type quad_module_mount
|
||||||
|
|
@ -36,7 +38,7 @@ function module.init(id)
|
||||||
if id then
|
if id then
|
||||||
idSpace[id] = this;
|
idSpace[id] = this;
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
function module.uninit(id)
|
function module.uninit(id)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ local module = {};
|
||||||
local insert = table.insert;
|
local insert = table.insert;
|
||||||
local pack = table.pack;
|
local pack = table.pack;
|
||||||
|
|
||||||
|
---@param shared quad_export
|
||||||
|
---@return quad_module_mount
|
||||||
function module.init(shared)
|
function module.init(shared)
|
||||||
---@class quad_module_mount
|
---@class quad_module_mount
|
||||||
local new = {__type = "quad_module_mount"};
|
local new = {__type = "quad_module_mount"};
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,9 @@ local function catch(...)
|
||||||
end
|
end
|
||||||
|
|
||||||
local week = {__mode = "v"};
|
local week = {__mode = "v"};
|
||||||
|
|
||||||
|
---@param shared quad_export
|
||||||
|
---@return quad_module_store
|
||||||
function module.init(shared)
|
function module.init(shared)
|
||||||
---@class quad_module_store
|
---@class quad_module_store
|
||||||
local new = {__type = "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