Skip to content

Instantly share code, notes, and snippets.

@cxmeel
Last active September 8, 2020 17:55
Show Gist options
  • Save cxmeel/bc8c5e1cefe7dd9f75d9f8a6ed7a1a9c to your computer and use it in GitHub Desktop.
Save cxmeel/bc8c5e1cefe7dd9f75d9f8a6ed7a1a9c to your computer and use it in GitHub Desktop.
Handles running time-based events in Roblox
--[[
EventHandler by csqrl (ClockworkSquirrel)
Version: 0.0.2
Documentation:
EventHandler.new(EventLength: number): Handler
Methods:
Handler:Start(): void
Handler:Pause(): void
Handler:Resume(): void
Handler:Stop(): void
Handler:Destroy(): void
Properties:
Handler.Length: number
Handler.Running: boolean
Handler.IsPaused: boolean
Handler.TimeRemaining: number
Events:
Handler.Started(TimeRemaining: number, EventLength: number): RawSignal
Handler.Progressed(TimeRemaining: number, EventLength: number): RawSignal
Handler.Paused(TimeRemaining: number, EventLength: number): RawSignal
Handler.Resumed(TimeRemaining: number, EventLength: number): RawSignal
Handler.Ended(TimeRemaining: number, EventLength: number): RawSignal
--]]
local Signal = {}; do
Signal.__index = Signal
function Signal.new()
local self = setmetatable({}, Signal)
self.__callbackInt = 0
self.__callbacks = {}
return self
end
function Signal:Connect(Callback)
local this = self
this.__callbackInt = this.__callbackInt + 1
local CallbackId = tostring(this.__callbackInt)
this.__callbacks[CallbackId] = Callback
return {
Disconnect = function()
this.__callbacks[CallbackId] = nil
end
}
end
function Signal:Fire(...)
for _, callback in next, self.__callbacks do
coroutine.wrap(callback)(...)
end
end
function Signal:Destroy()
for key, _ in next, self.__callbacks do
self.__callbacks[key] = nil
end
self = setmetatable({}, true)
end
end
local RunService = game:GetService("RunService")
local EventHandler = {}
EventHandler.__index = EventHandler
function EventHandler.new(EventLength: number)
local self = setmetatable({}, EventHandler)
self.Length = EventLength
self.Running = false
self.IsPaused = false
self.TimeRemaining = 0
self.__Bindables = {
Started = Signal.new(),
Ended = Signal.new(),
Progressed = Signal.new(),
Paused = Signal.new(),
Resumed = Signal.new(),
}
self.Started = self.__Bindables.Started
self.Ended = self.__Bindables.Ended
self.Progressed = self.__Bindables.Progressed
self.Paused = self.__Bindables.Paused
self.Resumed = self.__Bindables.Resumed
return self
end
function EventHandler:__FireEvent(EventName, ...)
self.__Bindables[EventName]:Fire(self.TimeRemaining, self.Length, ...)
end
function EventHandler:__GetHeartbeatConnection()
return function()
if self.IsPaused or self.__StopRequested then
return
end
if os.time() - self.__LastTick < 1 then
return
end
if self.TimeRemaining <= 0 then
self.__StopRequested = true
self:Stop()
return
end
self.TimeRemaining -= 1
self.__LastTick = os.time()
self:__FireEvent("Progressed")
end
end
function EventHandler:Start()
if self.IsPaused then
self.IsPaused = false
self:__FireEvent("Resumed")
return
end
if self.Running then
return warn("event is already running")
end
self.Running = true
self.TimeRemaining = self.Length
self.__LastTick = os.time()
self.__heartbeatConnection = RunService.Heartbeat:Connect(self:__GetHeartbeatConnection())
self:__FireEvent("Started")
end
function EventHandler:Pause()
self.IsPaused = true
self:__FireEvent("Paused")
end
function EventHandler:Stop()
if not self.Running then
return warn("event is not running")
end
self.__StopRequested = true
if self.__heartbeatConnection then
self.__heartbeatConnection:Disconnect()
end
self.TimeRemaining = 0
self.Running = false
self.IsPaused = false
self:__FireEvent("Ended")
end
function EventHandler:Destroy()
self:Stop()
if self.__heartbeatConnection then
self.__heartbeatConnection:Destroy()
end
for _, Bindable in next, self.__Bindables do
Bindable:Destroy()
end
end
EventHandler.Resume = EventHandler.Start
return EventHandler
local Handler = EventHandler.new(300) -- Event length in seconds
Handler.Progressed:Connect(function(TimeRemaining, EventLength)
if TimeRemaining == 60 then
print("Hurry! Only 1 minute left!")
end
end)
Handler.Ended:Connect(function()
print("Event has ended!")
end)
Handler:Start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment