A few days ago I made a module script to work as a method to streamline using RemoteEvents by adding a channel argument to allow for all network traffic to go through one remote event. If someone can tell me if this is a good idea, please do tell me.
But my main focus was ways to improve my code’s organization. The bullet points below are my main key points I would like to be focused on. Other feedback is welcome as I might have missed things.
-
Is my
CommunicationService:Remove()
function properly handling the disposal of my custom object. -
Any spots I could use less
if
statements, especially in myCommunicationService:BroadcastServer()
andCommunicationService:BroadcastAllClients()
functions? -
Use of marking functions / properties that external scripts should not access when using the module. I can easily add functions for external scripts to access those private properties but I removed them to decrease the length of the script present as these functions are very simple and only take one line of code so optimization isn’t a concern.
I’ve noticed I forgot to add a Server > Single Client function. I will add that when I work any revisions.
Code Dropdown
local runService = game:GetService("RunService")
local IS_SERVER = runService:IsServer()
local remoteEvent = script:WaitForChild("Communication Service Remote Event")
local CommunicationService = {}
CommunicationService.__index = CommunicationService
CommunicationService.DEFUALT_CHANNEL_NAME = "Defualt"
CommunicationService.activeListeners = {}
function CommunicationService:NewListener(channel)
local channel = channel or CommunicationService.DEFUALT_CHANNEL_NAME
local newListener = setmetatable({},CommunicationService)
newListener._customEvent = Instance.new("BindableEvent")
newListener._activeChannel = channel
newListener._listenerLocation = CommunicationService._listenerLocation()
newListener.OnMessageRecived = newListener.customEvent.Event
table.insert(CommunicationService.activeListeners,newListener)
return newListener
end
function CommunicationService:Remove()
self._customEvent:Destroy()
table.remove(CommunicationService.activeListeners,table.find(self))
end
function CommunicationService:BroadcastServer(...)
if IS_SERVER then
warn("BroadcastServer must be called on a Client")
return
end
local args = {...}
local channel
local payload
if #args > 1 then
channel = tostring(args[1])
table.remove(args,1)
payload = args
else
channel = CommunicationService.DEFUALT_CHANNEL_NAME
payload = args[1]
end
remoteEvent:FireServer(channel,table.unpack(args))
end
function CommunicationService:BroadcastAllClients(...)
if not IS_SERVER then
warn("BroadcastServer must be called on a Client")
return
end
local args = {...}
local channel
local payload
if #args > 1 then
channel = tostring(args[1])
table.remove(args,1)
payload = args
else
channel = CommunicationService.DEFUALT_CHANNEL_NAME
payload = args[1]
end
remoteEvent:FireAllClients(channel,table.unpack(args))
end
function CommunicationService:SetDefualtChannelName(channelName)
if typeof(channelName) ~= "string" then
warn("Expected string got "..typeof(channelName).." when calling SetDefualtChannelName")
return
end
for _,listener in ipairs(CommunicationService.activeListeners) do
if listener._activeChannel == CommunicationService.DEFUALT_CHANNEL_NAME then
listener._activeChannel = channelName
end
end
CommunicationService.DEFUALT_CHANNEL_NAME = channelName
end
function CommunicationService._listenerLocation()
local locationName
if IS_SERVER then
locationName = "Server"
else
locationName = "Client"
end
return locationName
end
function CommunicationService._serverHandler(player,channel,...)
for _,listener in ipairs(CommunicationService.activeListeners) do
if listener._activeChannel == channel then
listener._customEvent:Fire(player,...)
end
end
end
function CommunicationService._clientHandler(channel,...)
for _,listener in ipairs(CommunicationService.activeListeners) do
if listener._activeChannel == channel then
listener._customEvent:Fire(...)
end
end
end
if IS_SERVER then
remoteEvent.OnServerEvent:Connect(CommunicationService._serverHandler)
else
remoteEvent.OnClientEvent:Connect(CommunicationService._clientHandler)
end
return CommunicationService