-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathEntityQueue.lua
89 lines (79 loc) · 2.02 KB
/
EntityQueue.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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