102 lines
2.5 KiB
Lua
102 lines
2.5 KiB
Lua
local table = require('__stdlib__/stdlib/utils/table')
|
|
|
|
local function NtoZ_c(x, y)
|
|
return (x >= 0 and x or (-0.5 - x)), (y >= 0 and y or (-0.5 - y))
|
|
end
|
|
|
|
local function cantorPair_v7(pos)
|
|
local x, y = NtoZ_c(math.floor(pos.x), math.floor(pos.y))
|
|
local s = x + y
|
|
local h = s * (s + 0.5) + x
|
|
return h + h
|
|
end
|
|
|
|
local Queue = {}
|
|
|
|
function Queue.new(t)
|
|
if t and t._hash then
|
|
return setmetatable(t, Queue.mt)
|
|
else
|
|
return setmetatable({_hash = {}}, Queue.mt)
|
|
end
|
|
end
|
|
|
|
function Queue.set_hash(t, data)
|
|
local index = data.entity.unit_number or cantorPair_v7(data.entity.position)
|
|
local hash = t._hash
|
|
hash[index] = hash[index] or {}
|
|
hash[index][data.action] = data.action
|
|
return index
|
|
end
|
|
|
|
function Queue.count(t)
|
|
local count = 0
|
|
for index in pairs(t) do
|
|
if type(index) == 'number' then
|
|
count = count + 1
|
|
end
|
|
end
|
|
|
|
return count, table.size(t._hash)
|
|
end
|
|
|
|
function Queue.get_hash(t, entity)
|
|
local index = entity.unit_number or cantorPair_v7(entity.position)
|
|
return t._hash[index]
|
|
end
|
|
|
|
function Queue.insert(t, data, tick, count)
|
|
data.hash = Queue.set_hash(t, data)
|
|
|
|
t[tick] = t[tick] or {}
|
|
t[tick][#t[tick] + 1] = data
|
|
|
|
return t, count
|
|
end
|
|
|
|
function Queue.next(t, _next_tick, tick_spacing, dont_combine)
|
|
tick_spacing = tick_spacing or 1
|
|
local count = 0
|
|
local tick = (_next_tick and _next_tick >= game.tick and _next_tick) or game.tick
|
|
local next_tick = function(really_dont_combine)
|
|
tick = tick + tick_spacing
|
|
while (dont_combine or really_dont_combine) and t[tick] do
|
|
tick = tick + 1
|
|
end
|
|
count = count + 1
|
|
return tick, count
|
|
end
|
|
local queue_count = function(num)
|
|
count = count + (num or 0)
|
|
return count
|
|
end
|
|
return next_tick, queue_count
|
|
end
|
|
|
|
--Tick handler, handles executing multiple data tables in a queue
|
|
function Queue.execute(t, event)
|
|
if t[event.tick] then
|
|
for _, data in ipairs(t[event.tick]) do
|
|
local index = data.hash
|
|
if Queue[data.action] then
|
|
Queue[data.action](data)
|
|
end
|
|
t._hash[index][data.action] = nil
|
|
if table.size(t._hash[index]) <= 0 then
|
|
t._hash[index] = nil
|
|
end
|
|
end
|
|
t[event.tick] = nil
|
|
end
|
|
return t
|
|
end
|
|
|
|
Queue.mt = {__index = Queue, __call = nil}
|
|
local mt = {
|
|
__call = function(_, ...)
|
|
return Queue.new(...)
|
|
end
|
|
}
|
|
|
|
return setmetatable(Queue, mt)
|