Last active
September 21, 2021 22:55
-
-
Save lucasmz-dev/bac314776e02c3f1381acadfe368481d to your computer and use it in GitHub Desktop.
Stamper
This file contains 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
--[[ | |
Stamper.lua: | |
Stamper is a hyper-efficient library made for handling functions | |
that should run every x amount of seconds, | |
With multiple functions, this process can usually cause | |
lag, stamper fixes this, by handling it all in one connection / thread, | |
with custom scheduling! | |
]] | |
local RunService: RunService = game:GetService("RunService") | |
type CallbackFunction = (deltaTime: number) -> () | |
type EventNode = { | |
TimeOfLastUpdate: number, | |
Seconds: number, | |
Callback: CallbackFunction, | |
Next: EventNode?, | |
Previous: EventNode? | |
} | |
local TimePassed: number = 0 | |
local NextEvent: EventNode? = nil | |
local Connection = {} | |
Connection.Connected = true | |
Connection.__index = Connection | |
function Connection:Disconnect() | |
if self.Connected == false then | |
return | |
end | |
self.Connected = false | |
local _node: EventNode = self._node | |
local _next: EventNode? = _node.Next | |
local _prev: EventNode? = _node.Previous | |
if _next then | |
_next.Previous = _prev | |
end | |
if _prev then | |
_prev.Next = _next | |
else -- _node is 'NextEvent' | |
NextEvent = _next | |
end | |
self._node = nil | |
end | |
export type Connection = typeof( | |
setmetatable({}, Connection) | |
) | |
RunService.Heartbeat:Connect(function(frameDeltaTime: number) | |
TimePassed += frameDeltaTime | |
local node: EventNode? = NextEvent | |
while node ~= nil do | |
local deltaTime: number = TimePassed - node.TimeOfLastUpdate | |
if deltaTime >= node.Seconds then | |
node.TimeOfLastUpdate = TimePassed | |
task.defer( | |
node.Callback, | |
deltaTime | |
) | |
end | |
node = node.Next | |
end | |
end) | |
return function( | |
seconds: number, | |
callback: CallbackFunction | |
): Connection | |
assert( | |
typeof(seconds) == 'number', | |
"Seconds must be a number" | |
) | |
assert( | |
typeof(callback) == 'function', | |
"Handler must be a function" | |
) | |
local thisEvent: EventNode = { | |
TimeOfLastUpdate = TimePassed, | |
Seconds = seconds, | |
Callback = callback, | |
Next = NextEvent, | |
Previous = nil | |
} | |
if NextEvent then | |
NextEvent.Previous = thisEvent | |
end | |
NextEvent = thisEvent | |
return setmetatable({ | |
Connected = true, | |
_node = thisEvent | |
}, Connection) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment