-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSignal.lua
More file actions
76 lines (63 loc) · 2.45 KB
/
Signal.lua
File metadata and controls
76 lines (63 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
--- Lua-side duplication of the API of events on Roblox objects.
-- Signals are needed for to ensure that for local events objects are passed by
-- reference rather than by value where possible, as the BindableEvent objects
-- always pass signal arguments by value, meaning tables will be deep copied.
-- Roblox's deep copy method parses to a non-lua table compatable format.
-- @classmod Signal
local Signal = {}
Signal.__index = Signal
Signal.ClassName = "Signal"
--- Constructs a new signal.
-- @constructor Signal.new()
-- @treturn Signal
function Signal.new()
local self = setmetatable({}, Signal)
self._bindableEvent = Instance.new("BindableEvent")
self._argData = nil
self._argCount = nil -- Prevent edge case of :Fire("A", nil) --> "A" instead of "A", nil
return self
end
function Signal.isSignal(object)
return typeof(object) == 'table' and getmetatable(object) == Signal;
end;
--- Fire the event with the given arguments. All handlers will be invoked. Handlers follow
-- Roblox signal conventions.
-- @param ... Variable arguments to pass to handler
-- @treturn nil
function Signal:Fire(...)
self._argData = {...}
self._argCount = select("#", ...)
self._bindableEvent:Fire()
self._argData = nil
self._argCount = nil
end
--- Connect a new handler to the event. Returns a connection object that can be disconnected.
-- @tparam function handler Function handler called with arguments passed when `:Fire(...)` is called
-- @treturn Connection Connection object that can be disconnected
function Signal:Connect(handler)
if not self._bindableEvent then return error("Signal has been destroyed"); end --Fixes an error while respawning with the UI injected
if not (type(handler) == "function") then
error(("connect(%s)"):format(typeof(handler)), 2)
end
return self._bindableEvent.Event:Connect(function()
handler(unpack(self._argData, 1, self._argCount))
end)
end
--- Wait for fire to be called, and return the arguments it was given.
-- @treturn ... Variable arguments from connection
function Signal:Wait()
self._bindableEvent.Event:Wait()
assert(self._argData, "Missing arg data, likely due to :TweenSize/Position corrupting threadrefs.")
return unpack(self._argData, 1, self._argCount)
end
--- Disconnects all connected events to the signal. Voids the signal as unusable.
-- @treturn nil
function Signal:Destroy()
if self._bindableEvent then
self._bindableEvent:Destroy()
self._bindableEvent = nil
end
self._argData = nil
self._argCount = nil
end
return Signal