Hello, I’m just a new guy who wanna try to use GoodSignal or similar to that, can you tell me what’s the benefit of using that custom Signal? Thank you.
GoodSignal claims to be nearly the same as roblox’s RBXScriptSignal. the bonus is it might help with debugging by giving a couple more steps on a stack frame, The downside is that roblox can implement their signals in C/C++ and will have very good performance that no signal plugin can match.
Excerpt from GoodSignal github
-- Batched Yield-Safe Signal Implementation --
-- 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. --
if you want to make your own event system you can also do something like this
local module = {}
module.__index = module
module.New = function()
local self = setmetatable({}, module)
self.callbacks = {}
end
module.Bind = function(self, callback)
local callbacks = {} -- if we are looping the old callbacks we don't want to break the order so instead of adding the callback directly we make brand new table
callbacks[callback] = true
for callback, value in pairs(self.callbacks) do
callbacks[callback] = true
end
self.callbacks = callbacks
end
module.UnBind = function(self, callback)
self.callbacks[callback] = nil -- its safe the remove callbacks directly so we don't need to make a new table like Bind
end
module.UnBindAll = function(self, function)
self.callbacks = {}
end
module.Call = function(self, ...)
for callback, value in pairs(self.callbacks) do
callback(...) -- if you don't want the callback to block the next callbacks you might want to task.spawn the function
end
end
return module
-- require the module above
local eventsModule = require(game.ReplicatedStorage.ModuleScript)
-- create a new event
local myCoolEvent = eventsModule.New()
-- bind a function to the event
myCoolEvent:Bind(function(value1, value2)
print("Bind1", value1, value2)
end)
-- bind a second function to the event
myCoolEvent:Bind(function(value1, value2)
print("Bind2", value1, value2)
end)
-- every 2 seconds call the event
while true do
task.wait(2)
myCoolEvent:Call("String Value", math.random(100))
end
or you could just use a BindableEvent
-- create a new event
local myCoolEvent = Instance.new("BindableEvent")
-- bind a function to the event
myCoolEvent.Event:Connect(function(value1, value2)
print("Bind1", value1, value2)
end)
-- bind a second function to the event
myCoolEvent.Event:Connect(function(value1, value2)
print("Bind2", value1, value2)
end)
-- every 2 seconds call the event
while true do
task.wait(2)
myCoolEvent:Fire("String Value", math.random(100))
end
Maybe people who just start scripting especially in Roblox will ask, what’s the difference using event connection compared to just writing a function, if it’s only used in the same script
The difference can depend on how you tell the roblox workspace to handle events, the differed events beta can be a helpful mental mapping as well as speed up events execution (Article here). If not differing events then it should behave largely the same as a function until a yeilding function call is reached, then execution should (hopefully) resume after the bindable event’s :Fire
call.
Gotta make sure the return self is before the end and it will work