forked from Mirrorlandia_minetest/mesecons
Remove timer() from LuaController and make interrupt() use the ActionQueue so that it will keep working when restarting the server
This commit is contained in:
parent
39a0e56c18
commit
df6829e553
@ -6,18 +6,18 @@ end
|
|||||||
|
|
||||||
-- If add_action with twice the same overwritecheck and same position are called, the first one is overwritten
|
-- If add_action with twice the same overwritecheck and same position are called, the first one is overwritten
|
||||||
-- use overwritecheck nil to never overwrite, but just add the event to the queue
|
-- use overwritecheck nil to never overwrite, but just add the event to the queue
|
||||||
-- priority specifies the order actions are executed within one globalstep, highest by default
|
-- priority specifies the order actions are executed within one globalstep, highest first
|
||||||
-- should be between 0 and 1
|
-- should be between 0 and 1
|
||||||
function mesecon.queue:add_action(pos, func, params, time, overwritecheck, priority)
|
function mesecon.queue:add_action(pos, func, params, time, overwritecheck, priority)
|
||||||
-- Create Action Table:
|
-- Create Action Table:
|
||||||
time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution
|
time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution
|
||||||
priority = priority or 1
|
priority = priority or 1
|
||||||
action = { pos=mesecon:tablecopy(pos),
|
local action = { pos=mesecon:tablecopy(pos),
|
||||||
func=func,
|
func=func,
|
||||||
params=mesecon:tablecopy(params),
|
params=mesecon:tablecopy(params),
|
||||||
time=time,
|
time=time,
|
||||||
owcheck=(overwritecheck and mesecon:tablecopy(overwritecheck)) or nil,
|
owcheck=(overwritecheck and mesecon:tablecopy(overwritecheck)) or nil,
|
||||||
priority=priority}
|
priority=priority}
|
||||||
|
|
||||||
-- if not using the queue, (MESECONS_GLOBALSTEP off), just execute the function an we're done
|
-- if not using the queue, (MESECONS_GLOBALSTEP off), just execute the function an we're done
|
||||||
if not MESECONS_GLOBALSTEP and action.time == 0 then
|
if not MESECONS_GLOBALSTEP and action.time == 0 then
|
||||||
@ -50,7 +50,7 @@ end
|
|||||||
-- 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 seconds
|
-- start to be execute by 5 seconds
|
||||||
local get_highest_priority = function (actions)
|
local get_highest_priority = function (actions)
|
||||||
local highestp = 0, highesti
|
local highestp = -1, highesti
|
||||||
for i, ac in ipairs(actions) do
|
for i, ac in ipairs(actions) do
|
||||||
if ac.priority > highestp then
|
if ac.priority > highestp then
|
||||||
highestp = ac.priority
|
highestp = ac.priority
|
||||||
@ -70,7 +70,8 @@ minetest.register_globalstep(function (dtime)
|
|||||||
|
|
||||||
mesecon.queue.actions = {}
|
mesecon.queue.actions = {}
|
||||||
|
|
||||||
-- sort actions in execute now (actions_now) and for later (mesecon.queue.actions)
|
-- sort actions into two categories:
|
||||||
|
-- those toexecute now (actions_now) and those to execute later (mesecon.queue.actions)
|
||||||
for i, ac in ipairs(actions) do
|
for i, ac in ipairs(actions) do
|
||||||
if ac.time > 0 then
|
if ac.time > 0 then
|
||||||
ac.time = ac.time - dtime -- executed later
|
ac.time = ac.time - dtime -- executed later
|
||||||
|
@ -192,48 +192,21 @@ local safe_serialize = function(value)
|
|||||||
return minetest.serialize(deep_copy(value))
|
return minetest.serialize(deep_copy(value))
|
||||||
end
|
end
|
||||||
|
|
||||||
local interrupt = function(params)
|
mesecon.queue:add_function("lc_interrupt", function (pos, iid, luac_id)
|
||||||
lc_update(params.pos, {type="interrupt", iid = params.iid})
|
-- There is no luacontroller anymore / it has been reprogrammed / replaced
|
||||||
end
|
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end
|
||||||
|
lc_update(pos, {type="interrupt", iid = iid})
|
||||||
|
end)
|
||||||
|
|
||||||
local getinterrupt = function(pos)
|
local getinterrupt = function(pos)
|
||||||
local interrupt = function (time, iid) -- iid = interrupt id
|
local interrupt = function (time, iid) -- iid = interrupt id
|
||||||
if type(time) ~= "number" then return end
|
if type(time) ~= "number" then return end
|
||||||
local iid = iid or math.random()
|
luac_id = minetest.get_meta(pos):get_int("luac_id")
|
||||||
local meta = minetest.get_meta(pos)
|
mesecon.queue:add_action(pos, "lc_interrupt", {iid, luac_id}, time, iid, 1)
|
||||||
local interrupts = minetest.deserialize(meta:get_string("lc_interrupts")) or {}
|
|
||||||
local found = false
|
|
||||||
local search = safe_serialize(iid)
|
|
||||||
for _, i in ipairs(interrupts) do
|
|
||||||
if safe_serialize(i) == search then
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not found then
|
|
||||||
table.insert(interrupts, iid)
|
|
||||||
meta:set_string("lc_interrupts", safe_serialize(interrupts))
|
|
||||||
end
|
|
||||||
minetest.after(time, interrupt, {pos=pos, iid = iid})
|
|
||||||
end
|
end
|
||||||
return interrupt
|
return interrupt
|
||||||
end
|
end
|
||||||
|
|
||||||
local handle_timer = function(pos, elapsed)
|
|
||||||
local err = lc_update(pos, {type="timer"})
|
|
||||||
if err then print(err) end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local gettimer = function(pos)
|
|
||||||
local timer = function (time)
|
|
||||||
if type(time) ~= "number" then return end
|
|
||||||
local nodetimer = minetest.get_node_timer(pos)
|
|
||||||
nodetimer:start(time)
|
|
||||||
end
|
|
||||||
return timer
|
|
||||||
end
|
|
||||||
|
|
||||||
local getdigiline_send = function(pos)
|
local getdigiline_send = function(pos)
|
||||||
if not digiline then return end
|
if not digiline then return end
|
||||||
-- Send messages on next serverstep
|
-- Send messages on next serverstep
|
||||||
@ -255,7 +228,6 @@ local create_environment = function(pos, mem, event)
|
|||||||
pin = merge_portstates(vports, rports),
|
pin = merge_portstates(vports, rports),
|
||||||
port = vports,
|
port = vports,
|
||||||
interrupt = getinterrupt(pos),
|
interrupt = getinterrupt(pos),
|
||||||
timer = gettimer(pos),
|
|
||||||
digiline_send = getdigiline_send(pos),
|
digiline_send = getdigiline_send(pos),
|
||||||
mem = mem,
|
mem = mem,
|
||||||
tostring = tostring,
|
tostring = tostring,
|
||||||
@ -334,7 +306,6 @@ local do_overheat = function (pos, meta)
|
|||||||
if overheat(meta) then
|
if overheat(meta) then
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
minetest.swap_node(pos, {name = BASENAME.."_burnt", param2 = node.param2})
|
minetest.swap_node(pos, {name = BASENAME.."_burnt", param2 = node.param2})
|
||||||
minetest.get_meta(pos):set_string("lc_interrupts", "")
|
|
||||||
minetest.after(0.2, overheat_off, pos) -- wait for pending operations
|
minetest.after(0.2, overheat_off, pos) -- wait for pending operations
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -348,20 +319,6 @@ local save_memory = function(meta, mem)
|
|||||||
meta:set_string("lc_memory", safe_serialize(mem))
|
meta:set_string("lc_memory", safe_serialize(mem))
|
||||||
end
|
end
|
||||||
|
|
||||||
local interrupt_allow = function (meta, event)
|
|
||||||
if event.type ~= "interrupt" then return true end
|
|
||||||
|
|
||||||
local interrupts = minetest.deserialize(meta:get_string("lc_interrupts")) or {}
|
|
||||||
local search = safe_serialize(event.iid)
|
|
||||||
for _, i in ipairs(interrupts) do
|
|
||||||
if safe_serialize(i) == search then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local ports_invalid = function (var)
|
local ports_invalid = function (var)
|
||||||
if type(var) == "table" then
|
if type(var) == "table" then
|
||||||
return false
|
return false
|
||||||
@ -375,7 +332,6 @@ end
|
|||||||
|
|
||||||
lc_update = function (pos, event)
|
lc_update = function (pos, event)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
if not interrupt_allow(meta, event) then return end
|
|
||||||
if do_overheat(pos, meta) then return end
|
if do_overheat(pos, meta) then return end
|
||||||
|
|
||||||
-- load code & mem from memory
|
-- load code & mem from memory
|
||||||
@ -412,10 +368,10 @@ local reset_meta = function(pos, code, errmsg)
|
|||||||
"image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"..
|
"image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"..
|
||||||
"label[0.1,5;"..errmsg.."]")
|
"label[0.1,5;"..errmsg.."]")
|
||||||
meta:set_int("heat", 0)
|
meta:set_int("heat", 0)
|
||||||
|
meta:set_int("luac_id", math.random(1, 1000000))
|
||||||
end
|
end
|
||||||
|
|
||||||
local reset = function (pos)
|
local reset = function (pos)
|
||||||
minetest.get_meta(pos):set_string("lc_interrupts", "")
|
|
||||||
action(pos, {a=false, b=false, c=false, d=false})
|
action(pos, {a=false, b=false, c=false, d=false})
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -541,14 +497,15 @@ minetest.register_node(nodename, {
|
|||||||
reset(pos)
|
reset(pos)
|
||||||
reset_meta(pos, fields.code)
|
reset_meta(pos, fields.code)
|
||||||
local err = lc_update(pos, {type="program"})
|
local err = lc_update(pos, {type="program"})
|
||||||
if err then print(err) end
|
if err then
|
||||||
reset_meta(pos, fields.code, err)
|
print(err)
|
||||||
|
reset_meta(pos, fields.code, err)
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
on_timer = handle_timer,
|
on_timer = handle_timer,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = default.node_sound_stone_defaults(),
|
||||||
mesecons = mesecons,
|
mesecons = mesecons,
|
||||||
digiline = digiline,
|
digiline = digiline,
|
||||||
is_luacontroller = true,
|
|
||||||
virtual_portstates = { a = a == 1, -- virtual portstates are
|
virtual_portstates = { a = a == 1, -- virtual portstates are
|
||||||
b = b == 1, -- the ports the the
|
b = b == 1, -- the ports the the
|
||||||
c = c == 1, -- controller powers itself
|
c = c == 1, -- controller powers itself
|
||||||
@ -556,6 +513,7 @@ minetest.register_node(nodename, {
|
|||||||
after_dig_node = function (pos, node)
|
after_dig_node = function (pos, node)
|
||||||
mesecon:receptor_off(pos, output_rules)
|
mesecon:receptor_off(pos, output_rules)
|
||||||
end,
|
end,
|
||||||
|
is_luacontroller = true,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -588,11 +546,12 @@ minetest.register_node(BASENAME .. "_burnt", {
|
|||||||
reset(pos)
|
reset(pos)
|
||||||
reset_meta(pos, fields.code)
|
reset_meta(pos, fields.code)
|
||||||
local err = lc_update(pos, {type="program"})
|
local err = lc_update(pos, {type="program"})
|
||||||
if err then print(err) end
|
if err then
|
||||||
reset_meta(pos, fields.code, err)
|
print(err)
|
||||||
|
reset_meta(pos, fields.code, err)
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = default.node_sound_stone_defaults(),
|
||||||
is_luacontroller = true,
|
|
||||||
virtual_portstates = {a = false, b = false, c = false, d = false},
|
virtual_portstates = {a = false, b = false, c = false, d = false},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user