building timers (#1)
* building timers * timer spec * debug * wip * err * wip * wip * cleanup --------- Co-authored-by: BuckarooBanzay <BuckarooBanzay@users.noreply.github.com>
This commit is contained in:
parent
22d4f081ca
commit
9eda9b2203
1
init.lua
1
init.lua
@ -49,4 +49,5 @@ if minetest.get_modpath("mtt") and mtt.enabled then
|
||||
dofile(MP .. "/conditions.spec.lua")
|
||||
dofile(MP .. "/build.spec.lua")
|
||||
dofile(MP .. "/build_over.spec.lua")
|
||||
dofile(MP .. "/timer.spec.lua")
|
||||
end
|
||||
|
98
timer.lua
98
timer.lua
@ -11,36 +11,40 @@ function building_lib.get_building_timer(mapblock_pos)
|
||||
return setmetatable(self, BuildingTimer_mt)
|
||||
end
|
||||
|
||||
local function get_timer_key(mapblock_pos)
|
||||
return "timer_" .. minetest.pos_to_string(mapblock_pos)
|
||||
end
|
||||
|
||||
function BuildingTimer:get_entry()
|
||||
local data = building_lib.store:get_group_data(self.mapblock_pos)
|
||||
local key = get_timer_key(self.mapblock_pos)
|
||||
return data[key] or {}
|
||||
if not data.timers then
|
||||
-- create timers table
|
||||
data.timers = {}
|
||||
building_lib.store:set_group_data(self.mapblock_pos, data)
|
||||
end
|
||||
|
||||
local key = minetest.pos_to_string(self.mapblock_pos)
|
||||
return data.timers[key] or {}
|
||||
end
|
||||
|
||||
function BuildingTimer:set_entry(entry)
|
||||
local data = building_lib.store:get_group_data(self.mapblock_pos)
|
||||
if not data.timers then
|
||||
-- create timers table
|
||||
data.timers = {}
|
||||
end
|
||||
|
||||
local key = minetest.pos_to_string(self.mapblock_pos)
|
||||
data.timers[key] = entry
|
||||
building_lib.store:set_group_data(self.mapblock_pos, data)
|
||||
end
|
||||
|
||||
function BuildingTimer:set(timeout, elapsed)
|
||||
-- TODO: move timers to own field for better lookup
|
||||
local data = building_lib.store:get_group_data(self.mapblock_pos)
|
||||
local key = get_timer_key(self.mapblock_pos)
|
||||
|
||||
if timeout > 0 then
|
||||
-- started, update entry
|
||||
local entry = data[key]
|
||||
if not entry then
|
||||
entry = {}
|
||||
data[key] = entry
|
||||
end
|
||||
|
||||
entry.timeout = timeout
|
||||
entry.elapsed = elapsed
|
||||
self:set_entry({
|
||||
timeout = timeout,
|
||||
elapsed = elapsed
|
||||
})
|
||||
else
|
||||
-- stopped, remove entry
|
||||
data[key] = nil
|
||||
self:set_entry(nil)
|
||||
end
|
||||
building_lib.store:set_group_data(self.mapblock_pos, data)
|
||||
end
|
||||
|
||||
function BuildingTimer:start(timeout)
|
||||
@ -66,12 +70,52 @@ function BuildingTimer:is_started()
|
||||
return entry.timeout and entry.timeout > entry.elapsed
|
||||
end
|
||||
|
||||
function building_lib.update_timers(pos)
|
||||
-- TODO
|
||||
print(dump(pos))
|
||||
function building_lib.update_timers(pos, interval)
|
||||
local rpos = mapblock_lib.get_mapblock(pos)
|
||||
local data = building_lib.store:get_group_data(rpos)
|
||||
|
||||
if not data.timers then
|
||||
-- no timers found in the mapblock
|
||||
return
|
||||
end
|
||||
|
||||
for mapblock_pos_str, entry in pairs(data.timers) do
|
||||
-- increment active timers and call `on_timer` on buildings
|
||||
local mapblock_pos = minetest.string_to_pos(mapblock_pos_str)
|
||||
entry.elapsed = entry.elapsed + interval
|
||||
|
||||
local remove_timer = false
|
||||
|
||||
if entry.elapsed >= entry.timeout then
|
||||
-- timer event
|
||||
local def = building_lib.get_building_def_at(mapblock_pos)
|
||||
if type(def.on_timer) == "function" then
|
||||
local result = def.on_timer(mapblock_pos, entry.elapsed)
|
||||
if result then
|
||||
-- reschedule
|
||||
entry.elapsed = 0
|
||||
else
|
||||
-- remove
|
||||
remove_timer = true
|
||||
end
|
||||
else
|
||||
-- invalid field type
|
||||
remove_timer = true
|
||||
end
|
||||
end
|
||||
|
||||
if remove_timer then
|
||||
data.timers[mapblock_pos_str] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- store timer data
|
||||
building_lib.store:set_group_data(rpos, data)
|
||||
end
|
||||
|
||||
-- TODO: iterate over active areas and operate on `DataStorage:get_group_data(pos)`
|
||||
local TIMER_INTERVAL = 2
|
||||
|
||||
-- iterate over active areas and operate on `DataStorage:get_group_data(pos)`
|
||||
local function timer_update_loop()
|
||||
local visited = {}
|
||||
|
||||
@ -93,7 +137,7 @@ local function timer_update_loop()
|
||||
|
||||
-- check if already processed
|
||||
if not visited[key] then
|
||||
building_lib.update_timers(pos)
|
||||
building_lib.update_timers(pos, TIMER_INTERVAL)
|
||||
visited[key] = true
|
||||
end
|
||||
end
|
||||
@ -101,7 +145,7 @@ local function timer_update_loop()
|
||||
end
|
||||
end
|
||||
|
||||
minetest.after(2, timer_update_loop)
|
||||
minetest.after(TIMER_INTERVAL, timer_update_loop)
|
||||
end
|
||||
|
||||
minetest.after(1, timer_update_loop)
|
||||
|
41
timer.spec.lua
Normal file
41
timer.spec.lua
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
local building_mapblock_pos = {x=0, y=0, z=0}
|
||||
local building_name = "building_lib:dummy_timer"
|
||||
local rotation = 0
|
||||
local playername = "singleplayer"
|
||||
|
||||
local timer_mapblock_pos, timer_elapsed
|
||||
|
||||
building_lib.register_building(building_name, {
|
||||
placement = "dummy",
|
||||
on_timer = function(mapblock_pos, elapsed)
|
||||
timer_mapblock_pos = mapblock_pos
|
||||
timer_elapsed = elapsed
|
||||
end
|
||||
})
|
||||
|
||||
mtt.register("building_lib.get_building_timer", function()
|
||||
-- clear store
|
||||
building_lib.store:clear()
|
||||
|
||||
-- try to build
|
||||
local success, err = building_lib.can_build(building_mapblock_pos, playername, building_name, rotation)
|
||||
assert(not err)
|
||||
assert(success)
|
||||
|
||||
-- build
|
||||
return building_lib.build(building_mapblock_pos, playername, building_name, rotation)
|
||||
:next(function()
|
||||
local timer = building_lib.get_building_timer(building_mapblock_pos)
|
||||
timer:start(10)
|
||||
|
||||
local pos = { x=0, y=0, z=0 }
|
||||
building_lib.update_timers(pos, 5)
|
||||
assert(not timer_mapblock_pos)
|
||||
assert(not timer_elapsed)
|
||||
|
||||
building_lib.update_timers(pos, 5)
|
||||
assert(vector.equals(timer_mapblock_pos, building_mapblock_pos))
|
||||
assert(timer_elapsed >= 10)
|
||||
end)
|
||||
end)
|
Loading…
x
Reference in New Issue
Block a user