Warp/src/Index/Signal/init.luau

83 lines
1.7 KiB
Lua
Raw Normal View History

2024-01-31 06:33:19 +00:00
--!strict
--!native
local Signal = {}
Signal.__index = Signal
local DedicatedSignal = require(script.Dedicated)
local Util = script.Parent.Util
local Key = require(Util.Key)
local Assert = require(Util.Assert)
local Signals = {}
function Signal.new(Identifier: string)
Assert(typeof(Identifier) == "string", `[Signal]: Identifier must be a string type, got {typeof(Identifier)}`)
if not Signals[Identifier] then
local signal = setmetatable({}, Signal)
Signals[Identifier] = signal
return signal
end
return Signals[Identifier]
end
function Signal:Connect(fn: (...any) -> ()): string
local key = tostring(Key())
self[key] = DedicatedSignal(self, fn)
return key
end
function Signal:Once(fn: (...any) -> ()): string
local key: string
key = self:Connect(function(...)
self:Disconnect(key)
task.spawn(fn, ...)
end)
return key
end
function Signal:Disconnect(key: string)
self[key]:Disconnect()
end
function Signal:DisconnectAll(): ()
table.clear(self)
end
function Signal:Wait(): number
local thread, t = coroutine.running(), os.clock()
self:Once(function()
task.spawn(thread, os.clock()-t)
end)
return coroutine.yield()
end
function Signal:Fire(...: any): ()
for _, handle in self do
pcall(handle.fn, ...)
end
end
function Signal:FireTo(signal: string, ...: any): ()
local to = Signals[signal]
if not to then return end
Signal.Fire(to, ...)
end
function Signal:Invoke(key: string, ...: any): ()
local to = self[key]
if not to then return end
return to.fn(...)
end
function Signal:InvokeTo(signal: string, key: string, ...: any): ()
if not Signals[signal] then return end
return Signal.Invoke(Signals[signal], ...)
end
function Signal:Destroy(): ()
self:DisconnectAll()
setmetatable(self, nil)
end
return Signal.new :: typeof(Signal.new)