From 300abcb5877d948e6a68be454ed46b65a0f90f01 Mon Sep 17 00:00:00 2001 From: Jeija Date: Sun, 20 Apr 2014 21:44:58 +0200 Subject: [PATCH] Fix #155 (option 2 used). Remove non-ActionQueue system. Enable overheat for more than 20 actions per second on lua- / microcontrollers and gates. Fix a bug where a burnt luacontroller didn't have the correct pin-states as the burnt controller does not register any changes from outside. --- mesecons/actionqueue.lua | 6 ---- mesecons/init.lua | 26 ++++++-------- mesecons/internal.lua | 8 ++--- mesecons/services.lua | 45 ++++++++++++++++++------ mesecons/settings.lua | 7 ++-- mesecons_gates/init.lua | 10 +++--- mesecons_luacontroller/init.lua | 58 +++++++++++++------------------ mesecons_microcontroller/init.lua | 42 +++------------------- 8 files changed, 85 insertions(+), 117 deletions(-) diff --git a/mesecons/actionqueue.lua b/mesecons/actionqueue.lua index f9d197a..a5daf88 100644 --- a/mesecons/actionqueue.lua +++ b/mesecons/actionqueue.lua @@ -19,12 +19,6 @@ function mesecon.queue:add_action(pos, func, params, time, overwritecheck, prior 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 - mesecon.queue:execute(action) - return - end - local toremove = nil -- Otherwise, add the action to the queue if overwritecheck then -- check if old action has to be overwritten / removed: diff --git a/mesecons/init.lua b/mesecons/init.lua index c3794a2..3132955 100644 --- a/mesecons/init.lua +++ b/mesecons/init.lua @@ -79,14 +79,12 @@ mesecon.queue:add_function("receptor_on", function (pos, rules) rules = rules or mesecon.rules.default -- if area (any of the rule targets) is not loaded, keep trying and call this again later - if MESECONS_GLOBALSTEP then -- trying to enable resuming with globalstep disabled would cause an endless loop - for _, rule in ipairs(mesecon:flattenrules(rules)) do - local np = mesecon:addPosRule(pos, rule) - -- if area is not loaded, keep trying - if minetest.get_node_or_nil(np) == nil then - mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) - return - end + for _, rule in ipairs(mesecon:flattenrules(rules)) do + local np = mesecon:addPosRule(pos, rule) + -- if area is not loaded, keep trying + if minetest.get_node_or_nil(np) == nil then + mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) + return end end @@ -108,13 +106,11 @@ mesecon.queue:add_function("receptor_off", function (pos, rules) rules = rules or mesecon.rules.default -- if area (any of the rule targets) is not loaded, keep trying and call this again later - if MESECONS_GLOBALSTEP then - for _, rule in ipairs(mesecon:flattenrules(rules)) do - local np = mesecon:addPosRule(pos, rule) - if minetest.get_node_or_nil(np) == nil then - mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) - return - end + for _, rule in ipairs(mesecon:flattenrules(rules)) do + local np = mesecon:addPosRule(pos, rule) + if minetest.get_node_or_nil(np) == nil then + mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) + return end end diff --git a/mesecons/internal.lua b/mesecons/internal.lua index 06fbdff..ecbfff7 100644 --- a/mesecons/internal.lua +++ b/mesecons/internal.lua @@ -412,9 +412,7 @@ function mesecon:turnon(pos, rulename, recdepth) end mesecon.queue:add_function("turnon", function (pos, rulename, recdepth) - if (MESECONS_GLOBALSTEP) then -- do not resume if we don't use globalstep - that would cause an endless loop - mesecon:turnon(pos, rulename, recdepth) - end + mesecon:turnon(pos, rulename, recdepth) end) function mesecon:turnoff(pos, rulename, recdepth) @@ -455,9 +453,7 @@ function mesecon:turnoff(pos, rulename, recdepth) end mesecon.queue:add_function("turnoff", function (pos, rulename, recdepth) - if (MESECONS_GLOBALSTEP) then -- do not resume if we don't use globalstep - that would cause an endless loop - mesecon:turnoff(pos, rulename, recdepth) - end + mesecon:turnoff(pos, rulename, recdepth) end) diff --git a/mesecons/services.lua b/mesecons/services.lua index 7421b96..b0b45e0 100644 --- a/mesecons/services.lua +++ b/mesecons/services.lua @@ -1,3 +1,5 @@ +-- Dig and place services + mesecon.on_placenode = function (pos, node) -- Receptors: Send on signal when active if mesecon:is_receptor_on(node.name) then @@ -37,15 +39,38 @@ mesecon.on_dignode = function (pos, node) end end -minetest.register_abm({ - nodenames = {"group:overheat"}, - interval = 1.0, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - local meta = minetest.get_meta(pos) - meta:set_int("heat",0) - end, -}) - minetest.register_on_placenode(mesecon.on_placenode) minetest.register_on_dignode(mesecon.on_dignode) + +-- Overheating service for fast circuits + +-- returns true if heat is too high +mesecon.do_overheat = function(pos) + local meta = minetest.get_meta(pos) + local heat = meta:get_int("heat") or 0 + + heat = heat + 1 + meta:set_int("heat", heat) + + if heat < OVERHEAT_MAX then + mesecon.queue:add_action(pos, "cooldown", {}, 1, nil, 0) + else + return true + end + + return false +end + + +mesecon.queue:add_function("cooldown", function (pos) + if minetest.get_item_group(minetest.get_node(pos).name, "overheat") == 0 then + return -- node has been moved, this one does not use overheating - ignore + end + + local meta = minetest.get_meta(pos) + local heat = meta:get_int("heat") + + if (heat > 0) then + meta:set_int("heat", heat - 1) + end +end) diff --git a/mesecons/settings.lua b/mesecons/settings.lua index 593a79b..160df67 100644 --- a/mesecons/settings.lua +++ b/mesecons/settings.lua @@ -1,11 +1,12 @@ -- SETTINGS BLINKY_PLANT_INTERVAL = 3 -NEW_STYLE_WIRES = true -- true = new nodebox wires, false = old raillike wires +NEW_STYLE_WIRES = true -- true = new nodebox wires, false = old raillike wires PRESSURE_PLATE_INTERVAL = 0.1 OBJECT_DETECTOR_RADIUS = 6 PISTON_MAXIMUM_PUSH = 15 MOVESTONE_MAXIMUM_PUSH = 100 -MESECONS_GLOBALSTEP = true -- true = receptors/effectors won't be updated - -- until next globalstep, decreases server load MESECONS_RESUMETIME = 4 -- time to wait when starting the server before -- processing the ActionQueue, don't set this too low +OVERHEAT_MAX = 20 -- maximum heat of any component that directly sends an output + -- signal when the input changes (e.g. luacontroller, gates) + -- Unit: actions per second, checks are every 1 second diff --git a/mesecons_gates/init.lua b/mesecons_gates/init.lua index 51ed4af..a22edf6 100644 --- a/mesecons_gates/init.lua +++ b/mesecons_gates/init.lua @@ -47,9 +47,7 @@ function set_gate(pos, on) gate = get_gate(pos) local meta = minetest.get_meta(pos) if on ~= gate_state(pos) then - yc_heat(meta) - --minetest.after(0.5, yc_cool, meta) - if yc_overheat(meta) then + if mesecon.do_overheat(pos) then pop_gate(pos) else local node = minetest.get_node(pos) @@ -78,7 +76,9 @@ end function pop_gate(pos) gate = get_gate(pos) minetest.remove_node(pos) - minetest.after(0.2, yc_overheat_off, pos) + minetest.after(0.2, function (pos) + mesecon:receptor_off(pos, mesecon.rules.flat) + end , pos) -- wait for pending parsings minetest.add_item(pos, "mesecons_gates:"..gate.."_off") end @@ -153,7 +153,6 @@ for _, gate in ipairs(gates) do walkable = true, on_construct = function(pos) local meta = minetest.get_meta(pos) - meta:set_int("heat", 0) update_gate(pos) end, groups = groups, @@ -221,4 +220,3 @@ minetest.register_craft({ {'mesecons:mesecon', '', ''}, }, }) - diff --git a/mesecons_luacontroller/init.lua b/mesecons_luacontroller/init.lua index de3a972..f4869b5 100644 --- a/mesecons_luacontroller/init.lua +++ b/mesecons_luacontroller/init.lua @@ -122,30 +122,6 @@ end -- Overheat stuff -- -------------------- -local heat = function (meta) -- warm up - h = meta:get_int("heat") - if h ~= nil then - meta:set_int("heat", h + 1) - end -end - ---local cool = function (meta) -- cool down after a while --- h = meta:get_int("heat") --- if h ~= nil then --- meta:set_int("heat", h - 1) --- end ---end - -local overheat = function (meta) -- determine if too hot - h = meta:get_int("heat") - if h == nil then return true end -- if nil then overheat - if h > 40 then - return true - else - return false - end -end - local overheat_off = function(pos) mesecon:receptor_off(pos, mesecon.rules.flat) end @@ -232,6 +208,8 @@ local create_environment = function(pos, mem, event) mem = mem, tostring = tostring, tonumber = tonumber, + heat = minetest.get_meta(pos):get_int("heat"), + heat_max = OVERHEAT_MAX, string = { byte = string.byte, char = string.char, @@ -299,11 +277,8 @@ local create_sandbox = function (code, env) return f end -local do_overheat = function (pos, meta) - -- Overheat protection - heat(meta) - --minetest.after(0.5, cool, meta) - if overheat(meta) then +local lc_overheat = function (pos, meta) + if mesecon.do_overheat(pos) then -- if too hot local node = minetest.get_node(pos) minetest.swap_node(pos, {name = BASENAME.."_burnt", param2 = node.param2}) minetest.after(0.2, overheat_off, pos) -- wait for pending operations @@ -332,7 +307,7 @@ end lc_update = function (pos, event) local meta = minetest.get_meta(pos) - if do_overheat(pos, meta) then return end + if lc_overheat(pos) then return end -- load code & mem from memory local mem = load_memory(meta) @@ -507,9 +482,9 @@ minetest.register_node(nodename, { mesecons = mesecons, digiline = digiline, virtual_portstates = { a = a == 1, -- virtual portstates are - b = b == 1, -- the ports the the - c = c == 1, -- controller powers itself - d = d == 1},-- so those that light up + b = b == 1, -- the ports the the + c = c == 1, -- controller powers itself + d = d == 1},-- so those that light up after_dig_node = function (pos, node) mesecon:receptor_off(pos, output_rules) end, @@ -520,7 +495,21 @@ end end end ---overheated luacontroller +------------------------------ +-- overheated luacontroller -- +------------------------------ + +local mesecons_burnt = { + effector = + { + rules = mesecon.rules.flat, + action_change = function (pos, _, rulename, newstate) + -- only update portstates when changes are triggered + lc_update_real_portstates(pos, rulename, newstate) + end + } +} + minetest.register_node(BASENAME .. "_burnt", { drawtype = "nodebox", tiles = { @@ -553,6 +542,7 @@ minetest.register_node(BASENAME .. "_burnt", { end, sounds = default.node_sound_stone_defaults(), virtual_portstates = {a = false, b = false, c = false, d = false}, + mesecons = mesecons_burnt, }) ------------------------ diff --git a/mesecons_microcontroller/init.lua b/mesecons_microcontroller/init.lua index b6134da..ec7afbd 100644 --- a/mesecons_microcontroller/init.lua +++ b/mesecons_microcontroller/init.lua @@ -93,7 +93,6 @@ minetest.register_node(nodename, { "button[7.5,0.2;1.5,3;brsflop;RS-Flop]".. "button_exit[3.5,1;2,3;program;Program]") meta:set_string("infotext", "Unprogrammed Microcontroller") - meta:set_int("heat", 0) local r = "" for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0" meta:set_string("eeprom", r) @@ -156,7 +155,6 @@ minetest.register_craft({ function yc_reset(pos) yc_action(pos, {a=false, b=false, c=false, d=false}) local meta = minetest.get_meta(pos) - meta:set_int("heat", 0) meta:set_int("afterid", 0) local r = "" for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0" @@ -165,11 +163,12 @@ end function update_yc(pos) local meta = minetest.get_meta(pos) - yc_heat(meta) - --minetest.after(0.5, yc_cool, meta) - if (yc_overheat(meta)) then + + if (mesecon.do_overheat(pos)) then minetest.remove_node(pos) - minetest.after(0.2, yc_overheat_off, pos) --wait for pending parsings + minetest.after(0.2, function (pos) + mesecon:receptor_off(pos, mesecon.rules.flat) + end , pos) -- wait for pending parsings minetest.add_item(pos, "mesecons_microcontroller:microcontroller0000") end @@ -698,34 +697,3 @@ function yc_merge_portstates(Lreal, Lvirtual) if Lvirtual.d or Lreal.d then L.d = true end return L end - ---"Overheat" protection -function yc_heat(meta) - h = meta:get_int("heat") - if h ~= nil then - meta:set_int("heat", h + 1) - end -end - ---function yc_cool(meta) --- h = meta:get_int("heat") --- if h ~= nil then --- meta:set_int("heat", h - 1) --- end ---end - -function yc_overheat(meta) - if MESECONS_GLOBALSTEP then return false end - h = meta:get_int("heat") - if h == nil then return true end -- if nil the overheat - if h>60 then - return true - else - return false - end -end - -function yc_overheat_off(pos) - rules = mesecon:get_rules("mesecons_microcontroller:microcontroller1111") - mesecon:receptor_off(pos, rules) -end