Version 0.41.3
[MineClone/MineClone2/MineClone2-Fixes.git] / mods / ITEMS / REDSTONE / mesecons / actionqueue.lua
blobf3479ce59e7cf6196958be76fa69fdf9cdb08205
1 mesecon.queue.actions={} -- contains all ActionQueue actions
3 function mesecon.queue:add_function(name, func)
4 mesecon.queue.funcs[name] = func
5 end
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),
16 func=func,
17 params=mesecon.tablecopy(params or {}),
18 time=time,
19 owcheck=(overwritecheck and mesecon.tablecopy(overwritecheck)) or nil,
20 priority=priority}
22 local toremove = 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
28 toremove = i
29 break
30 end
31 end
32 end
34 if (toremove ~= nil) then
35 table.remove(mesecon.queue.actions, toremove)
36 end
38 table.insert(mesecon.queue.actions, action)
39 end
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)
47 local highestp = -1
48 local highesti
49 for i, ac in ipairs(actions) do
50 if ac.priority > highestp then
51 highestp = ac.priority
52 highesti = i
53 end
54 end
56 return highesti
57 end
59 local m_time = 0
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)
67 local actions_now={}
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
74 if ac.time > 0 then
75 ac.time = ac.time - dtime -- executed later
76 table.insert(mesecon.queue.actions, ac)
77 else
78 table.insert(actions_now, ac)
79 end
80 end
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)
86 end
87 end)
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))
94 end
95 end
98 -- Store and read the ActionQueue to / from a file
99 -- so that upcoming actions are remembered when the game
100 -- is restarted
101 mesecon.queue.actions = mesecon.file2table("mesecon_actionqueue")
103 minetest.register_on_shutdown(function()
104 mesecon.table2file("mesecon_actionqueue", mesecon.queue.actions)
105 end)