GoodSignal
Batched Yield-Safe Signal Implementation
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.
This class is designed to work both in deferred mode and in regular mode. It follows whatever mode is set.
local signal = Signal.new()
local arg = {}
signal:Connect(function(value)
assert(arg == value, "Tables are preserved when firing a Signal")
end)
signal:Fire(arg)
info
Why this over a direct BindableEvent? Well, in this case, the signal prevents Roblox from trying to serialize and desialize each table reference fired through the BindableEvent.
This is a Signal class which has effectively identical behavior to a normal RBXScriptSignal, with the only difference being a couple extra stack frames at the bottom of the stack trace when an error is thrown This implementation caches runner coroutines, so the ability to yield in the signal handlers comes at minimal extra cost over a naive signal implementation that either always or never spawns a thread.
Author notes: stravant - July 31st, 2021 - Created the file. Quenty - Auguest 21st, 2023 - Modified to fit Nevermore contract, with Moonwave docs