Skip to content

Instantly share code, notes, and snippets.

@lucasmz-dev
Last active September 21, 2021 22:55
Show Gist options
  • Save lucasmz-dev/bac314776e02c3f1381acadfe368481d to your computer and use it in GitHub Desktop.
Save lucasmz-dev/bac314776e02c3f1381acadfe368481d to your computer and use it in GitHub Desktop.
Stamper
--[[
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