local Y={}Y.__index=Y local n={}n.__index=n function n.new(Y,o)return setmetatable({_handler=o,_signal=Y},n)end function n.Disconnect(Y)Y._signal[Y]=nil end function Y.new()return setmetatable({},Y)end function Y.Connect(o,Y)local C=n.new(o,Y)o[C]=true return C end function Y.DisconnectAll(Y)table.clear(Y)end function Y.Fire(Y,...)if next(Y)then for Y,n in pairs(Y)do Y._handler(...)end end end function Y.Wait(Y)local n=coroutine.running()local o o=Y:Connect(function(...)o:Disconnect()task.spawn(n,...)end)return coroutine.yield()end function Y.Once(n,Y)local o o=n:Connect(function(...)o:Disconnect()Y(...)end)return o end return Y
--------------------------------------------------------------------------------
--                           Fast Signal-like class                           --
-- This is a Signal class that is implemented in the most performant way      --
-- possible, sacrificing correctness. The event handlers will be called       --
-- directly, so it is not safe to yield in them, and it is also not safe to   --
-- connect new handlers in the middle of a handler (though it is still safe   --
-- for a handler to specifically disconnect itself)                           --
--------------------------------------------------------------------------------

local Signal = {}
Signal.__index = Signal

local Connection = {}
Connection.__index = Connection

function Connection.new(signal, handler)
	return setmetatable({
		_handler = handler,
		_signal = signal,
	}, Connection)
end

function Connection:Disconnect()
	self._signal[self] = nil
end

function Signal.new()
	return setmetatable({}, Signal)
end

function Signal:Connect(fn)
	local connection = Connection.new(self, fn)
	self[connection] = true
	return connection
end

function Signal:DisconnectAll()
	table.clear(self)
end

function Signal:Fire(...)
	if next(self) then
		for handler, _ in pairs(self) do
			handler._handler(...)
		end
	end
end

function Signal:Wait()
	local waitingCoroutine = coroutine.running()
	local cn
	cn = self:Connect(function(...)
		cn:Disconnect()
		task.spawn(waitingCoroutine, ...)
	end)
	return coroutine.yield()
end

function Signal:Once(fn)
	local cn
	cn = self:Connect(function(...)
		cn:Disconnect()
		fn(...)
	end)
	return cn
end

return Signal
