RblxTimer, Timer Library
Introducing RblxTimer
What is RblxTimer?
- RblxTimer is a simple, small library, with full support for type-checking (Luau) designed by @Mubinets.
❔ Why should I use RblxTimer?
- Full Support For Typechecking!
- Designed with OOP in mind!
- Easy To Use!
- Listen for Events for Certain Actions (
OnStarted
,OnStopped
, etc) - Your bugs are my bugs! It will be maintained by me, for long time!
How To Use RblxTimer!
- Get the source code directly!
- Create new
ModuleScript
script inReplicatedStorage
or place of your choice - Paste the source code in the
ModuleScript
script. - Require the module and use!
How To Actually Use RblxTimer?
- Once you have required the module. You can start by creating a new timer. Here is the example:
local RblxTimer = require(...)
local timer : RblxTimer.Timer = RblxTimer.createTimer(60, 5) -- 60 Seconds with 5 Seconds interval
timer:start() -- Immediately starts the Timer object!
-- This function will run immediately for FIRST TIME and then ONCE every 5 seconds! (Interval)
timer.onElapsed:Connect(function(timerState : RblxTimer.TimerState)
print("The clock is ticking...")
end
timer.onFinished:Connect(function(timerState : RblxTimer.TimerState)
print("Round is starting!")
. . . -- The rest code.
end
Source Code
-- Author : Mubinet (@mubinets | 5220307661)
-- Date : 5/12/2024
-- Version : 1.0.1a
--!strict
------------ [[ ROBLOX SERVICES ]] ------------
local RunService = game:GetService("RunService")
------------ [[ USER MODULE ]] ------------
local RblxTimer = {} :: RblxTimer
------------ [[ USER TYPES ]] ------------
export type TimerStatus = "Pending" | "Running" | "Complete" | "Stopped" | "Paused"
--[[
An object that provides information about the result of the Timer object.
]]
export type TimerState = {
--[[
The value that is provided if the Timer object is either paused or stopped in time.
]]
remainingTime : number?,
--[[
The status value describing the current state of the Timer object.
]]
timerStatus : TimerStatus
}
--[[
An object representing the time in the game.
]]
export type Timer = {
--[[
The inital value in seconds in the construction of the Timer object.
]]
initalTime : number,
--[[
The event which fires on the completion of the timer, an TimerState object which provides information about the result will be given.
]]
onFinished : RBXScriptSignal<TimerState>,
--[[
The event which fires every interval of specified time. Defaults to 1 second internal if not specified
]]
onElapsed : RBXScriptSignal<TimerState>,
--[[
The event which fires when the Timer object has been stopped
]]
onStopped : RBXScriptSignal<TimerState>,
--[[
The event which fires when the Timer object has been paused
]]
onPaused : RBXScriptSignal<TimerState>,
--[[
The event which fires when the Timer object has been resumed
]]
onResumed : RBXScriptSignal<TimerState>,
--[[
The event which fires when the Timer object has started
]]
onStarted : RBXScriptSignal<TimerState>,
--[[
Returns the remaining time of the Timer object.
]]
getRemainingTime : (any) -> DateTime,
--[[
Stops the Timer object if not stopped already.
]]
stop : (any) -> TimerState,
--[[
Resumes the Timer object if it has been paused.
]]
resume : (any) -> TimerState,
--[[
Pauses the Timer object if not paused already.
]]
pause : (any) -> TimerState,
--[[
Starts the Timer object if not stopped already.
]]
start : (any) -> TimerState,
}
--[[
A user service for working with a timer object.
]]
export type RblxTimer = {
createTimer : (number, number?) -> Timer
}
------------ [[ MAIN ]] ------------
--[[
Creates a new object Timer with specified amount of time and optional interval in seconds.
]]
function RblxTimer.createTimer(seconds : number, interval: number?) : Timer
-- Definitions
local newTimerObject = {} :: Timer
local newElaspedBindableEvent = Instance.new("BindableEvent") :: BindableEvent
local newFinishedBindableEvent = Instance.new("BindableEvent") :: BindableEvent
local newStoppedBindableEvent = Instance.new("BindableEvent") :: BindableEvent
local newResumedBindableEvent = Instance.new("BindableEvent") :: BindableEvent
local newPausedBindableEvent = Instance.new("BindableEvent") :: BindableEvent
local newStartedBindableEvent = Instance.new("BindableEvent") :: BindableEvent
newTimerObject.onElapsed = newElaspedBindableEvent.Event
newTimerObject.onFinished = newFinishedBindableEvent.Event
newTimerObject.onStarted = newStartedBindableEvent.Event
newTimerObject.onPaused = newPausedBindableEvent.Event
newTimerObject.onStopped = newStoppedBindableEvent.Event
newTimerObject.onResumed = newResumedBindableEvent.Event
-- Object Private Constants
local DEFAULT_INTERVAL = 1 :: number
-- Object Private Properties
local _initalTime = seconds :: number
local _currentTime = seconds :: number
local _timeElapsed = 0 :: number
local _interval = interval or DEFAULT_INTERVAL :: number
local _currentTimerState = {} :: TimerState
local _isTicking = false :: boolean
-- Object Private Methods
local function _tick()
task.spawn(function()
local heartbeatConnection : RBXScriptConnection do
heartbeatConnection = RunService.Heartbeat:Connect(function(deltatime : number)
if not (_isTicking) then return end
_currentTime -= deltatime
_timeElapsed += deltatime
if (_currentTime <= 0) then
_currentTimerState.remainingTime = nil
_currentTimerState.timerStatus = "Complete"
_isTicking = false
newFinishedBindableEvent:Fire(_currentTimerState)
heartbeatConnection:Disconnect()
end
if (_timeElapsed >= _interval) then
_currentTimerState.remainingTime = math.round(_currentTime)
newElaspedBindableEvent:Fire(_currentTimerState)
_timeElapsed = 0
end
end)
end
end)
end
local function _toggleTick(tickingToggle : boolean)
if (_isTicking ~= tickingToggle) then
_isTicking = tickingToggle
if (tickingToggle == true) then
_tick()
end
end
end
-- Object Private Properties Initalization
_currentTimerState.remainingTime = _currentTime
_currentTimerState.timerStatus = "Pending"
-- Object Initalization
newTimerObject.initalTime = seconds
-- Methods Definition
newTimerObject.getRemainingTime = function() : DateTime
return DateTime.fromUnixTimestamp(_currentTime)
end
newTimerObject.start = function() : TimerState
if (_currentTimerState.timerStatus == "Pending") or (_currentTimerState.timerStatus == "Complete") or (_currentTimerState.timerStatus == "Stopped") then
_toggleTick(true)
_currentTime = _initalTime
_currentTimerState.remainingTime = _initalTime
_currentTimerState.timerStatus = "Running"
newStartedBindableEvent:Fire(_currentTimerState)
newElaspedBindableEvent:Fire(_currentTimerState)
return _currentTimerState
end
return _currentTimerState
end
newTimerObject.resume = function() : TimerState
if (_currentTimerState.timerStatus == "Paused") then
_toggleTick(true)
_currentTimerState.timerStatus = "Running"
newResumedBindableEvent:Fire(_currentTimerState)
return _currentTimerState
end
return _currentTimerState
end
newTimerObject.pause = function() : TimerState
if (_currentTimerState.timerStatus == "Running") then
_toggleTick(false)
_currentTimerState.timerStatus = "Paused"
newPausedBindableEvent:Fire(_currentTimerState)
return _currentTimerState
end
return _currentTimerState
end
newTimerObject.stop = function() : TimerState
if (_currentTimerState.timerStatus == "Running") or (_currentTimerState.timerStatus == "Paused") then
_toggleTick(false)
_currentTimerState.timerStatus = "Stopped"
newStoppedBindableEvent:Fire(_currentTimerState)
return _currentTimerState
end
return _currentTimerState
end
return newTimerObject
end
return RblxTimer
📜 Changelogs ( Latest: v.1.0.1 )
RblxTimer v1.0.1 Changelog
- Adjusted the time mechanic to be more accurate. This now uses
Heartbeat
to run the time mechanic. This is done to ensure prefect timing.
NOTE: This does not affect your code that uses the module. The change is backend, and therefore only affects the performance.
If you have any questions or issues, please let me know! I will be HAPPY to fix any issue.
/Mub