From fde90076c009cb367840f5a25f018982058efbf7 Mon Sep 17 00:00:00 2001 From: James <119134081+2jammers@users.noreply.github.com> Date: Sun, 5 Jan 2025 15:13:11 -0600 Subject: [PATCH] feat: add scopes to event actions adds scopes to event based actions so they can be cleaned up easily #11 --- src/changed.luau | 7 ++++-- src/{computed.luau => compute.luau} | 33 ++++++----------------------- src/event.luau | 7 ++++-- src/init.luau | 6 ++---- src/spring.luau | 3 +-- src/state.luau | 1 - src/types.luau | 7 ++---- 7 files changed, 21 insertions(+), 43 deletions(-) rename src/{computed.luau => compute.luau} (62%) diff --git a/src/changed.luau b/src/changed.luau index 0dfd600..012f689 100644 --- a/src/changed.luau +++ b/src/changed.luau @@ -12,14 +12,17 @@ local Debugger = require(Root.Parent.roblox_packages.debugger) [Open Documentation](https://lumin-org.github.io/ui/api/actions/#change) ]=] -return function(prop: string, callback: (changed: T) -> ()): Types.Action +return function(prop: string, callback: (changed: T) -> (), scope: {any}?): Types.Action return Action(function(instance) local Success, Event = pcall(instance.GetPropertyChangedSignal, instance :: any, prop :: any) -- Ensure prop exists if not Success or type(callback) ~= "function" then Debugger.Fatal("InvalidPropOrEvent", prop) end - Event:Connect(function() + local ToAdd = Event:Connect(function() callback((instance :: any)[prop]) -- Pass new value through callback end) + if scope then + table.insert(scope, ToAdd) + end end) end diff --git a/src/computed.luau b/src/compute.luau similarity index 62% rename from src/computed.luau rename to src/compute.luau index 5539406..d680bf9 100644 --- a/src/computed.luau +++ b/src/compute.luau @@ -8,22 +8,9 @@ Class.__index = Class -- Functions ---[=[ - Gets the current value of a value object for use within the compute. - - [Open Documentation](https://lumin-org.github.io/ui/api/computed/#use) -]=] -local function Use(value: Types.State | any) - if type(value) == "table" then - return value:Get() - else - return value - end -end - local function Listener(self: Types.Computed) return function() - self._Value = self._Processor(Use) -- Set the value of the computed to the processed value + self._Value = self._Processor() -- Set the value of the computed to the processed value if self._Instances ~= nil then for prop, instance in self._Instances do @@ -64,15 +51,11 @@ end [Open Documentation](https://lumin-org.github.io/ui/api/#computed) ]=] -return function( - processor: (use: (value: Types.State | any) -> ()) -> (), - dependencies: { Types.State | Types.Spring }? -): Types.ComputedExport +return function(processor: () -> (), dependencies: { Types.State | Types.Spring }?): Types.ComputedExport local self = setmetatable({}, Class) - self._Type = "Computed" self._Processor = processor - self._Value = processor(Use) + self._Value = processor() self._Instances = {} self._Dependencies = nil @@ -82,13 +65,9 @@ return function( self._Dependencies = {} :: any for _, dependency in dependencies do if type(dependency) == "table" then - if dependency._Type == "Spring" then - (self._Dependencies :: any)[dependency] = (dependency :: any)._Goal:Listen(Listener(self :: any)) - elseif dependency._Type == "State" then - (self._Dependencies :: any)[dependency] = (dependency :: any):Listen(Listener(self :: any)) - else - Debugger.Fatal("InvalidType", "state or spring", type(dependency)) - end + (self._Dependencies :: any)[dependency] = (dependency :: any):Listen(Listener(self :: any)) + else + Debugger.Fatal("InvalidType", "state", type(dependency)) end end end diff --git a/src/event.luau b/src/event.luau index 7402c53..e0851c6 100644 --- a/src/event.luau +++ b/src/event.luau @@ -16,12 +16,15 @@ end [Open Documentation](https://lumin-org.github.io/ui/api/keys/#event) ]=] -return function(event: string, callback: (...any) -> ()): Types.Action +return function(event: string, callback: (...any) -> (), scope: {any}?): Types.Action return Action(function(instance: Instance) local Success, Event = pcall(Find, instance :: any, event :: any) -- Ensure event exists if not Success or type(callback) ~= "function" then Debugger.Fatal("InvalidPropOrEvent", event) end - Event:Connect(callback) + local ToAdd = Event:Connect(callback) + if scope then + table.insert(scope, ToAdd) + end end) end diff --git a/src/init.luau b/src/init.luau index 72fe8ea..d2cbd9f 100644 --- a/src/init.luau +++ b/src/init.luau @@ -13,17 +13,15 @@ export type Animatable = Types.Animatable -- Module Debugger.SetMetadata(Logs, { - URL = "https://github.com/lumin-org/ui", + URL = "https://lumin-org.github.io/ui/error/#", Name = "UI", }) return table.freeze({ - version = { major = 0, minor = 3, patch = 0 }, - New = require(script.new), Update = require(script.update), State = require(script.state), - Computed = require(script.computed), + Compute = require(script.compute), Spring = require(script.spring), Cleanup = require(script.cleanup), Action = require(script.action), diff --git a/src/spring.luau b/src/spring.luau index 66ed3a8..88a7b6f 100644 --- a/src/spring.luau +++ b/src/spring.luau @@ -75,11 +75,10 @@ end ]=] return function(goal: Types.State, damping: number?, frequency: number?): Types.SpringExport Debugger.Assert(table.find(Animatable, typeof((goal :: any):Get())), "NotAnimatable", typeof((goal :: any):Get())) - Debugger.Assert(type(goal) == "table" and goal._Type == "State", "InvalidType", "State", type(goal)) + Debugger.Assert(type(goal) == "table" and goal._Listeners, "InvalidType", "State", type(goal)) local self = setmetatable({}, Class) - self._Type = "Spring" self._Damping = damping or 1 self._Frequency = frequency or 1 self._Instances = {} diff --git a/src/state.luau b/src/state.luau index 2f40712..fee194a 100644 --- a/src/state.luau +++ b/src/state.luau @@ -86,7 +86,6 @@ return function(initial: any): Types.StateExport local self = setmetatable({}, Class) - self._Type = "State" self._Value = initial self._Listeners = {} diff --git a/src/types.luau b/src/types.luau index 844e9e2..6e9232b 100644 --- a/src/types.luau +++ b/src/types.luau @@ -14,7 +14,7 @@ export type Animatable = export type Action = (instance: Instance, ...any) -> () export type New = (T) -> ({ any }) -> U export type NewInstance = - & New<"Folder", Folder> + & New<"Folder", Folder> & New<"BillboardGui", BillboardGui> & New<"CanvasGroup", CanvasGroup> & New<"Frame", Frame> @@ -56,7 +56,6 @@ export type StateExport = { export type State = typeof(setmetatable( {} :: { - _Type: "State", _Value: any, _Listeners: { (newValue: any, oldValue: any) -> () }, }, @@ -69,7 +68,6 @@ export type SpringExport = { export type Spring = typeof(setmetatable( {} :: { - _Type: "Spring", _Goal: StateExport, _Damping: number, _Frequency: number, @@ -82,8 +80,7 @@ export type ComputedExport = Constructor export type Computed = typeof(setmetatable( {} :: { - _Type: "Computed", - _Processor: (use: (value: State | any) -> ()) -> (), + _Processor: () -> (), _Value: any, _Dependencies: { State | Spring }, _Instances: { [string]: Instance }?,