Best approach for server-side timers: OOP vs simple loops?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

  2. What is the issue? Include screenshots / videos if possible!

  3. What solutions have you tried so far? Did you look for solutions on the Creator Hub?

What is the issue?

I’ve created two different approaches and I’m unsure which one is better for Roblox server performance and code maintainability:

  1. OOP approach - Timer class with methods (Start, Stop, IsRunning) and callbacks
  2. Simple approach - Table with flags and for loops
local RunService = game:GetService("RunService")

local Timer = {}
Timer.__index = Timer

function Timer.new(interval, OnTick, OnCompleted)
	local self = setmetatable({},Timer)
	
	if not interval or interval <=0 then error("Must be a Valid Interval") end
	
	
	self.Interval = interval
	self.OnTick = OnTick or function() end 
	self.Running = false
	self.OnCompleted = OnCompleted or function() end
	self._runHandle = nil
	self.Signal = RunService.Heartbeat
	
	return self
end

function Timer:_startTimer()
	
	self.Running = true
	local t = os.clock()
	local endTime = t + self.Interval
	local LastSecondLeft
	local NextTick = t
	self._runHandle = self.Signal:Connect(function()
		local now = os.clock()
		
		--When Finish
		if now>= endTime then
			self:Stop()
			pcall(function()
				self.OnTick(0)
				return true
			end)
			pcall(function()
				self.OnCompleted()
				return true
			end)
			
			return
		end
		
		--EverySecond
		if now >= NextTick then
			local secondsLeft = math.ceil(endTime-now)
			if LastSecondLeft == secondsLeft then return end 
			LastSecondLeft = secondsLeft
			pcall(self.OnTick(secondsLeft))
			NextTick +=1
		end
		
		
	end)
end

function Timer:Start()
	if self.Running then 
		return
	end
	
	self:_startTimer()
end

function Timer:Stop()
	self.Running = false
	if self._runHandle then
		self._runHandle:Disconnect()
		self._runHandle = nil
	end
end

function Timer:isRunning()
	return self.Running
end

return Timer

1 Like