89 lines
2.0 KiB
Lua
89 lines
2.0 KiB
Lua
local Event = require "Event"
|
|
|
|
-- Entity Queue
|
|
-- executes a task periodically for a set of entities,
|
|
-- inspecting only one entity per tick
|
|
local M = {}
|
|
|
|
function M:register(entity)
|
|
global[self.name][entity.unit_number] = entity
|
|
Event.register_nth_tick(self.interval, self.on_tick)
|
|
end
|
|
|
|
local function unregister_helper(self, key)
|
|
local queue = global[self.name]
|
|
if queue[key] then
|
|
-- ensure iter always holds a valid key
|
|
if key == global[self.iter_name] then
|
|
global[self.iter_name] = next(queue, key)
|
|
end
|
|
queue[key] = nil
|
|
if not next(queue) then
|
|
Event.unregister_nth_tick(self.interval, self.on_tick)
|
|
end
|
|
end
|
|
end
|
|
|
|
function M:unregister(entity)
|
|
unregister_helper(self, entity.unit_number)
|
|
end
|
|
|
|
function M:on_init()
|
|
global[self.name] = {}
|
|
end
|
|
|
|
function M:on_load()
|
|
local queue = global[self.name]
|
|
local iter_name = self.iter_name
|
|
if queue and next(queue) then
|
|
if global[iter_name] and not queue[global[iter_name]] then
|
|
global[iter_name] = nil
|
|
end
|
|
Event.register_nth_tick(self.interval, self.on_tick)
|
|
end
|
|
end
|
|
|
|
local function create_on_tick(self)
|
|
self.on_tick = function()
|
|
local queue = global[self.name]
|
|
local iter_name = self.iter_name
|
|
if not queue[global[iter_name]] then
|
|
global[iter_name] = nil
|
|
end
|
|
local k, v
|
|
repeat
|
|
k, v = next(queue, global[iter_name])
|
|
global[iter_name] = k
|
|
if not k and not next(queue) then
|
|
-- table is empty
|
|
Event.unregister_nth_tick(self.interval, self.on_tick)
|
|
return
|
|
end
|
|
if v and not v.valid then
|
|
unregister_helper(self, k)
|
|
end
|
|
until k and v and v.valid
|
|
local should_unregister = self.task(v)
|
|
if should_unregister then
|
|
unregister_helper(self, k)
|
|
end
|
|
end
|
|
end
|
|
|
|
function M.new(name, interval, task)
|
|
local self = {
|
|
name = name,
|
|
iter_name = name .. "_iter",
|
|
interval = interval,
|
|
task = task,
|
|
}
|
|
create_on_tick(self)
|
|
|
|
local meta = {
|
|
__index = M,
|
|
__call = M.new,
|
|
}
|
|
return setmetatable(self, meta)
|
|
end
|
|
|
|
return M |