local function C()local C={}local Q={}local A=false local function m(m,L)assert(typeof(L)=="\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 Y={callback=L;disconnected=false}if A and not C[L]then Q[L]=Y end C[L]=Y local function q()assert(not Y.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")Y.disconnected=true C[L]=nil Q[L]=nil end return q end local function L(m,...)A=true for C,A in pairs(C)do if not A.disconnected and not Q[C]then C(...)end end A=false for C,A in pairs(Q)do Q[C]=nil end end return{subscribe=m;fire=L}end return C


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
