75 lines
1.2 KiB
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 |