Timer.lua (7367B)
1 -- Timer.lua - Timer library for LuajitOS 2 -- Provides simple and advanced timer functionality 3 -- Timers are namespaced by app: "com.dev.app-timer_name" 4 5 local Timer = {} 6 7 -- Internal storage for all active timers 8 local timers = {} 9 10 -- Current tick count (updated by kernel) 11 local currentTick = 0 12 13 -- Get current time in seconds 14 local function getTime() 15 return currentTick / 1000 -- Convert ms to seconds 16 end 17 18 -- Update tick count (called from kernel/main loop) 19 function Timer.setTick(tick) 20 currentTick = tick 21 end 22 23 -- Get current tick 24 function Timer.getTick() 25 return currentTick 26 end 27 28 -- Update all timers (should be called from main loop) 29 function Timer.update() 30 local currentTime = getTime() 31 local toRemove = {} 32 33 for name, timer in pairs(timers) do 34 if timer._running and timer._startTime then 35 local elapsed = currentTime - timer._startTime 36 if elapsed >= timer.interval then 37 -- Timer elapsed 38 if timer.onElapsed then 39 local success, err = pcall(timer.onElapsed, timer) 40 if not success and osprint then 41 osprint("Timer '" .. name .. "' onElapsed error: " .. tostring(err) .. "\n") 42 end 43 end 44 45 -- Handle repeats 46 if timer.repeats == true then 47 -- Infinite repeats 48 if timer.autoReset then 49 timer._startTime = currentTime 50 else 51 timer._running = false 52 end 53 elseif type(timer.repeats) == "number" and timer.repeats > 0 then 54 -- Decrement repeat count 55 timer.repeats = timer.repeats - 1 56 if timer.repeats > 0 then 57 if timer.autoReset then 58 timer._startTime = currentTime 59 else 60 timer._running = false 61 end 62 else 63 -- No more repeats, stop timer 64 timer._running = false 65 if not timer._keepAlive then 66 toRemove[#toRemove + 1] = name 67 end 68 end 69 else 70 -- No repeats (false, 0, or nil) 71 timer._running = false 72 if not timer._keepAlive then 73 toRemove[#toRemove + 1] = name 74 end 75 end 76 end 77 end 78 end 79 80 -- Remove completed non-keepalive timers 81 for _, name in ipairs(toRemove) do 82 timers[name] = nil 83 end 84 end 85 86 --- Create a simple one-shot timer 87 ---@param app_id string The app identifier (e.g., "com.luajitos.myapp") 88 ---@param timer_name string Timer name within the app 89 ---@param seconds number Delay in seconds 90 ---@param onElapsed function Callback when timer elapses 91 ---@return table Timer object 92 function Timer.simple(app_id, timer_name, seconds, onElapsed) 93 local full_name = app_id .. "-" .. timer_name 94 95 if timers[full_name] then 96 -- Remove existing timer with same name 97 timers[full_name] = nil 98 end 99 100 local timer = { 101 name = full_name, 102 interval = seconds, 103 autoReset = false, 104 repeats = false, 105 onElapsed = onElapsed, 106 _running = true, 107 _startTime = getTime(), 108 _keepAlive = false, 109 _app_id = app_id, 110 111 start = function(self) 112 self._running = true 113 self._startTime = getTime() 114 end, 115 116 reset = function(self) 117 self._startTime = getTime() 118 end, 119 120 stop = function(self) 121 self._running = false 122 end, 123 124 destroy = function(self) 125 timers[full_name] = nil 126 end 127 } 128 129 timers[full_name] = timer 130 return timer 131 end 132 133 --- Create a new configurable timer 134 ---@param app_id string The app identifier (e.g., "com.luajitos.myapp") 135 ---@param timer_name string Timer name within the app 136 ---@return table Timer object 137 function Timer.new(app_id, timer_name) 138 local full_name = app_id .. "-" .. timer_name 139 140 if timers[full_name] then 141 -- Remove existing timer with same name 142 timers[full_name] = nil 143 end 144 145 local timer = { 146 name = full_name, 147 interval = 1, 148 autoReset = false, 149 repeats = false, 150 onElapsed = nil, 151 _running = false, 152 _startTime = nil, 153 _keepAlive = true, -- Don't auto-remove on completion 154 _app_id = app_id, 155 156 start = function(self) 157 self._running = true 158 self._startTime = getTime() 159 end, 160 161 reset = function(self) 162 self._startTime = getTime() 163 end, 164 165 stop = function(self) 166 self._running = false 167 end, 168 169 destroy = function(self) 170 timers[full_name] = nil 171 end 172 } 173 174 timers[full_name] = timer 175 return timer 176 end 177 178 --- Remove a timer by app and name 179 ---@param app_id string The app identifier 180 ---@param timer_name string Timer name within the app 181 function Timer.remove(app_id, timer_name) 182 local full_name = app_id .. "-" .. timer_name 183 timers[full_name] = nil 184 end 185 186 --- Remove all timers for an app 187 ---@param app_id string The app identifier 188 function Timer.removeAll(app_id) 189 local prefix = app_id .. "-" 190 local toRemove = {} 191 for name, _ in pairs(timers) do 192 if name:sub(1, #prefix) == prefix then 193 toRemove[#toRemove + 1] = name 194 end 195 end 196 for _, name in ipairs(toRemove) do 197 timers[name] = nil 198 end 199 end 200 201 --- Get a timer by app and name 202 ---@param app_id string The app identifier 203 ---@param timer_name string Timer name within the app 204 ---@return table|nil Timer object or nil if not found 205 function Timer.get(app_id, timer_name) 206 local full_name = app_id .. "-" .. timer_name 207 return timers[full_name] 208 end 209 210 --- Get all timer names for an app 211 ---@param app_id string The app identifier 212 ---@return table Array of timer names (without app prefix) 213 function Timer.list(app_id) 214 local prefix = app_id .. "-" 215 local names = {} 216 for name, _ in pairs(timers) do 217 if name:sub(1, #prefix) == prefix then 218 names[#names + 1] = name:sub(#prefix + 1) 219 end 220 end 221 return names 222 end 223 224 --- Get all active timer names (full names) 225 ---@return table Array of full timer names 226 function Timer.listAll() 227 local names = {} 228 for name, _ in pairs(timers) do 229 names[#names + 1] = name 230 end 231 return names 232 end 233 234 --- Create a sandboxed Timer API for an app 235 ---@param app_id string The app identifier 236 ---@return table Sandboxed Timer API 237 function Timer.createAPI(app_id) 238 return { 239 simple = function(timer_name, seconds, onElapsed) 240 return Timer.simple(app_id, timer_name, seconds, onElapsed) 241 end, 242 243 new = function(timer_name) 244 return Timer.new(app_id, timer_name) 245 end, 246 247 remove = function(timer_name) 248 return Timer.remove(app_id, timer_name) 249 end, 250 251 get = function(timer_name) 252 return Timer.get(app_id, timer_name) 253 end, 254 255 list = function() 256 return Timer.list(app_id) 257 end 258 } 259 end 260 261 return Timer