From 24a6e0f6b7bf47a67b978afeeb94116a10cc7dfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=84=B8=EC=A0=A4=EA=B7=80=20=EA=B3=A0=EC=96=91=EC=9D=B4?= =?UTF-8?q?=EB=93=A4?= <46598063+qwreey75@users.noreply.github.com> Date: Fri, 24 Dec 2021 17:32:19 +0900 Subject: [PATCH] change build system --- build.project.json | 9 + build.rbxmx | 648 ------------------------------------------ build.sh | 2 +- default.project.json | 11 +- test.project.json | 18 -- testScript.client.lua | 2 +- 6 files changed, 18 insertions(+), 672 deletions(-) create mode 100644 build.project.json delete mode 100644 build.rbxmx delete mode 100644 test.project.json diff --git a/build.project.json b/build.project.json new file mode 100644 index 0000000..5fd06aa --- /dev/null +++ b/build.project.json @@ -0,0 +1,9 @@ +{ + "name": "Plugin", + "tree": { + "$properties": { + "Name": "quad" + }, + "$path": "src" + } +} \ No newline at end of file diff --git a/build.rbxmx b/build.rbxmx deleted file mode 100644 index cb10f08..0000000 --- a/build.rbxmx +++ /dev/null @@ -1,648 +0,0 @@ - - - - Plugin - quad - - - - - class - 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) - local new = {}; - local bind = shared.event.bind; - 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 - -- make thing - local item; - local classOfClassName = type(ClassName); - if classOfClassName == "string" then -- if classname is a string value, cdall instance.new for making new roblox instance - item = Instance.new(ClassName); - elseif classOfClassName == "function" then -- if classname is a function value, call it for making new object (OOP object) - item = ClassName(); - 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; - 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(); - end - if not item then -- if cannot make new object, ignore this call - local str = tostring(ClassName); - print(("fail to make item '%s', did you forget to checking the class '%s' is exist?"):format(str,str)); - end - - -- 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 - 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 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 - -- 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 - return item; - end - local make = new.make; - - -- import quad object - function new.import(ClassName,defaultProperties) -- make new quad class object - local this = defaultProperties or {}; - setmetatable(this,{ - __call = function (self,prop) - if type(prop) == "string" then - local lastName = prop; - return function (nprop) - nprop.Name = lastName; - local item = make(ClassName,nprop); - addObject(lastName,item); - return item; - end; - end - return make(ClassName,prop,this); - end; - }); - return this; - 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 - setmetatable(new,{ - __call = function (self,...) - return new.import(...); - 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; -end - -return module; - - - - - event - local module = {}; - -function module.init(shared) - local new = {}; - local unpack = table.unpack; - local wrap = coroutine.wrap; - - local prefix = "Event::"; - local special = { - ["Property::(.+)"] = function (this,func,property) - this.GetPropertyChangedSignal(property):Connect(function() - func(this,this[property]); - end); - end; - ["CreatedSync::"] = function (this,func) - func(this); - end; - ["Created::"] = function (this,func) - wrap(func)(this); - end; - }; - - local prefixLen = #prefix; - setmetatable(new,{ - __call = function(self,eventName) - return prefix .. eventName; - end; - }); - - -- try binding, if key dose match with anything, ignore call - 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 - if key:sub(1,prefixLen) ~= prefix then - return; - elseif not func then - return true; - end - key = key:sub(prefixLen + 1,-1); - - -- find special bindings - for specKey,specFunc in pairs(special) do - local find = {key:match(specKey)}; - if #find ~= 0 then - specFunc(this,func,unpack(find)); - return true; - end - end - - -- binding normal events - local event = this[key]; - if event then - event:Connect(function(...) - func(self or this,...); - end); - return true; - end - end - - -- property changed binding - local prefixProperty = prefix .. "Property::"; - function new.prop(name) - return prefixProperty .. name; - end - - -- when created binding - new.created = prefix .. "Created::"; - new.createdSync = prefix .. "CreatedSync::"; - return new; -end - -return module; - - - - - mount - local module = {}; - -function module.init(shared) - 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 - function new.mount(to,this) - this.Parent = to; - return setmetatable({to = to,this = this},mount); - end - - setmetatable(new,{ - __call = function (self,...) - return new.mount(...); - end; - }); - - return new; -end - -return module; - - - - - require - -- remove the roblox's require system, --- now, we can call modules with string path - -if (not workspace) and (not game) and (not script) then - return; -end - -return function (query) - local typeQuery = type(query); - - if typeQuery == "string" then - local object = script.Parent; - query = query:gsub("/","."); - -- local index = 0; - query:gsub("[^%.]+",function (this) - -- index = index + 1; - -- if index == 1 and this == "src" then - -- return; - -- end - local lastObject = object; - object = object[this]; - if not object then - object = lastObject.libs - error(("[require] : object %s was not found from this worktree, require failed"):format(query)); - end - end); - return require(object); - elseif typeQuery == "userdata" then - return require(query); - end -end; - - - - - store - - - - - \ No newline at end of file diff --git a/build.sh b/build.sh index fa3e5ec..b3e96fa 100644 --- a/build.sh +++ b/build.sh @@ -1 +1 @@ -rojo build default.project.json -o build.rbxmx \ No newline at end of file +rojo build build.project.json -o build.rbxmx \ No newline at end of file diff --git a/default.project.json b/default.project.json index 5fd06aa..b9f71b6 100644 --- a/default.project.json +++ b/default.project.json @@ -1,9 +1,12 @@ { "name": "Plugin", "tree": { - "$properties": { - "Name": "quad" - }, - "$path": "src" + "$className": "DataModel", + "ReplicatedStorage": { + "$className": "ReplicatedStorage", + "Quad": { + "$path": "src" + } + } } } \ No newline at end of file diff --git a/test.project.json b/test.project.json deleted file mode 100644 index f0c4b51..0000000 --- a/test.project.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "Plugin", - "tree": { - "$className": "DataModel", - "StarterGui": { - "$className": "StarterGui", - "testGUI": { - "$className": "ScreenGui", - "testScript": { - "$path": "testScript.client.lua" - }, - "quad": { - "$path": "src" - } - } - } - } -} \ No newline at end of file diff --git a/testScript.client.lua b/testScript.client.lua index 689e8c7..687781d 100644 --- a/testScript.client.lua +++ b/testScript.client.lua @@ -1,6 +1,6 @@ -- 이렇게 모듈을 부를 수 있다, 뒤에 if 가 붇은것은 자동완성이 뜨도록 하기 위해서 사용된다 ---@module "src/init.lua" -local quad = require(script.Parent.quad); +local quad = require(game.ReplicatedStorage:WaitForChild "Quad"); local render = quad.init(); -- init 함수를 이용해 여러 스크립트가 이 모듈을 호출해도 완전히 별계의 -- 환경에서 실행될 수 있도록 만든다, init 를 호출하면 완전히 새로운 store 와 style