To use this module, copy this code below:
local freeThreads: { thread } = {}
local function runCallback<T...>(callback: (T...) -> (), thread: thread, ...: T...)
callback(...)
table.insert(freeThreads, thread)
end
local function yielder()
while true do
runCallback(coroutine.yield())
end
end
local function spawn<T...>(callback: (T...) -> (), ...: T...)
local thread: thread
if #freeThreads > 0 then
thread = freeThreads[#freeThreads]
freeThreads[#freeThreads] = nil
else
thread = coroutine.create(yielder)
coroutine.resume(thread)
end
task.spawn(thread, callback, thread, ...)
end
type SignalNode<T...> = {
callback: (T...) -> (),
next: SignalNode<T...>?,
}
type SignalData<T...> = {
root: SignalNode<T...>?,
}
local function disconnect<T...>(self: SignalData<T...>, node: SignalNode<T...>)
if self.root == node then
self.root = node.next
else
local current = self.root
while current do
if current.next == node then
current.next = node.next
break
end
current = current.next
end
end
end
export type Signal<T...> = {
connect: (callback: (T...) -> ()) -> () -> (),
disconnectAll: () -> (),
fire: (T...) -> (),
once: (callback: (T...) -> ()) -> () -> (),
wait: () -> T...,
}
local function Signal<T...>(): Signal<T...>
local self: SignalData<T...> = {}
local function connect(callback: (T...) -> ()): () -> ()
local node: SignalNode<T...> = {
callback = callback,
next = self.root,
}
self.root = node
return function()
disconnect(self, node)
end
end
local function disconnectAll()
self.root = nil
end
local function fire(...: T...)
local current = self.root
while current do
spawn(current.callback, ...)
current = current.next
end
end
local function once(callback: (T...) -> ()): () -> ()
local unsubscribe: () -> ()
unsubscribe = connect(function(...)
unsubscribe()
callback(...)
end)
return unsubscribe
end
local function wait(): T...
local thread = coroutine.running()
once(function(...)
task.spawn(thread, ...)
end)
return coroutine.yield()
end
return {
connect = connect,
disconnectAll = disconnectAll,
fire = fire,
once = once,
wait = wait,
}
end
return Signal
Why SimpleSignal?:
- Faster method call, why call
:
instead of.
? - Explicit type check.
- No more ugly intellisense like
__index