From 2e1325c429c09537e4fffa39fe80ea83f661e67b Mon Sep 17 00:00:00 2001 From: Rose Liverman Date: Tue, 22 Sep 2026 15:43:25 -0600 Subject: [PATCH] forgot to add timer library --- src/lib/timer.lua | 76 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/lib/timer.lua diff --git a/src/lib/timer.lua b/src/lib/timer.lua new file mode 100644 index 0000000..204f40c --- /dev/null +++ b/src/lib/timer.lua @@ -0,0 +1,76 @@ +local is_callable = function(callback) + local _type = type(callback) + if _type == "function" then return true end + of _type == "table" then + local metatable = getmetatable(callback) + return (type(metatable) == "table") and (type(metatable.__call) == "function") + end +end + +local update_after = function(self, delta) + if self.run_time >= self.deadline then return true end + self.run_time = self.run_time + delta + if self.run_time >= self.deadline then + self.callback(unpack(self.args)) + return true + end +end + +local update_every = function(self, delta) + self.run_time = self.run_time + delta + while self.run_time >= self.interval do + self.callback(unpack(self.args)) + self.run_time = self.run_time - self.interval + end +end + +local timer_metatable = { + __index = { + reset = function(self, time) + self.run_time = time or 0 + end, + }, +} + +local timers = {} + +local new_timer = function(callback, update, ...) + assert(is_callable(callback), "callback function must be callable") + + local timer = setmetatable({ + callback = callback, + update = update, + args = {...}, + run_time = 0, + }, timer_metatable) + + timers[timer] = timer + return timer +end + +return { + after = function(deadline, callback, ...) + local timer = new_timer(callback, update_after, ...) + timer.deadline = deadline + return timer + end, + every = function(interval, callback, ...) + local timer = new_timer(callback, update_every, ...) + timer.interval = interval + return timer + end, + update = function(delta) + local expired = {} + for timer in pairs(timers) do + if not timer.manual then + if timer:update(delta) then + expired[timer] = true + end + end + end + for timer in pairs(expired) do + timers[timer] = nil + end + return expired + end, +}