local function Q()local Q={}local R={}local w=false local function S(S,u)assert(typeof(u)=="\102\117\110\099\116\105\111\110","\067\097\110 \111\110\108\121 \115\117\098\115\099\114\105\098\101 \116\111 \115\105\103\110\097\108\115 \119\105\116\104 \097 \102\117\110\099\116\105\111\110\046")local l={callback=u;disconnected=false}if w and not Q[u]then R[u]=l end Q[u]=l local function h()assert(not l.disconnected,"\076\105\115\116\101\110\101\114\115 \099\097\110 \111\110\108\121 \098\101 \100\105\115\099\111\110\110\101\099\116\101\100 \111\110\099\101\046")l.disconnected=true Q[u]=nil R[u]=nil end return h end local function u(S,...)w=true for Q,w in pairs(Q)do if not w.disconnected and not R[Q]then Q(...)end end w=false for Q,w in pairs(R)do R[Q]=nil end end return{subscribe=S;fire=u}end return Q
--[[
	This is a simple signal implementation that has a dead-simple API.

		local signal = createSignal()

		local disconnect = signal:subscribe(function(foo)
			print("Cool foo:", foo)
		end)

		signal:fire("something")

		disconnect()
]]

local function createSignal()
	local connections = {}
	local suspendedConnections = {}
	local firing = false

	local function subscribe(_self, callback)
		assert(typeof(callback) == "function", "Can only subscribe to signals with a function.")

		local connection = {
			callback = callback,
			disconnected = false,
		}

		-- If the callback is already registered, don't add to the suspendedConnection. Otherwise, this will disable
		-- the existing one.
		if firing and not connections[callback] then
			suspendedConnections[callback] = connection
		end

		connections[callback] = connection

		local function disconnect()
			assert(not connection.disconnected, "Listeners can only be disconnected once.")

			connection.disconnected = true
			connections[callback] = nil
			suspendedConnections[callback] = nil
		end

		return disconnect
	end

	local function fire(_self, ...)
		firing = true
		for callback, connection in pairs(connections) do
			if not connection.disconnected and not suspendedConnections[callback] then
				callback(...)
			end
		end

		firing = false

		for callback, _ in pairs(suspendedConnections) do
			suspendedConnections[callback] = nil
		end
	end

	return {
		subscribe = subscribe,
		fire = fire,
	}
end

return createSignal
