A simple and usefull module to create signals without use bindable events, with a lot of usefull features
Features:
Gonna list the extra features, Connect,Disconnect and Fire are already expected from a signal module.
ConnectMultiple: You can connect multiple functions at same time,
ConnectOnce: You can connect a function that will be auto disconnected after triggered, you can also have a Condition function on it, to avoid disconnect if the Condition is false.
DisconnectAll: Disconnect all functions on that signal
FireOnce: Wil fire the signal once than disconnect all functions
Destroy: Will completly remove signal from existence
GetSignal: You can get the signal you created from any local, making ez to connect functions from different modules / scripts
Why use it over others Signals modules?
It have extra usefull utilitys, its also almost fast as the fastest signal module right now (GoodSignal) loosing for few mileseconds
i made a test with x1000 (for i=1,1000) to FireAll with Connect
and i try to make my self signal with same option like above on test
the Finish is longer because i add :Wait function here
local oneSignal = {}
oneSignal.ClassName = "oneSignal"
oneSignal.__index = oneSignal
local Collections = {}
function oneSignal.new(identifier)
assert(typeof(identifier) == "string", "[oneSignal]: Identifier must be string")
assert(not Collections[identifier], string.format("[oneSignal]: %s already exist", identifier))
Collections[identifier] = setmetatable({
cb = nil,
Connected = false,
Identifier = identifier,
_ping = nil,
}, oneSignal)
return Collections[identifier]
end
function oneSignal.get(identifier)
assert(Collections[identifier], string.format("[oneSignal]: %s not exist", identifier))
return Collections[identifier]
end
function oneSignal:Connect(callback)
if self then
assert(not self.Connected, string.format("[oneSignal]: %s already connected", self.Identifier))
self.cb = callback
self.Connected = true
end
end
function oneSignal:Wait()
if self then
local thread = coroutine.running()
local clock = os.clock()
self._ping = function(x)
task.spawn(thread, x - clock)
self._ping = nil
end
return coroutine.yield()
end
end
function oneSignal:Once(callback)
if self and not self.Connected then
self.cb = function(...)
self:Disconnect()
task.spawn(callback, ...)
end
self.Connected = true
end
end
function oneSignal:Disconnect()
if self and self.Connected then
self.Connected = false
self.cb = nil
end
end
function oneSignal:Destroy()
self:Disconnect()
if self then
Collections[self.Identifier] = nil
self = nil
end
end
function oneSignal:Fire(...)
if self then
if self.Connected then
task.spawn(self.cb, ...)
end
if self._ping then
task.spawn(self._ping, os.clock())
end
end
end
return table.freeze(oneSignal)
i use os.clock here for more precist and save the finish time estimate so no time loss here
ms is miliseconds (1e3)
µs is microseconds (1e6)
ns is nanoseconds (1e9)
local One = require(script.Parent:WaitForChild("oneSignal"))
local test1 = One.new("test")
test1:Once(function()
print(test1:Wait()*1e6)
end)
task.wait(3)
test1:Fire()
test1:Fire()
Wait you are just connection one function on the signal, Means you doenst need loop It, i connect multiple functions on same signal, Means i loop It, idk why you make one signal Just be able to have 1 connection, seens not reliable
u finished the loop faster because in ur Fire function only do once callback, but in my funvtion does callback and ping, ping for :Wait function. but in Avg received ur later, avg receive is when the fire is reached to callback and received