1 mesecon
.queue
.actions
={} -- contains all ActionQueue actions
3 function mesecon
.queue
:add_function(name
, func
)
4 mesecon
.queue
.funcs
[name
] = func
7 -- If add_action with twice the same overwritecheck and same position are called, the first one is overwritten
8 -- use overwritecheck nil to never overwrite, but just add the event to the queue
9 -- priority specifies the order actions are executed within one globalstep, highest first
10 -- should be between 0 and 1
11 function mesecon
.queue
:add_action(pos
, func
, params
, time
, overwritecheck
, priority
)
12 -- Create Action Table:
13 time
= time
or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution
14 priority
= priority
or 1
15 local action
= { pos
=mesecon
.tablecopy(pos
),
17 params
=mesecon
.tablecopy(params
or {}),
19 owcheck
=(overwritecheck
and mesecon
.tablecopy(overwritecheck
)) or nil,
23 -- Otherwise, add the action to the queue
24 if overwritecheck
then -- check if old action has to be overwritten / removed:
25 for i
, ac
in ipairs(mesecon
.queue
.actions
) do
26 if(vector
.equals(pos
, ac
.pos
)
27 and mesecon
.cmpAny(overwritecheck
, ac
.owcheck
)) then
34 if (toremove
~= nil) then
35 table.remove(mesecon
.queue
.actions
, toremove
)
38 table.insert(mesecon
.queue
.actions
, action
)
41 -- execute the stored functions on a globalstep
42 -- if however, the pos of a function is not loaded (get_node_or_nil == nil), do NOT execute the function
43 -- this makes sure that resuming mesecons circuits when restarting minetest works fine
44 -- However, even that does not work in some cases, that's why we delay the time the globalsteps
45 -- start to be execute by 5 seconds
46 local get_highest_priority
= function (actions
)
49 for i
, ac
in ipairs(actions
) do
50 if ac
.priority
> highestp
then
51 highestp
= ac
.priority
60 local resumetime
= mesecon
.setting("resumetime", 4)
61 minetest
.register_globalstep(function (dtime
)
62 m_time
= m_time
+ dtime
63 -- don't even try if server has not been running for XY seconds; resumetime = time to wait
64 -- after starting the server before processing the ActionQueue, don't set this too low
65 if (m_time
< resumetime
) then return end
66 local actions
= mesecon
.tablecopy(mesecon
.queue
.actions
)
69 mesecon
.queue
.actions
= {}
71 -- sort actions into two categories:
72 -- those toexecute now (actions_now) and those to execute later (mesecon.queue.actions)
73 for i
, ac
in ipairs(actions
) do
75 ac
.time
= ac
.time
- dtime
-- executed later
76 table.insert(mesecon
.queue
.actions
, ac
)
78 table.insert(actions_now
, ac
)
82 while(#actions_now
> 0) do -- execute highest priorities first, until all are executed
83 local hp
= get_highest_priority(actions_now
)
84 mesecon
.queue
:execute(actions_now
[hp
])
85 table.remove(actions_now
, hp
)
89 function mesecon
.queue
:execute(action
)
90 -- ignore if action queue function name doesn't exist,
91 -- (e.g. in case the action queue savegame was written by an old mesecons version)
92 if mesecon
.queue
.funcs
[action
.func
] then
93 mesecon
.queue
.funcs
[action
.func
](action
.pos
, unpack(action
.params
))
98 -- Store and read the ActionQueue to / from a file
99 -- so that upcoming actions are remembered when the game
101 mesecon
.queue
.actions
= mesecon
.file2table("mesecon_actionqueue")
103 minetest
.register_on_shutdown(function()
104 mesecon
.table2file("mesecon_actionqueue", mesecon
.queue
.actions
)