BatterUp/src/action-queue.lua

51 lines
1.6 KiB
Lua

---@alias ActionResult {}
---@type table<string, ActionResult>
-- selene: allow(unscoped_variables)
ActionResult = {
Succeeded = {},
Failed = {},
NeedsMoreTime = {},
}
-- selene: allow(unscoped_variables)
actionQueue = {
---@type ({ action: Action, expireTimeMs: number })[]
queue = {},
}
---@alias Action fun(deltaSeconds: number): ActionResult
--- Added actions will be called on every runWaiting() update.
--- They will continue to be executed until they return Succeeded or Failed instead of NeedsMoreTime.
---
--- Replaces any existing action with the given name.
--- If the initial call of action() doesn't return NeedsMoreTime, this function will not bother adding it to the queue.
---@param name string
---@param maxTimeMs number
---@param action Action
function actionQueue:upsert(name, maxTimeMs, action)
if action(0) ~= ActionResult.NeedsMoreTime then
return
end
self.queue[name] = {
action = action,
expireTimeMs = maxTimeMs + playdate.getCurrentTimeMilliseconds(),
}
end
--- Must be called on every playdate.update() to check for (and run) any waiting tasks.
--- Actions that return NeedsMoreTime will not be removed from the queue unless they have expired.
function actionQueue:runWaiting(deltaSeconds)
local currentTimeMs = playdate.getCurrentTimeMilliseconds()
for name, actionObject in pairs(self.queue) do
local result = actionObject.action(deltaSeconds)
if
result ~= ActionResult.NeedsMoreTime
or currentTimeMs > actionObject.expireTimeMs
then
self.queue[name] = nil
end
end
end