-- Signal class


local Signal = {}
Signal.__index = Signal

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

function Signal:Connect(fn)
	local connection = Connection.new(self, fn)
	connection._next = (self._handlerListHead and self._handlerListHead) or connection._next
	self._handlerListHead = connection
	return connection
end

function Signal:Fire(...)
	local item = self._handlerListHead
	while item do
		if item._connected then
			if not freeRunnerThread then
				freeRunnerThread = coroutine.create(function(...)
					acquireRunnerThreadAndCallEventHandler(...)
					while true do
						acquireRunnerThreadAndCallEventHandler(coroutine.yield())
					end
				end)
			end
			task.spawn(freeRunnerThread, item._fn, ...)
		end
		item = item._next
	end
end

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

return Signal
