local function O(O,...)local Z={}local p=#O for p=1,p,1 do Z[p]=O[p]end for O=1,select("\035",...),1 do Z[p+O]=select(O,...)end return Z end local function Z(O,Z)local p={}for j=1,#O,1 do if O[j]~=Z then table.insert(p,O[j])end end return p end local p={}p.__index=p function p.new()local O={_listeners={}}setmetatable(O,p)return O end function p.connect(j,p)local N={callback=p,disconnected=false}j._listeners=O(j._listeners,N)local function T()N.disconnected=true j._listeners=Z(j._listeners,N)end return{disconnect=T}end function p.fire(O,...)for O,Z in ipairs(O._listeners)do if not Z.disconnected then Z.callback(...)end end end return p
--[[
	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