WaAAAAAAAAAAAAAAAAAA

This commit is contained in:
세젤귀 고양이들 2021-12-18 00:24:12 +09:00
parent 76eb260617
commit 846788fd4c
7 changed files with 700 additions and 86 deletions

View file

@ -28,19 +28,19 @@ frame{
]] ]]
require = require(script.require); local require = require(script.require);
local event = require("event"); local event = require("event"); ---@module "src.event"
local store = require("store"); local store = require("store"); ---@module "src.store"
local style = require("style"); --local style = require("style");
local class = require("class"); local class = require("class"); ---@module "src.class"
local mount = require("mount"); local mount = require("mount"); ---@module "src.mount"
function module.init() function module.init()
local this = {items = {}}; local this = {items = {}};
this.event = event.init(this); this.event = event.init(this);
this.store = store.init(this); this.store = store.init(this);
this.style = style.init(this); --this.style = style.init(this);
this.class = class.init(this); this.class = class.init(this);
this.mount = mount.init(this); this.mount = mount.init(this);
@ -55,22 +55,34 @@ return module;
]]></string> ]]></string>
</Properties> </Properties>
<Item class="ModuleScript" referent="1"> <Item class="ModuleScript" referent="1">
<Properties>
<string name="Name">bind</string>
<string name="Source"></string>
</Properties>
</Item>
<Item class="ModuleScript" referent="2">
<Properties> <Properties>
<string name="Name">class</string> <string name="Name">class</string>
<string name="Source">local module = {}; <string name="Source">local module = {};
-- local exportItemMeta = {
-- __index = function (self,key)
-- local methods = self.__methods;
-- local events = self.__events;
-- return (methods and methods[key]) or (events and events[key]) or (self.getters[key](self.__this));
-- end;
-- __newindex = function (self,key,value)
-- self.__setters[key](self.__this,value);
-- end;
-- };
function module.init(shared) function module.init(shared)
local new = {}; local new = {};
local bind = shared.event.bind; local bind = shared.event.bind;
local addObject = shared.store.addObject; local addObject = shared.store.addObject;
local storeNew = shared.store.new;
function new.make(ClassName,prop) function new.getHolder(item)
return (type(item) == "table") and (item._holder or item.holder or item.__holder) or item;
end
local getHolder = new.getHolder;
-- make object that from instance, class and more
function new.make(ClassName,...) -- render object
-- make thing -- make thing
local item; local item;
local classOfClassName = type(ClassName); local classOfClassName = type(ClassName);
@ -80,6 +92,32 @@ function module.init(shared)
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
local childs,props = {},{...};
local parsed;
for iprop = #props,1,-1 do
local prop = props[iprop];
for i,v in ipairs(prop) do
childs[i] = ((iprop == 1) and v or v:Clone());
prop[i] = nil;
end
if next(prop) then -- there are (key/value)s
if parsed then
for i,v in pairs(prop) do
parsed[i] = v;
end
else
parsed = prop;
end
end
end
item = func(parsed);
local holder = getHolder(item);
for _,v in ipairs(childs) do
v.Parent = holder;
end
return item;
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
@ -88,24 +126,54 @@ function module.init(shared)
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)
-- for iprop,prop in ipairs({...}) do
for iprop = select("#",...),1,-1 do
local prop = select(iprop,...);
for index,value in pairs(prop) do for index,value in pairs(prop) do
local valueType = typeof(value); local valueType = typeof(value);
local indexType = typeof(index); local indexType = typeof(index);
-- child -- child
if indexType ~= "string" then -- object if indexType == "string" and valueType == "table" and value.t == "reg" then -- register (bind to store event)
value.Parent = new; -- store binding
elseif valueType == "function" and bind(value) then -- connect event local with = value.wfunc;
local set = value.store[value.key];
if set then
if with then
set = with(set);
end
item[index] = set;
else
local dset = value.dvalue;
if dset then
item[index] = dset;
end
end
value.register(function (newValue,store)
if with then
newValue = with(newValue,item,store);
end
item[index] = newValue;
end);
elseif (valueType == "function" or valueType == "table") and bind(item,index,value,valueType) then -- connect event
-- event binding
elseif indexType == "string" then elseif indexType == "string" then
new[index] = value; -- set property -- prop set
item[index] = value; -- set property
elseif indexType == "number" then -- object
-- child object
((iprop == 1) and value or value:Clone()).Parent = holder;
end
end end
end end
return item; return item;
end end
local make = new.make; local make = new.make;
function new.import(ClassName) -- make new quad class object -- import quad object
local this = {styles = {}}; function new.import(ClassName,defaultProperties) -- make new quad class object
local this = defaultProperties or {};
setmetatable(this,{ setmetatable(this,{
__call = function (self,prop) __call = function (self,prop)
if type(prop) == "string" then if type(prop) == "string" then
@ -117,26 +185,159 @@ function module.init(shared)
return item; return item;
end; end;
end end
return make(ClassName,prop); return make(ClassName,prop,this);
end; end;
}); });
return this; return this;
end end
-- function new.export(newFn,setters,getters,methods,events) -- make quad importable class
-- return function ()
-- return setmetatable({
-- __this = newFn();
-- __setters = setters;
-- __getters = getters;
-- __methods = methods;
-- __events = events;
-- },exportItemMeta);
-- end;
-- end
-- set module calling function -- set module calling function
setmetatable(new,{ setmetatable(new,{
__call = function (self,...) __call = function (self,...)
return self.import(...); return new.import(...);
end; end;
}); });
-- make class
function new.extend()
local this = {};
--- make new object
function this.new(prop)
-- make metatable
prop = storeNew(prop);
local parent = prop and (prop.Parent or prop.parent);
local self = {__prop = prop; __parent = parent};
local init = this.init;
if init then
init(self,prop);
end
setmetatable(self,this);
-- render that
local object = self:render(prop);
rawset(self,"__object",object);
rawset(self,"__holder",object);
if parent then
rawset(self,"__parent",parent);
object.Parent = getHolder(parent);
end
return self;
end
--- re-render object (if some props chaged, call this to render again)
function this:update() -- swap object
local object = rawget(self,"__object"); -- get last instance
local parent = rawget(self,"__parent") or (object and object.Parent); -- date parent
local lastObject = object;
if lastObject then
lastObject.Parent = nil;
end
object = self:render(self.__prop); -- new instance
rawset(self,"__holder",object);
rawset(self,"__object",object);
object.Parent = getHolder(parent); -- update parent
if lastObject then -- remove old instance
self:Destroy(lastObject);
end
end
-- define destroy method
function this:Destroy(object)
local unload = rawget(self,"unload");
object = object or rawget(self,"__object");
if object then
if unload then
unload(self,object);
else
local destroy = (object.Destroy or object.destroy);
if destroy then
pcall(destroy,object);
end
end
end
end
--- link to new
function this.__call(self,...)
return (self.new or self.New or self.__new)(...);
end;
-- indexer (getter)
function this:__index(k)
if k == "destroy" then
return self.Destroy;
end
local getter = this.getter[k];
if getter then
return getter(self,rawget(self,"__object"));
end
-- from this (have more priority)
local fromThis = this[k];
if fromThis then
return fromThis;
end
-- from prop, not start with '_' (private value)
if k:sub(1,1) ~= "_" then
return self.__prop[k];
end
end
--- new indexer (setter)
function this:__newindex(k,v)
-- from setter
local setter = this.setter[k];
if setter then
return setter(self,v,rawget(self,"__object"));
end
-- is private (self value)
if k == "holder" or k:sub(1,1) == "_" then
return rawset(self,k,v);
end
-- prop update
self.__prop[k] = v;
if this.updateTriggers[k] then
self:update();
end
end
this.getter = {};
this.setter = {
Parent = function(self,parent,object)
rawset(self,"__parent",parent);
if object then
object.Parent = getHolder(parent);
end
end;
};
this.updateTriggers = {};
this.__noSetup = true;
return this;
end
return new; return new;
end end
return module;</string> return module;</string>
</Properties> </Properties>
</Item> </Item>
<Item class="ModuleScript" referent="3"> <Item class="ModuleScript" referent="2">
<Properties> <Properties>
<string name="Name">event</string> <string name="Name">event</string>
<string name="Source">local module = {}; <string name="Source">local module = {};
@ -144,10 +345,9 @@ return module;</string>
function module.init(shared) function module.init(shared)
local new = {}; local new = {};
local unpack = table.unpack; local unpack = table.unpack;
local coroutineCreate = coroutine.create; local wrap = coroutine.wrap;
local coroutineResume = coroutine.resume;
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()
@ -158,7 +358,7 @@ function module.init(shared)
func(this); func(this);
end; end;
["Created::"] = function (this,func) ["Created::"] = function (this,func)
coroutineResume(coroutineCreate(func),this); wrap(func)(this);
end; end;
}; };
@ -170,10 +370,19 @@ function module.init(shared)
}); });
-- 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) function new.bind(this,key,func,typefunc)
-- if is advanced binding (self setted)
typefunc = typefunc or type(func);
local self;
if typefunc == "table" then
self = func.self;
func = func.func;
end
-- check prefix -- check prefix
if key:sub(1,prefixLen) ~= prefix then if key:sub(1,prefixLen) ~= prefix then
return; return;
elseif not func then
return true;
end end
key = key:sub(prefixLen + 1,-1); key = key:sub(prefixLen + 1,-1);
@ -190,7 +399,7 @@ function module.init(shared)
local event = this[key]; local event = this[key];
if event then if event then
event:Connect(function(...) event:Connect(function(...)
func(this,...); func(self or this,...);
end); end);
return true; return true;
end end
@ -198,7 +407,7 @@ function module.init(shared)
-- property changed binding -- property changed binding
local prefixProperty = prefix .. "Property::"; local prefixProperty = prefix .. "Property::";
function new.property(name) function new.prop(name)
return prefixProperty .. name; return prefixProperty .. name;
end end
@ -211,7 +420,7 @@ end
return module;</string> return module;</string>
</Properties> </Properties>
</Item> </Item>
<Item class="ModuleScript" referent="4"> <Item class="ModuleScript" referent="3">
<Properties> <Properties>
<string name="Name">mount</string> <string name="Name">mount</string>
<string name="Source">local module = {}; <string name="Source">local module = {};
@ -219,14 +428,33 @@ return module;</string>
function module.init(shared) function module.init(shared)
local new = {}; local new = {};
local mount = {};
mount.__index = mount;
function mount:unmount()
local this = self.this;
local typeThis = type(this);
if typeThis == "userdata" then
this:Destroy();
elseif typeThis == "table" then
pcall(function()
this.Parent = nil;
end);
local destroyThis = this.Destroy;
if destroyThis then
pcall(destroyThis);
end
end
end
-- we should add plugin support -- we should add plugin support
function new.mount(to,this) function new.mount(to,this)
this.Parent = to; this.Parent = to;
return setmetatable({to = to,this = this},mount);
end end
setmetatable(new,{ setmetatable(new,{
__call = function (self,...) __call = function (self,...)
self.mount(...); return new.mount(...);
end; end;
}); });
@ -236,7 +464,7 @@ end
return module;</string> return module;</string>
</Properties> </Properties>
</Item> </Item>
<Item class="ModuleScript" referent="5"> <Item class="ModuleScript" referent="4">
<Properties> <Properties>
<string name="Name">require</string> <string name="Name">require</string>
<string name="Source">-- remove the roblox's require system, <string name="Source">-- remove the roblox's require system,
@ -272,7 +500,7 @@ return function (query)
end;</string> end;</string>
</Properties> </Properties>
</Item> </Item>
<Item class="ModuleScript" referent="6"> <Item class="ModuleScript" referent="5">
<Properties> <Properties>
<string name="Name">store</string> <string name="Name">store</string>
<string name="Source"><![CDATA[local module = {}; <string name="Source"><![CDATA[local module = {};
@ -282,23 +510,132 @@ this feature allows get object without making some created callback and local va
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 insert = table.insert; local insert = table.insert;
local remove = table.remove;
local function catch(...)
local passed,err = pcall(...);
if not passed then
wran("[QUAD] Error occured while operating async task\n" .. tostring(err));
end
end
function module.init(shared) function module.init(shared)
local new = {}; local new = {};
local items = shared.items; local items = shared.items;
-- id space (array of object)
local objSpace = {};
function objSpace:each(func)
for i,v in ipairs(self) do
wrap(catch)(func,i,v);
end
end
function objSpace:eachSync(func)
for i,v in ipairs(self) do
local ret = func(i,v);
if ret then
break;
end
end
end
function objSpace:remove(indexOrItem)
local thisType = type(indexOrItem);
if thisType == "number" then
remove(self,indexOrItem);
else
for i,v in pairs(self) do
if v == indexOrItem then
remove(self,i);
break;
end
end
end
end
function objSpace.__new()
return setmetatable({},objSpace);
end
function objSpace:__newIndex(key,value) -- props setter
self:each(function (this)
this[key] = value;
end);
end
objSpace.__mode = "kv"; -- week link for gc
objSpace.__index = objSpace;
-- get object array with id (objSpace)
function new.getObjects(id) function new.getObjects(id)
return items[id]; return items[id];
end end
function new.addObject(id,object)
-- get first object with id (not array)
function new.getObject(id)
local item = items[id];
return item and item[1];
end
--TODO: if item is exist already, ignore this call
-- adding object with id
function new.addObject(ids,object)
for id in ids:gmatch("[^,]+") do -- split by ,
-- remove trailing, heading spaces
id = id:gsub("^ +",""):gsub(" +$","");
local array = items[id]; local array = items[id];
if not array then if not array then
array = {}; array = objSpace.__new();
items[id] = array; items[id] = array;
end end
insert(array, object); insert(array, object);
end end
end
-- bindable store object
local store = {};
function store:__index(key)
return self.__self[key];
end
function store:__newindex(key,value)
self.__self[key] = value;
local event = self.__evt[key];
if event then
for _,v in ipairs(event) do
wrap(catch)(v,value,store);
end
end
end
function store:__call(key,func)
local register = self.__reg[key];
if not register then
local event = {}
self.__evt[key] = event;
register = {
register = function (efunc)
insert(event,efunc);
end;
with = function (s,efunc)
return setmetatable({wfunc = efunc},{__index = s});
end;
default = function (s,value)
return setmetatable({dvalue = value},{__index = s});
end;
key = key;
store = self;
t = "reg";
};
self.__reg[key] = register;
end
if func then
register.register(func);
end
return register;
end
function new.new(self)
return setmetatable(
{__self = self or {},__evt = {},__reg = {}},store
);
end
return new; return new;
end end
@ -307,23 +644,5 @@ return module;
]]></string> ]]></string>
</Properties> </Properties>
</Item> </Item>
<Item class="ModuleScript" referent="7">
<Properties>
<string name="Name">style</string>
<string name="Source">local module = {};
function module.init(shared)
local new = {};
function shared.new(property)
end
return new;
end
return module;</string>
</Properties>
</Item>
</Item> </Item>
</roblox> </roblox>

52
mybutton.lua Normal file
View file

@ -0,0 +1,52 @@
local quad = require(script.Parent.quad);
local render = quad.init();
local class = render.class;
local event = render.event;
local myButton = class.extend(); -- 클래스 만들기
local imageButton = class.import "ImageButton"; -- 로블 인스턴스 클래스화
local textLabel = class.import "TextLabel";
local textButton = class.import "TextButton";
-- 인스턴스의 기본값 설정
imageButton.BackgroundTransparency = 1;
textButton.BorderSizePixel = 0;
textLabel.Size = UDim2.fromScale(1,1);
-- 기본 값 설정
function myButton:init(props)
props.style = props.style or "round"; -- flat ...
props.roundSize = props.roundSize or 12;
props.Text = props.Text or "Button Text";
props.Size = props.Size or UDim2.fromOffset(120,32);
end
-- 렌더링
function myButton:render(props)
if props.style == "round" then
return imageButton {
Size = props "Size";
Image = "http://www.roblox.com/asset/?id=4668069300";
ScaleType = Enum.ScaleType.Slice;
SliceCenter = Rect.new(Vector2.new(516,516),Vector2.new(516,516));
SliceScale = props "roundSize":with(function (value)
return 0.0019166666666667 * props.roundSize;
end);
[event "MouseButton1Click"] = {
self = self;
func = props.MouseButton1Click;
};
textLabel {
Text = props "Text";
};
};
elseif props.style == "flat" then
return textButton {
Size = props "Size";
BorderSizePixel = 2;
}
else error ("unknown style " .. props.style);
end
end
myButton.updateTriggers.style = true;

View file

@ -15,7 +15,14 @@ function module.init(shared)
local new = {}; local new = {};
local bind = shared.event.bind; local bind = shared.event.bind;
local addObject = shared.store.addObject; local addObject = shared.store.addObject;
local storeNew = shared.store.new;
function new.getHolder(item)
return (type(item) == "table") and (item._holder or item.holder or item.__holder) or item;
end
local getHolder = new.getHolder;
-- make object that from instance, class and more
function new.make(ClassName,...) -- render object function new.make(ClassName,...) -- render object
-- make thing -- make thing
local item; local item;
@ -29,7 +36,8 @@ function module.init(shared)
if ClassName.__noSetup then -- if is support initing props if ClassName.__noSetup then -- if is support initing props
local childs,props = {},{...}; local childs,props = {},{...};
local parsed; local parsed;
for iprop,prop in ipairs(props) do for iprop = #props,1,-1 do
local prop = props[iprop];
for i,v in ipairs(prop) do for i,v in ipairs(prop) do
childs[i] = ((iprop == 1) and v or v:Clone()); childs[i] = ((iprop == 1) and v or v:Clone());
prop[i] = nil; prop[i] = nil;
@ -37,15 +45,15 @@ function module.init(shared)
if next(prop) then -- there are (key/value)s if next(prop) then -- there are (key/value)s
if parsed then if parsed then
for i,v in pairs(prop) do for i,v in pairs(prop) do
prop[i] = v; parsed[i] = v;
end end
else else
parsed = prop; parsed = prop;
end end
end end
end end
item = func(props); item = func(parsed);
local holder = (type(item) == "table") and (item.__holder or item.holder) or item; local holder = getHolder(item);
for _,v in ipairs(childs) do for _,v in ipairs(childs) do
v.Parent = holder; v.Parent = holder;
end end
@ -59,17 +67,43 @@ function module.init(shared)
end end
-- set property and adding child and binding functions -- set property and adding child and binding functions
local holder = (type(item) == "table") and (item.__holder or item.holder) or 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 pairs({...}) do -- for iprop,prop in ipairs({...}) do
for iprop = select("#",...),1,-1 do
local prop = select(iprop,...);
for index,value in pairs(prop) do for index,value in pairs(prop) do
local valueType = typeof(value); local valueType = typeof(value);
local indexType = typeof(index); local indexType = typeof(index);
-- child -- child
if valueType == "function" and bind(value) then -- connect event if indexType == "string" and valueType == "table" and value.t == "reg" then -- register (bind to store event)
-- store binding
local with = value.wfunc;
local set = value.store[value.key];
if set then
if with then
set = with(set);
end
item[index] = set;
else
local dset = value.dvalue;
if dset then
item[index] = dset;
end
end
value.register(function (newValue,store)
if with then
newValue = with(newValue,item,store);
end
item[index] = newValue;
end);
elseif (valueType == "function" or valueType == "table") and bind(item,index,value,valueType) then -- connect event
-- event binding
elseif indexType == "string" then elseif indexType == "string" then
-- prop set
item[index] = value; -- set property item[index] = value; -- set property
elseif indexType == "number" then -- object elseif indexType == "number" then -- object
-- child object
((iprop == 1) and value or value:Clone()).Parent = holder; ((iprop == 1) and value or value:Clone()).Parent = holder;
end end
end end
@ -78,6 +112,7 @@ function module.init(shared)
end end
local make = new.make; local make = new.make;
-- import quad object
function new.import(ClassName,defaultProperties) -- make new quad class object function new.import(ClassName,defaultProperties) -- make new quad class object
local this = defaultProperties or {}; local this = defaultProperties or {};
setmetatable(this,{ setmetatable(this,{
@ -116,6 +151,127 @@ function module.init(shared)
end; end;
}); });
-- make class
function new.extend()
local this = {};
--- make new object
function this.new(prop)
-- make metatable
prop = storeNew(prop);
local parent = prop and (prop.Parent or prop.parent);
local self = {__prop = prop; __parent = parent};
local init = this.init;
if init then
init(self,prop);
end
setmetatable(self,this);
-- render that
local object = self:render(prop);
rawset(self,"__object",object);
rawset(self,"__holder",object);
if parent then
rawset(self,"__parent",parent);
object.Parent = getHolder(parent);
end
return self;
end
--- re-render object (if some props chaged, call this to render again)
function this:update() -- swap object
local object = rawget(self,"__object"); -- get last instance
local parent = rawget(self,"__parent") or (object and object.Parent); -- date parent
local lastObject = object;
if lastObject then
lastObject.Parent = nil;
end
object = self:render(self.__prop); -- new instance
rawset(self,"__holder",object);
rawset(self,"__object",object);
object.Parent = getHolder(parent); -- update parent
if lastObject then -- remove old instance
self:Destroy(lastObject);
end
end
-- define destroy method
function this:Destroy(object)
local unload = rawget(self,"unload");
object = object or rawget(self,"__object");
if object then
if unload then
unload(self,object);
else
local destroy = (object.Destroy or object.destroy);
if destroy then
pcall(destroy,object);
end
end
end
end
--- link to new
function this.__call(self,...)
return (self.new or self.New or self.__new)(...);
end;
-- indexer (getter)
function this:__index(k)
if k == "destroy" then
return self.Destroy;
end
local getter = this.getter[k];
if getter then
return getter(self,rawget(self,"__object"));
end
-- from this (have more priority)
local fromThis = this[k];
if fromThis then
return fromThis;
end
-- from prop, not start with '_' (private value)
if k:sub(1,1) ~= "_" then
return self.__prop[k];
end
end
--- new indexer (setter)
function this:__newindex(k,v)
-- from setter
local setter = this.setter[k];
if setter then
return setter(self,v,rawget(self,"__object"));
end
-- is private (self value)
if k == "holder" or k:sub(1,1) == "_" then
return rawset(self,k,v);
end
-- prop update
self.__prop[k] = v;
if this.updateTriggers[k] then
self:update();
end
end
this.getter = {};
this.setter = {
Parent = function(self,parent,object)
rawset(self,"__parent",parent);
if object then
object.Parent = getHolder(parent);
end
end;
};
this.updateTriggers = {};
this.__noSetup = true;
return this;
end
return new; return new;
end end

View file

@ -3,10 +3,9 @@ local module = {};
function module.init(shared) function module.init(shared)
local new = {}; local new = {};
local unpack = table.unpack; local unpack = table.unpack;
local coroutineCreate = coroutine.create; local wrap = coroutine.wrap;
local coroutineResume = coroutine.resume;
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()
@ -17,7 +16,7 @@ function module.init(shared)
func(this); func(this);
end; end;
["Created::"] = function (this,func) ["Created::"] = function (this,func)
coroutineResume(coroutineCreate(func),this); wrap(func)(this);
end; end;
}; };
@ -29,10 +28,19 @@ function module.init(shared)
}); });
-- 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) function new.bind(this,key,func,typefunc)
-- if is advanced binding (self setted)
typefunc = typefunc or type(func);
local self;
if typefunc == "table" then
self = func.self;
func = func.func;
end
-- check prefix -- check prefix
if key:sub(1,prefixLen) ~= prefix then if key:sub(1,prefixLen) ~= prefix then
return; return;
elseif not func then
return true; -- nil binding
end end
key = key:sub(prefixLen + 1,-1); key = key:sub(prefixLen + 1,-1);
@ -49,7 +57,7 @@ function module.init(shared)
local event = this[key]; local event = this[key];
if event then if event then
event:Connect(function(...) event:Connect(function(...)
func(this,...); func(self or this,...);
end); end);
return true; return true;
end end

View file

@ -23,7 +23,7 @@ frame{
]] ]]
require = require(script.require); local require = require(script.require);
local event = require("event"); ---@module "src.event" local event = require("event"); ---@module "src.event"
local store = require("store"); ---@module "src.store" local store = require("store"); ---@module "src.store"
--local style = require("style"); --local style = require("style");

View file

@ -20,6 +20,7 @@ function module.init(shared)
local new = {}; local new = {};
local items = shared.items; local items = shared.items;
-- id space (array of object)
local objSpace = {}; local objSpace = {};
function objSpace:each(func) function objSpace:each(func)
for i,v in ipairs(self) do for i,v in ipairs(self) do
@ -50,21 +51,27 @@ function module.init(shared)
function objSpace.__new() function objSpace.__new()
return setmetatable({},objSpace); return setmetatable({},objSpace);
end end
function objSpace:__newIndex(key,value) function objSpace:__newIndex(key,value) -- props setter
self:each(function (this) self:each(function (this)
this[key] = value; this[key] = value;
end); end);
end end
objSpace.__mode = "kv"; -- week link for gc
objSpace.__index = objSpace; objSpace.__index = objSpace;
-- get object array with id (objSpace)
function new.getObjects(id) function new.getObjects(id)
return items[id]; return items[id];
end end
-- 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[1]; return item and item[1];
end end
--TODO: if item is exist already, ignore this call --TODO: if item is exist already, ignore this call
-- adding object with id
function new.addObject(ids,object) function new.addObject(ids,object)
for id in ids:gmatch("[^,]+") do -- split by , for id in ids:gmatch("[^,]+") do -- split by ,
-- remove trailing, heading spaces -- remove trailing, heading spaces
@ -78,6 +85,7 @@ function module.init(shared)
end end
end end
-- bindable store object
local store = {}; local store = {};
function store:__index(key) function store:__index(key)
return self.__self[key]; return self.__self[key];
@ -96,20 +104,31 @@ function module.init(shared)
if not register then if not register then
local event = {} local event = {}
self.__evt[key] = event; self.__evt[key] = event;
register = {
register = function (efunc) register = function (efunc)
insert(event,efunc); insert(event,efunc);
end; end;
with = function (s,efunc)
return setmetatable({wfunc = efunc},{__index = s});
end;
default = function (s,value)
return setmetatable({dvalue = value},{__index = s});
end;
key = key;
store = self;
t = "reg";
};
self.__reg[key] = register; self.__reg[key] = register;
end end
if func then if func then
register(func); register.register(func);
end end
return {register,t="reg"}; return register;
end end
function new.new() function new.new(self)
return setmetatable( return setmetatable(
{__self = {},__evt = {},__reg = {}},store {__self = self or {},__evt = {},__reg = {}},store
); );
end end

View file

@ -33,3 +33,63 @@ store.getObjects "Child":forEach(function (this)
print(this); print(this);
end); end);
``` ```
# 클래서
```lua
-- 새로운 클래스를 확장한다
local myButton = class.extend();
-- 클래스를 초기화합니다, 메타 테이블에 영향을 받지 않습니다
-- 선택적입니다
function myButton:init(prop)
prop.Text = prop.Text or "Hello world"; -- 기본 값을 설정합니다
end
-- 실제 그려질 때 이다
function myButton:render(prop)
-- if you make value in self, you must be use
-- prefix '_', if you missing that, it will make
-- overflow on meta method!!
self._someValue = 2;
return textButton {
frame {
[event.created] = function (this)
self._holder = this; -- set holder for child instance
end;
};
--Text = prop.Text; -- 이렇게 하면 업데이트 될 때 다시 그려짐
Text = prop "Text":default("Hello world"); -- 이렇게 하면 업데이트 될 때 프로퍼티만 고침
[event "MouseButton1Click"] = {
self = self;
func = prop[event "MouseButton1Click"];
};
[event.created] = function (this)
self._button;
end;
};
end
myButton.ignore.Text = true;
function myButton.getter:MouseButton1Click(object)
return (self._button or object).MouseButton1Click;
-- ^ this is same ^
end
function myButton.setter:Count(v,object)
self._someValue = v;
end
function myButton.getter:Count(object)
return self._someValue;
end
-- this is option, you can set destroy functions
function myButton:unload(object)
print("remove myButton",object,self);
object:Destroy();
end
-- DONT MAKE THIS! this is will broken class system
-- function myButton.new()
-- end
```