Last active
September 8, 2020 17:55
-
-
Save cxmeel/bc8c5e1cefe7dd9f75d9f8a6ed7a1a9c to your computer and use it in GitHub Desktop.
Handles running time-based events in Roblox
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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