diff --git a/src/class.lua b/src/class.lua index 63e4e04..9ea89e0 100644 --- a/src/class.lua +++ b/src/class.lua @@ -2,6 +2,7 @@ local module = {}; local pack = table.pack; local match = string.match; local insert = table.insert; +local gsub = string.gsub ---@param shared quad_export ---@return quad_module_class @@ -59,6 +60,7 @@ function module.init(shared) end return item[index]; end + new.getProperty = getProperty local function setProperty(item,index,value,ClassName) if type(item) == "table" then item[index] = value; return; end @@ -92,12 +94,13 @@ function module.init(shared) item[index] = value; -- set property end end + new.setProperty = setProperty local function rawGetProperty(item,index) return item[index]; end local function pcallGetProperty(item,index) - local ok,err = pcall(rawGetProperty,index); + local ok,err = pcall(rawGetProperty,item,index); if ok then return err; end return nil; end @@ -109,7 +112,8 @@ function module.init(shared) local indexType = typeof(index); -- child - if indexType == "string" and valueType == "table" and pcallGetProperty(value,"__type") == "quad_register" then -- register (bind to store event) + local quadType = valueType == "table" and pcallGetProperty(value,"__type") + if indexType == "string" and valueType == "table" and quadType == "quad_register" then -- register (bind to store event) processedProperty[index] = true; -- ignore next -- store reading do @@ -155,7 +159,7 @@ function module.init(shared) processedProperty[index] = true; -- ignore next -- prop set setProperty(item,index,value,className); - elseif indexType == "number" and valueType == "table" and pcallGetProperty(value,"__type") == "quad_style" then -- style + elseif indexType == "number" and valueType == "table" and quadType == "quad_style" then -- style -- style parsing for _,thisStyle in ipairs(parseStyles(value)) do if not processedProperty[thisStyle] then @@ -253,7 +257,7 @@ function module.init(shared) local lastName = prop; return function (nprop,...) nprop = nprop or {}; - nprop.Name = lastName; + nprop.Name = gsub(gsub(match(lastName,"[^,]+")," +$",""),"^ +",""); for styleName,styleObj in pairs(styleList) do if match(prop,styleName) then insert(nprop,styleObj); @@ -288,7 +292,7 @@ function module.init(shared) -- make metatable prop = storeNew(prop,nil); local parent = prop and (prop.Parent or prop.parent); - local self = {__prop = prop; __parent = parent}; + local self = {__prop = prop; __parent = parent,__propertyChangedSignals = {}}; local init = this.init; if init then init(self,prop); @@ -318,6 +322,18 @@ function module.init(shared) return self; end + function this:GetPropertyChangedSignal(propertyName) + local signal = self.__propertyChangedSignals[propertyName] + if not signal then + signal = {} + self.__propertyChangedSignals[propertyName] = signal + end + end + + function this:EmitPropertyChangedSignal(propertyName,value) + + 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 diff --git a/src/init.lua b/src/init.lua index edc5bd9..95dfe13 100644 --- a/src/init.lua +++ b/src/init.lua @@ -45,7 +45,12 @@ function module.init(id) return this,this.round,this.class,this.mount,this.store,this.event,this.tween,this.style; end +local function cleanup(space) + -- space.items +end + function module.uninit(id) + pcall(cleanup,idSpace[id]) idSpace[id] = nil; end diff --git a/src/libs/AdvancedTween/init.lua b/src/libs/AdvancedTween/init.lua index 5faf096..7d4fba9 100644 --- a/src/libs/AdvancedTween/init.lua +++ b/src/libs/AdvancedTween/init.lua @@ -145,6 +145,11 @@ module.LerpProperties = LerpProperties --Properties : 트윈할 속성과 목표값 예시 : --Data.Properties.Position = UDim2.new(1,0,1,0) 처럼 하면 Position 속성의 목표를 1,0,1,0 으로 지정 function module.RunTween(Item,Data,Properties,Ended,OnStepped,Setter,Getter,_) + OnStepped = OnStepped or Data.OnStepped + Ended = Ended or Data.Ended + Setter = Setter or Data.Setter + Getter = Getter or Data.Getter + -- remove self if Item == module then warn "AdvancedTween:RunTween() is deprecated, Use AdvancedTween.RunTween() instead"; Item = Data; Data = Properties; Properties = Ended; Ended = OnStepped; OnStepped = Setter; Setter = Getter; Getter = _; end @@ -275,20 +280,12 @@ function module.RunTween(Item,Data,Properties,Ended,OnStepped,Setter,Getter,_) if CallBack then for FncIndex,Fnc in pairs(CallBack) do if FncIndex == "*" then - Fnc(Index,Alpha,Item) + Fnc(Item,Index,Alpha) else local num = tonumber(FncIndex) - if num then - if num <= Index then - Fnc(Alpha,Item) - CallBack[FncIndex] = nil - end - else - local alphaNum = tonumber(FncIndex:match"~([%d.]+)") - if alphaNum <= Alpha then - Fnc(Index,Item) - CallBack[FncIndex] = nil - end + if num and num <= Index then + Fnc(Alpha,Index,Item) + CallBack[FncIndex] = nil end end end diff --git a/src/signal.lua b/src/signal.lua new file mode 100644 index 0000000..7c79d07 --- /dev/null +++ b/src/signal.lua @@ -0,0 +1,19 @@ + +local module = {} +local signal + +local customSignal = {} +customSignal.__index = customSignal +function customSignal:emit(name,...) + +end +function customSignal:Connect() +end +function customSignal.new() + local self = {} + setmetatable(self,customSignal) +end +function this.new(...) + customSignal.new(...) +end +this.customSignal = customSignal diff --git a/src/store.lua b/src/store.lua index eb527a1..364225d 100644 --- a/src/store.lua +++ b/src/store.lua @@ -5,11 +5,12 @@ this feature allows get object without making some created callback and local va but, it can't allows mulit id and object this feature should be upgraded ]] -local wrap = coroutine.wrap; +local wrap = coroutine.wrap; local insert = table.insert; local remove = table.remove; local gmatch = string.gmatch; -local gsub = string.gsub; +local gsub = string.gsub; +local match = string.match; local function catch(...) local passed,err = pcall(...); @@ -50,12 +51,11 @@ function module.init(shared) function objectListClass:remove(indexOrItem) local thisType = type(indexOrItem); if thisType == "number" then - remove(self,indexOrItem); + return remove(self,indexOrItem),indexOrItem; else for i,v in pairs(self) do if v == indexOrItem then - remove(self,i); - break; + return remove(self,i),i; end end end @@ -76,12 +76,26 @@ function module.init(shared) objectListClass.__index = objectListClass; -- get object array with id (objSpace) - function new.getObjects(id) - local list = items[id]; - if list then return list; end - list = objectListClass.__new(id); - items[id] = list; - return list; + function new.getObjects(ids) + if match(ids,",") then + local list = items[ids]; + if list then return list; end + list = objectListClass.__new(); + items[ids] = list; + return list; + else + local list = objectListClass.__new(); + for id in gmatch(ids,"[^,]+") do -- split by , + id = gsub(gsub(id,"^ +","")," +$",""); + local idItem = items[id]; + if idItem then + for _,item in pairs(idItem) do + insert(list,item); + end + end + end + return list + end end -- get first object with id (not array) function new.getObject(id) @@ -208,7 +222,7 @@ function module.init(shared) -- if got register, just copy data to self and connect 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"; - + local selfValues = self.__self; local selfTweens = self.__tweens; @@ -303,8 +317,7 @@ function module.init(shared) return register; end function store:default(key,value) - local old = self[key]; - if old == nil then + if self[key] == nil then self[key] = value; return; end diff --git a/src/types.lua b/src/types.lua new file mode 100644 index 0000000..65f8bd7 --- /dev/null +++ b/src/types.lua @@ -0,0 +1,165 @@ +------------------- +-- module_class +------------------- +export type extend = { + getter: {[string]: ()->any|any?}; + setter: {[string]: ()->()?}; +} +export type DOM = { + [string]: any; +} +export type DOM_constructor = { + [event]: + (DOM,...any)->() + &{self: any,func: ()->()}; +} & { [number]: DOM|style; } +& { [string]: any|register; } +export type DOM_creator = (DOM_constructor,...DOM_constructor)->DOM +export type imported = + {[string]:any} + &(ids:ObjectIdList)->DOM_creator + &DOM_creator +export type import = (ClassName:string|ModuleScript|extend|()->()|{any},defaultProperties:DOM_constructor?)->imported +export type module_class = { + extend: ()->extend; + import: import; + getProperty: (item:extend|any,index:string,ClassName:string?)->any; + setProperty: (item:extend|any,index:string,value:any,ClassName:string?)->(); + make: (ClassName:string|(...any)->any|extend,...{any})->any; +} & import + +------------------- +-- module_event +------------------- +export type event = string +export type disconnecter = { + add: (self:disconnecter,connection:RBXScriptConnection)->(); + destroy: (self:disconnecter)->(); + disconnect: (self:disconnecter)->(); +} +export type module_event = { + prop: (propName:string)->event; + createdAsync: event; + created: event; + bind: (this:DOM|any,key:event|string,func:(...any)->(),typefunc:string?)->(); + disconnecter: (id:string?)->disconnecter; +} & (eventName:string)->event; + +------------------- +-- module_signal +------------------- +export type module_signal = {} + +------------------- +-- module_register +------------------- +export type register = { + register: (self:register,()->())->(); + with: (self:R®ister,handler:{any}|(store:store,value:any,key:any,item:DOM)->any)->R®ister; + default: (self:R®ister,value:any)->R®ister; + add: (self:R®ister,value:any)->R®ister; + tween: (self:R®ister,tween:TweenOptions)->R®ister; +} +export type store = {} +export type objectList = { + each: (self:objectList,(item:DOM,index:number)->())->(); + eachSync: (self:objectList,(item:DOM,index:number)->())->(); + remove: (self:objectList,index:number|DOM)->(DOM?,number?); + isEmpty: (self:objectList)->boolean; +} +export type ObjectIdList = string +export type module_store = { + getObjects: (ids:ObjectIdList)->objectList; + getObject: (id:string)->DOM?; + addObject: (ids:ObjectIdList)->(); + +} + +------------------- +-- module_signal +------------------- +export type style = {} +export type module_style = {} + +------------------- +-- module_signal +------------------- +export type module_mount = {} + +------------------- +-- module_signal +------------------- + +export type TweenOnStepped = (Item:DOM|any,Alpha:number,AbsolutePercent:number)->() +export type TweenEnded = (Item:DOM|any)->() +export type TweenSetter = (Item:DOM|any,Property:string,Value:Lerpable)->() +export type TweenGetter = (Item:DOM|any,Property:string)->() +export type TweenOptions = { + Easing: EasingFunction?; + Direction: EasingDirection?; + CallBack: {[number|"*"|string]:(Item:DOM|any,Alpha:number,AbsolutePercent:number)->()}?; + OnStepped: TweenOnStepped?; -- Same as CallBack{["*"]:()->()} But faster then CallBack due to table loop + Ended: TweenEnded?; + Getter: TweenGetter?; + Setter: TweenSetter?; +} +export type EasingFunction = {run:(number)->number,[any]:any} +export type EasingFunctions = { + Linear: EasingFunction; ---직선, Linear. i=x, x=0 ~ 1 + Quint: EasingFunction; ---5제곱, Quint. (^5) i=1-(1-x)^5, x=0 ~ 1 + Quart: EasingFunction; ---4제곱, Quart. (^4) i=1-(1-x)^4, x=0 ~ 1 + Cubic: EasingFunction; ---3제곱, Cubic. (^3) i=1-(1-x)^3, x=0 ~ 1 + Quad: EasingFunction; ---2제곱, Quad. (^2) i=1-(1-x)^2, x=0 ~ 1 + Sin: EasingFunction; ---사인파, Sin. i=sin(x*pi/2), x=0 ~ 1 + Circle: EasingFunction; ---사분원, Circle. i=sqrt(1-(1-x)^2), x=0 ~ 1 + Expo: EasingFunction; ---지수함수, Expo. i=1-2^(-10*x), x=0~1 + Elastic: EasingFunction; ---튀어오름, Elastic. + Bounce: EasingFunction; ---통통거림, Bounce + + -- Old things + Exp2: EasingFunction; ---덜 가파른 지수. i=math.exp(x), x=-4 ~ 2 + Exp4: EasingFunction; ---더 가파른 지수. i=math.exp(x), x=-4 ~ 4 + Exp2Max4: EasingFunction; ---@deprecated +} +export type EasingDirection = string +export type EasingDirections = { + Out: EasingDirection&"Out"; + In: EasingDirection&"In"; +} +export type Lerpable = Color3|UDim|UDim2|number|Vector2|Vector3|CFrame +export type TweenHandler = ()->(); +export type AdvancedTween = { + EasingFunctions:EasingFunctions; + EasingDirections:EasingDirections; + LerpProperties: (item:item&(DOM|any),old:{[string]:Lerpable},new:{[string]:Lerpable},alpha:number,setter:(item:item&(DOM|any),property:string,value:Lerpable)->()?)->(); + RunTween: (Item:DOM|any,Option:TweenOptions,Properties:{[string]:Lerpable},Ended:TweenEnded?,OnStepped:TweenOnStepped?,Setter:TweenSetter?,Getter:TweenGetter?)->TweenHandler; +} + +------------------- +-- module_signal +------------------- +export type round = { + setRound: (ImageFrame:ImageLabel|ImageButton,RoundSize:number)->(ImageLabel|ImageButton); + setOutline: (ImageFrame:ImageLabel|ImageButton,RoundSize:number)->(ImageLabel|ImageButton); + getRound: (ImageFrame:ImageLabel|ImageButton)->number; + getOutline: (ImageFrame:ImageLabel|ImageButton)->number; +} + +------------------- +-- module +------------------- +export type module_exported = { + round: round; + tween: AdvancedTween; + style: module_style; + event: module_event; + store: module_store; + mount: module_mount; + class: module_class; +} +export type module = { + uninit: (id:string)->(); + init: (id:string)->module_exported; +} + +return {} diff --git a/src/vercheck.lua b/src/vercheck.lua new file mode 100644 index 0000000..b514865 --- /dev/null +++ b/src/vercheck.lua @@ -0,0 +1,11 @@ + +local IS_TEST = true +local VER = "1.14" .. (IS_TEST and "B" or "") + +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) +end + +return { + version = VER +}