local h={}h.__index=h function h.Connect(O,h,k,V)local z={_listener=h,_script_signal=O,_disconnect_listener=k;_disconnect_param=V,_next=O._head;_is_connected=true}setmetatable(z,ScriptConnection)O._head=z O._listener_count+=1 return z end function h.GetListenerCount(h)return h._listener_count end function h.Fire(h,...)local k=h._head while k~=nil do if k._is_connected==true then if not FreeRunnerThread then FreeRunnerThread=coroutine.create(RunEventHandlerInFreeThread)end task.spawn(FreeRunnerThread,k._listener,...)end k=k._next end end function h.FireUntil(k,h,...)local V=k._head while V~=nil do if V._is_connected==true then V._listener(...)if h()~=true then return end end V=V._next end end function MadworkScriptSignal.NewScriptSignal()return{_head=nil;_listener_count=0;Connect=h.Connect,GetListenerCount=h.GetListenerCount,Fire=h.Fire;FireUntil=h.FireUntil}end return MadworkScriptSignal
-- ScriptSignal object:

local ScriptSignal = {
	--[[
		_head = nil,
		_listener_count = 0,
	--]]
}
ScriptSignal.__index = ScriptSignal

function ScriptSignal:Connect(listener, disconnect_listener, disconnect_param) --> [ScriptConnection]
	local script_connection = {
		_listener = listener,
		_script_signal = self,
		_disconnect_listener = disconnect_listener,
		_disconnect_param = disconnect_param,

		_next = self._head,
		_is_connected = true,
	}
	setmetatable(script_connection, ScriptConnection)

	self._head = script_connection
	self._listener_count += 1

	return script_connection
end

function ScriptSignal:GetListenerCount() --> [number]
	return self._listener_count
end

function ScriptSignal:Fire(...)
	local item = self._head
	while item ~= nil do
		if item._is_connected == true then
			if not FreeRunnerThread then
				FreeRunnerThread = coroutine.create(RunEventHandlerInFreeThread)
			end
			task.spawn(FreeRunnerThread, item._listener, ...)
		end
		item = item._next
	end
end

function ScriptSignal:FireUntil(continue_callback, ...)
	local item = self._head
	while item ~= nil do
		if item._is_connected == true then
			item._listener(...)
			if continue_callback() ~= true then
				return
			end
		end
		item = item._next
	end
end

function MadworkScriptSignal.NewScriptSignal() --> [ScriptSignal]
	return {
		_head = nil,
		_listener_count = 0,
		Connect = ScriptSignal.Connect,
		GetListenerCount = ScriptSignal.GetListenerCount,
		Fire = ScriptSignal.Fire,
		FireUntil = ScriptSignal.FireUntil,
	}
end

return MadworkScriptSignal
