Created
November 20, 2021 00:33
-
-
Save lucasmz-dev/ea4bbd96b87915cbf539ff63d21f38c1 to your computer and use it in GitHub Desktop.
SimpleSignal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export type ScriptSignal = { | |
_active: boolean, | |
_head: ScriptConnection?, | |
IsActive: (ScriptSignal) -> boolean, | |
Connect: ( | |
ScriptSignal, | |
handler: (...any) -> () | |
) -> ScriptConnection, | |
Wait: (ScriptSignal) -> (...any), | |
Fire: (ScriptSignal, ...any) -> (), | |
DisconnectAll: (ScriptSignal) -> (), | |
Destroy: (ScriptSignal) -> (), | |
} | |
export type ScriptConnection = { | |
Connected: boolean, | |
Disconnect: (ScriptConnection) -> (), | |
_signal: ScriptSignal, | |
_handler: (...any) -> (), | |
_next: ScriptConnection?, | |
_previous: ScriptConnection?, | |
} | |
local function ScriptConnection( | |
signal: ScriptSignal, | |
handler: (...any) -> () | |
): ScriptConnection | |
local self = { | |
Connected = true, | |
_signal = signal, | |
_handler = handler, | |
_next = nil, | |
_previous = nil | |
} | |
function self:Disconnect() | |
if self.Connected ~= true then | |
return | |
end | |
self.Connected = false | |
local next = self._next | |
local previous = self._previous | |
if next ~= nil then | |
next._previous = previous | |
end | |
if previous ~= nil then | |
previous._next = next | |
else | |
self._signal._head = next | |
end | |
end | |
return self | |
end | |
local function ScriptSignal(): ScriptSignal | |
local self = { | |
_active = true, | |
_head = nil | |
} | |
function self:IsActive() | |
return self._active == true | |
end | |
function self:Connect(handler) | |
assert( | |
typeof(handler) == 'function', | |
"Must be function" | |
) | |
local connection = ScriptConnection(self, handler) | |
if self._active ~= true then | |
connection.Connected = false | |
return connection | |
end | |
local head = self._head | |
connection._next = head | |
if head ~= nil then | |
head._previous = connection | |
end | |
self._head = connection | |
return connection | |
end | |
function self:Wait() | |
local thread do | |
thread = coroutine.running() | |
local connection = nil | |
connection = self:Connect(function(...) | |
if connection == nil then | |
return | |
end | |
connection:Disconnect() | |
connection = nil | |
task.spawn(thread, ...) | |
end) | |
end | |
return coroutine.yield() | |
end | |
function self:Fire(...) | |
local connection = self._head | |
while connection ~= nil do | |
task.defer( | |
connection._handler, | |
... | |
) | |
connection = connection._next | |
end | |
end | |
function self:DisconnectAll() | |
local connection = self._head | |
while connection ~= nil do | |
connection.Connected = false | |
connection = connection._next | |
end | |
self._head = nil | |
end | |
function self:Destroy() | |
if self._active ~= true then | |
return | |
end | |
self._active = false | |
self:DisconnectAll() | |
end | |
return self | |
end | |
return ScriptSignal |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment