diff --git a/mesecons/actionqueue.lua b/mesecons/actionqueue.lua index cf74d47..f9d197a 100644 --- a/mesecons/actionqueue.lua +++ b/mesecons/actionqueue.lua @@ -6,18 +6,18 @@ end -- 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 --- 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 function mesecon.queue:add_action(pos, func, params, time, overwritecheck, priority) -- Create Action Table: time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution priority = priority or 1 - action = { pos=mesecon:tablecopy(pos), - func=func, - params=mesecon:tablecopy(params), - time=time, - owcheck=(overwritecheck and mesecon:tablecopy(overwritecheck)) or nil, - priority=priority} + local action = { pos=mesecon:tablecopy(pos), + func=func, + params=mesecon:tablecopy(params), + time=time, + owcheck=(overwritecheck and mesecon:tablecopy(overwritecheck)) or nil, + priority=priority} -- 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 @@ -50,7 +50,7 @@ end -- 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 local get_highest_priority = function (actions) - local highestp = 0, highesti + local highestp = -1, highesti for i, ac in ipairs(actions) do if ac.priority > highestp then highestp = ac.priority @@ -70,7 +70,8 @@ minetest.register_globalstep(function (dtime) 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 if ac.time > 0 then ac.time = ac.time - dtime -- executed later diff --git a/mesecons_luacontroller/init.lua b/mesecons_luacontroller/init.lua index 940b5da..b5ed12a 100644 --- a/mesecons_luacontroller/init.lua +++ b/mesecons_luacontroller/init.lua @@ -192,48 +192,21 @@ local safe_serialize = function(value) return minetest.serialize(deep_copy(value)) end -local interrupt = function(params) - lc_update(params.pos, {type="interrupt", iid = params.iid}) -end +mesecon.queue:add_function("lc_interrupt", function (pos, iid, luac_id) + -- There is no luacontroller anymore / it has been reprogrammed / replaced + 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 interrupt = function (time, iid) -- iid = interrupt id if type(time) ~= "number" then return end - local iid = iid or math.random() - local meta = minetest.get_meta(pos) - 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}) + luac_id = minetest.get_meta(pos):get_int("luac_id") + mesecon.queue:add_action(pos, "lc_interrupt", {iid, luac_id}, time, iid, 1) end return interrupt 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) if not digiline then return end -- Send messages on next serverstep @@ -255,7 +228,6 @@ local create_environment = function(pos, mem, event) pin = merge_portstates(vports, rports), port = vports, interrupt = getinterrupt(pos), - timer = gettimer(pos), digiline_send = getdigiline_send(pos), mem = mem, tostring = tostring, @@ -334,7 +306,6 @@ local do_overheat = function (pos, meta) if overheat(meta) then local node = minetest.get_node(pos) 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 return true end @@ -348,20 +319,6 @@ local save_memory = function(meta, mem) meta:set_string("lc_memory", safe_serialize(mem)) 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) if type(var) == "table" then return false @@ -375,7 +332,6 @@ end lc_update = function (pos, event) local meta = minetest.get_meta(pos) - if not interrupt_allow(meta, event) then return end if do_overheat(pos, meta) then return end -- 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;]".. "label[0.1,5;"..errmsg.."]") meta:set_int("heat", 0) + meta:set_int("luac_id", math.random(1, 1000000)) end local reset = function (pos) - minetest.get_meta(pos):set_string("lc_interrupts", "") action(pos, {a=false, b=false, c=false, d=false}) end @@ -541,14 +497,15 @@ minetest.register_node(nodename, { reset(pos) reset_meta(pos, fields.code) local err = lc_update(pos, {type="program"}) - if err then print(err) end - reset_meta(pos, fields.code, err) + if err then + print(err) + reset_meta(pos, fields.code, err) + end end, on_timer = handle_timer, sounds = default.node_sound_stone_defaults(), mesecons = mesecons, digiline = digiline, - is_luacontroller = true, virtual_portstates = { a = a == 1, -- virtual portstates are b = b == 1, -- the ports the the c = c == 1, -- controller powers itself @@ -556,6 +513,7 @@ minetest.register_node(nodename, { after_dig_node = function (pos, node) mesecon:receptor_off(pos, output_rules) end, + is_luacontroller = true, }) end end @@ -588,11 +546,12 @@ minetest.register_node(BASENAME .. "_burnt", { reset(pos) reset_meta(pos, fields.code) local err = lc_update(pos, {type="program"}) - if err then print(err) end - reset_meta(pos, fields.code, err) + if err then + print(err) + reset_meta(pos, fields.code, err) + end end, sounds = default.node_sound_stone_defaults(), - is_luacontroller = true, virtual_portstates = {a = false, b = false, c = false, d = false}, })