Clients/Client2018/content/LuaPackages/RoduxImpl/Signal.lua

75 lines
1.2 KiB
Lua

--[[
A limited, simple implementation of a Signal.
Handlers are fired in order, and (dis)connections are properly handled when
executing an event.
]]
local function immutableAppend(list, ...)
local new = {}
local len = #list
for key = 1, len do
new[key] = list[key]
end
for i = 1, select("#", ...) do
new[len + i] = select(i, ...)
end
return new
end
local function immutableRemoveValue(list, removeValue)
local new = {}
for i = 1, #list do
if list[i] ~= removeValue then
table.insert(new, list[i])
end
end
return new
end
local Signal = {}
Signal.__index = Signal
function Signal.new()
local self = {
_listeners = {}
}
setmetatable(self, Signal)
return self
end
function Signal:connect(callback)
local listener = {
callback = callback,
disconnected = false,
}
self._listeners = immutableAppend(self._listeners, listener)
local function disconnect()
listener.disconnected = true
self._listeners = immutableRemoveValue(self._listeners, listener)
end
return {
disconnect = disconnect
}
end
function Signal:fire(...)
for _, listener in ipairs(self._listeners) do
if not listener.disconnected then
listener.callback(...)
end
end
end
return Signal