Skip to content

Instantly share code, notes, and snippets.

@cxmeel
Last active March 24, 2021 17:29
Show Gist options
  • Save cxmeel/6d8fab884248487b6ca22b6231ebdba7 to your computer and use it in GitHub Desktop.
Save cxmeel/6d8fab884248487b6ca22b6231ebdba7 to your computer and use it in GitHub Desktop.
Pure Lua Signal
--[[
Signal class in pure Lua.
Based on Roblox's BindableEvents.
Signal.new(): Signal
-- Creates a new Signal object
Signal:Connect(Callback: function): SignalConnection
-- Binds a function to invoke when the Signal is fired
SignalConnection:Disconnect(): nil
-- Unbinds the previously bound function
Signal:Fire(...args: any): nil
-- Invokes bound functions, passing the given arguments
Signal:Destroy(): nil
-- Unbinds all functions, and prevents the Signal from
being fired/connected to again
--]]
local Signal = {}; do
math.randomseed(os.time())
Signal.__index = Signal
function Signal.new()
local self = setmetatable({}, Signal)
self.__callbacks = {}
return self
end
function Signal:Connect(Callback)
local this = self
local CallbackId = math.random(1000000, 9999999)
this.__callbacks[CallbackId] = Callback
return {
Disconnect = function()
this.__callbacks[CallbackId] = nil
end
}
end
function Signal:Fire(...)
for _, callback in next, self.__callbacks do
coroutine.wrap(callback)(...)
end
end
function Signal:Destroy()
for key, _ in next, self.__callbacks do
self.__callbacks[key] = nil
end
self = setmetatable({})
self = nil
end
end
local Signal={}do math.randomseed(os.time())Signal.__index=Signal;function Signal.new()local self=setmetatable({},Signal)self.__callbacks={}return self end;function Signal:Connect(b)local c=self;local d=math.random(1000000,9999999)c.__callbacks[d]=b;return{Disconnect=function()c.__callbacks[d]=nil end}end;function Signal:Fire(...)for e,f in next,self.__callbacks do coroutine.wrap(f)(...)end end;function Signal:Destroy()for g,e in next,self.__callbacks do self.__callbacks[g]=nil;end;self=setmetatable({})self=nil end end
@cxmeel
Copy link
Author

cxmeel commented May 14, 2020

local TestEvent = Signal.new()

local TestEventConn; do
    TestEventConn = TestEvent:Connect(function(text)
        print("> Signal fired:", text)
        TestEventConn:Disconnect()
    end)
end

TestEvent:Fire("Hello, world!") --> Will print: "> Signal fired: Hello, world!"
TestEvent:Fire("Bye, world!") --> Won't fire, as it was disconnected when it was first fired

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment