mirror of
https://github.com/minetest-mods/mesecons.git
synced 2024-09-26 06:10:37 +02:00
some documentation and hopefully no breaking anymore
This commit is contained in:
parent
b00fab6c48
commit
dce6943149
|
@ -1,3 +1,28 @@
|
||||||
|
--[[
|
||||||
|
Mesecons uses something it calls an ActionQueue.
|
||||||
|
|
||||||
|
The ActionQueue holds functions and actions.
|
||||||
|
Functions are added on load time with a specified name.
|
||||||
|
Actions are preserved over server restarts.
|
||||||
|
|
||||||
|
Each action consists of a position, the name of an added function to be called,
|
||||||
|
the params that should be used in this function call (additionally to the pos),
|
||||||
|
the time after which it should be executed, an optional overwritecheck and a
|
||||||
|
priority.
|
||||||
|
|
||||||
|
If time = 0, the action will be executed in the next globalstep, otherwise the
|
||||||
|
earliest globalstep when it will be executed is the after next globalstep.
|
||||||
|
|
||||||
|
It is guaranteed, that for two actions ac1, ac2 where ac1 ~= ac2,
|
||||||
|
ac1.time == ac2.time, ac1.priority == ac2.priority and ac1 was added earlier
|
||||||
|
than ac2, ac1 will be executed before ac2 (but in the same globalstep).
|
||||||
|
|
||||||
|
Note: Do not pass references in params, as they can not be preserved.
|
||||||
|
|
||||||
|
Also note: Some of the guarantees here might be dropped at some time.
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
-- localize for speed
|
-- localize for speed
|
||||||
local queue = mesecon.queue
|
local queue = mesecon.queue
|
||||||
|
|
||||||
|
@ -29,49 +54,46 @@ function queue:add_action(pos, func, params, time, overwritecheck, priority)
|
||||||
for i, ac in ipairs(queue.actions) do
|
for i, ac in ipairs(queue.actions) do
|
||||||
if vector.equals(pos, ac.pos)
|
if vector.equals(pos, ac.pos)
|
||||||
and mesecon.cmpAny(overwritecheck, ac.owcheck) then
|
and mesecon.cmpAny(overwritecheck, ac.owcheck) then
|
||||||
-- replace the old action
|
-- remove the old action
|
||||||
queue.actions[i] = action
|
table.remove(queue.actions, i)
|
||||||
return
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- otherwise just add to queue
|
|
||||||
table.insert(queue.actions, action)
|
table.insert(queue.actions, action)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- execute the stored functions on a globalstep
|
-- execute the stored functions on a globalstep
|
||||||
-- if however, the pos of a function is not loaded (get_node_or_nil == nil), do NOT execute the function
|
-- if however, the pos of a function is not loaded (get_node_or_nil == nil), do NOT execute the function
|
||||||
-- this makes sure that resuming mesecons circuits when restarting minetest works fine
|
-- this makes sure that resuming mesecons circuits when restarting minetest works fine (hm, where do we do this?)
|
||||||
-- However, even that does not work in some cases, that's why we delay the time the globalsteps
|
-- However, even that does not work in some cases, that's why we delay the time the globalsteps
|
||||||
-- start to be execute by 5 (4?) seconds
|
-- start to be execute by 4 seconds
|
||||||
|
|
||||||
local function globalstep_func(dtime)
|
local function globalstep_func(dtime)
|
||||||
-- sort out the actions to execute now (actions_now)
|
local actions = queue.actions
|
||||||
|
-- split into two categories:
|
||||||
|
-- actions_now: actions to execute now
|
||||||
|
-- queue.actions: actions to execute later
|
||||||
local actions_now = {}
|
local actions_now = {}
|
||||||
local actions_count = #queue.actions
|
queue.actions = {}
|
||||||
|
|
||||||
-- iterating downwards makes it easier to remove actions
|
for _, ac in ipairs(actions) do
|
||||||
for i = actions_count, 1, -1 do
|
if ac.time > 0 then
|
||||||
local ac = queue.actions[i]
|
-- action ac is to be executed later
|
||||||
|
-- ~> insert into queue.actions
|
||||||
ac.time = ac.time - dtime
|
ac.time = ac.time - dtime
|
||||||
|
table.insert(queue.actions, ac)
|
||||||
if ac.time <= 0 then
|
else
|
||||||
-- action ac is to be executed now
|
-- action ac is to be executed now
|
||||||
-- ~> insert into actions_now
|
-- ~> insert into actions_now
|
||||||
table.insert(actions_now, ac)
|
table.insert(actions_now, ac)
|
||||||
|
|
||||||
-- ~> remove from queue.actions
|
|
||||||
queue.actions[i] = queue.actions[actions_count]
|
|
||||||
queue.actions[actions_count] = nil
|
|
||||||
actions_count = actions_count - 1
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- stable-sort the executed actions after their priority
|
-- stable-sort the executed actions after their priority
|
||||||
-- (some constructions might depend on the execution order for acions with delay 0)
|
-- some constructions might depend on the execution order, hence we first
|
||||||
-- note that the actions were added in inverse order because of the downwards iteration,
|
-- execute the actions that had a lower index in actions_now
|
||||||
-- hence we first execute the actions that had a higher index in actions_now
|
|
||||||
local old_action_order = {}
|
local old_action_order = {}
|
||||||
for i, ac in ipairs(actions_now) do
|
for i, ac in ipairs(actions_now) do
|
||||||
old_action_order[ac] = i
|
old_action_order[ac] = i
|
||||||
|
@ -80,17 +102,17 @@ local function globalstep_func(dtime)
|
||||||
if ac1.priority ~= ac2.priority then
|
if ac1.priority ~= ac2.priority then
|
||||||
return ac1.priority > ac2.priority
|
return ac1.priority > ac2.priority
|
||||||
else
|
else
|
||||||
return old_action_order[ac1] > old_action_order[ac2]
|
return old_action_order[ac1] < old_action_order[ac2]
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- execute highest priorities first, until all are executed
|
-- execute highest priorities first, until all are executed
|
||||||
for i, ac in ipairs(actions_now) do
|
for _, ac in ipairs(actions_now) do
|
||||||
queue:execute(ac)
|
queue:execute(ac)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- delay the time the globalsteps start to be execute by 5 (4?) seconds
|
-- delay the time the globalsteps start to be execute by 4 seconds
|
||||||
do
|
do
|
||||||
local m_time = 0
|
local m_time = 0
|
||||||
local resumetime = mesecon.setting("resumetime", 4)
|
local resumetime = mesecon.setting("resumetime", 4)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user