Review On Custom Signal

Im making a custom Signal Class Module for my game, and I want to improve on it. What do you guys think I should add or change?

local signalService = {}

signalService.__index = signalService

type self = {
	Connections : {(any...) -> any...},
	Waiting : {(any...) -> any...}
}

export type Signal = typeof(setmetatable({} :: self, signalService))

function signalService.New() : Signal
	local newSignal = setmetatable({},signalService)
	
	newSignal.Connections = {}
	newSignal.Waiting = {}
	
	return newSignal
end

function signalService.Connect(self : Signal, listener : (any...) -> (any...) ) : (any...) -> (any...)
	table.insert(self.Connections,listener)
	return listener
end

function signalService.Fire(self : Signal, ... : any)
	if self.Connections[1] then --If there is atleast 1 connection, then fire connections.
		for index = #self.Connections, 1, -1 do
			local newThread = coroutine.create(self.Connections[index])
			coroutine.resume(newThread,...)
		end
	end
	
	if self.Connections[1] then
		for index = #self.Waiting, 1, -1 do
			coroutine.resume(self.Waiting[index],...)
			self.Waiting[index] = nil
		end
	end
	
end

function signalService.Wait(self : Signal)
	local thread = coroutine.running()
	table.insert(self.Waiting, thread)
	return coroutine.yield()
end

function signalService.Disconnect(self : Signal, listener : (any...) -> any...)
	for index = #self.Connections, 1, -1 do
		if listener == self.Connections[index] then
			table.remove(self.Connections, index)
		end
	end
end

function signalService.DisconnectAll(self : Signal)
	if self.Connections[1] then
		for index = #self.Connections, 1, -1 do
			table.remove(self.Connections, index)
		end
	end
	
	if self.Waiting[1] then
		for index = #self.Waiting, 1, -1 do
			table.remove(self.Connections, index)
		end
	end	
end

function signalService.Delete(self : Signal)
	signalService.DisconnectAll(self)
	self = nil
end

return signalService

You should use self properly. Instead of having it like this:

function signalService.Connect(self : Signal, listener : (any...) -> (any...) ) : (any...) -> (any...)
	table.insert(self.Connections,listener)
	return listener
end

Try using it like this:

function signalService:Connect(listener : (any...) -> (any...) ) : (any...) -> (any...)
	table.insert(self.Connections,listener)
	return listener
end

Self will be provided as the object which is called upon when using : to call the function. Replace all functions except the signalService.New function with a :

I would and did do this for my signal class, but ever since I have added Signal as its own type as well as a class, it requires me to use . instead of : in my code. But when using it you can use : on a Signal object and it will work perfectly fine. Thanks for the feedback though! :+1:

1 Like