Skip to content

Commit eeef255

Browse files
authored
Update Signal.lua
1 parent aa65176 commit eeef255

File tree

1 file changed

+63
-71
lines changed

1 file changed

+63
-71
lines changed

src/ReplicatedStorage/Signal.lua

Lines changed: 63 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,6 @@
7878
7979
]]
8080

81-
local c_running = coroutine.running
82-
local c_yield = coroutine.yield
83-
local t_defer = task.defer
84-
local t_desynchronize = task.desynchronize
85-
8681
local ERROR_ON_ALREADY_DISCONNECTED = false
8782

8883
local Signal = {}
@@ -91,64 +86,66 @@ Signal.__index = Signal
9186
local Connection = {}
9287
Connection.__index = Connection
9388

89+
function Signal:__call(_, ...)
90+
if not self:IsActive() then
91+
return
92+
end
93+
94+
return self:Connect(...)
95+
end
96+
9497
function Signal.new()
9598
local self = setmetatable({
96-
[1] = nil, -- _head
97-
[2] = true -- _active
99+
_active = true,
100+
_head = nil
98101
}, Signal)
99102

100103
return self
101104
end
102105

103106
function Signal:IsActive()
104-
return self[2] == true
107+
return self._active == true
105108
end
106109

107-
local function Connect(self, func, self_disconnects)
110+
function Signal:Connect(func)
111+
assert(
112+
typeof(func) == 'function',
113+
":Connect must be called with a function"
114+
)
115+
108116
if not self:IsActive() then
109117
return setmetatable({
110118
Connected = false
111119
}, Connection)
112120
end
113121

114-
local _head = self[1]
115-
116122
local connection = setmetatable({
117123
Connected = true,
118-
[1] = func, -- _func
119-
[2] = self, -- _signal
120-
[3] = _head, -- _next
121-
[4] = nil, -- _prev
122-
[5] = self_disconnects -- _self_disconnects
124+
_func = func,
125+
_signal = self,
126+
_next = nil,
127+
_prev = nil
123128
}, Connection)
124129

130+
local _head = self._head
125131
if _head ~= nil then
126-
_head[4] = connection -- _head._prev = connection
127-
connection[3] = _head -- connection._next = _head
132+
_head._prev = connection
133+
connection._next = _head
128134
end
129135

130-
self[1] = connection -- _head = connection
136+
self._head = connection
131137

132138
return connection
133139
end
134140

135-
function Signal:Connect(func)
136-
assert(
137-
typeof(func) == 'function',
138-
":Connect must be called with a function"
139-
)
140-
141-
return Connect(self, func)
142-
end
143-
144141
function Signal:ConnectParallel(func)
145142
assert(
146143
typeof(func) == 'function',
147144
":ConnectParallel must be called with a function"
148145
)
149146

150-
return Connect(self, function(...)
151-
t_desynchronize()
147+
return self:Connect(function(...)
148+
task.desynchronize()
152149
func(...)
153150
end)
154151
end
@@ -164,37 +161,48 @@ function Connection:Disconnect()
164161

165162
self.Connected = false
166163

167-
local _next = self[3]
168-
local _prev = self[4]
164+
local _next = self._next
165+
local _prev = self._prev
169166

170167
if _next ~= nil then
171-
_next[4] = _prev -- _next._prev = _prev
168+
_next._prev = _prev
172169
end
173170

174171
if _prev ~= nil then
175-
_prev[3] = _next -- _prev._next = _next
172+
_prev._next = _next
176173
else
177174
--\\ This connection was the _head,
178175
-- therefore we need to update the head
179176
-- to the connection after this one.
180177

181-
self[2][1] = _next -- self._signal._head = _next
178+
self._signal._head = _next
182179
end
183180

184181
--\\ Safe to wipe references to:
185182

186-
self[2] = nil
187-
self[4] = nil
183+
self._signal = nil
184+
self._prev = nil
188185
end
189186

190187
function Signal:Wait()
191-
Connect(
192-
self,
193-
c_running(),
194-
true
195-
)
188+
if not self:IsActive() then
189+
warn("Tried to :Wait on destroyed signal")
190+
return
191+
end
192+
193+
local thread = coroutine.running()
194+
195+
local connection
196+
connection = self:Connect(function(...)
197+
connection:Disconnect()
196198

197-
return c_yield()
199+
task.spawn(
200+
thread,
201+
...
202+
)
203+
end)
204+
205+
return coroutine.yield()
198206
end
199207

200208
function Signal:Fire(...)
@@ -203,54 +211,38 @@ function Signal:Fire(...)
203211
return
204212
end
205213

206-
local connection = self[1]
214+
local connection = self._head
207215
while connection ~= nil do
208-
t_defer(
209-
connection[1],
216+
task.defer(
217+
connection._func,
210218
...
211219
)
212-
213-
if connection[5] then
214-
-- If connection is one-fire only:
215-
connection:Disconnect()
216-
end
217220

218-
connection = connection[3] --> _next
221+
connection = connection._next
219222
end
220223
end
221224

222225
function Signal:DisconnectAll()
223-
local connection = self[1] -- _head
226+
local connection = self._head
224227
while connection ~= nil do
228+
--connection:Disconnect()
229+
225230
connection.Connected = false
226-
connection[2] = nil -- _signal = nil
227-
connection[4] = nil -- _prev = nil
231+
connection._prev = nil
232+
connection._signal = nil
228233

229-
connection = connection[3] --> _next
234+
connection = connection._next
230235
end
231-
self[1] = nil -- _head = nil
236+
self._head = nil
232237
end
233238

234239
function Signal:Destroy()
235240
if not self:IsActive() then
236241
return
237242
end
238243

239-
self[2] = false
244+
self._active = false
240245
self:DisconnectAll()
241246
end
242247

243-
function Signal:__call(_, func)
244-
if not self:IsActive() then
245-
return
246-
end
247-
248-
assert(
249-
typeof(func) == 'function',
250-
":Connect must be called with a function"
251-
)
252-
253-
return Connect(self, func)
254-
end
255-
256248
return Signal

0 commit comments

Comments
 (0)