Don't trigger an "off" event to itself when luacontroller turns a port off

I hope this doesn't break anyone's setup.
This commit is contained in:
Jeija 2014-11-29 10:56:09 +01:00
parent 2a51e40af9
commit d2373eb605
2 changed files with 33 additions and 2 deletions

View File

@ -598,7 +598,7 @@ function mesecon.is_powered(pos, rule)
local nn = minetest.get_node(np)
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
or mesecon.is_receptor_on (nn.name)) then
sourcepos.insert(np)
table.insert(sourcepos, np)
end
end
end

View File

@ -133,6 +133,23 @@ local function set_port_states(pos, ports)
local new_name = generate_name(ports)
if name ~= new_name and vports then
-- Problem:
-- We need to place the new node first so that when turning
-- off some port, it won't stay on because the rules indicate
-- there is an onstate output port there.
-- When turning the output off then, it will however cause feedback
-- so that the luacontroller will receive an "off" event by turning
-- its output off.
-- Solution / Workaround:
-- Remember which output was turned off and ignore next "off" event.
local meta = minetest.get_meta(pos)
local ign = minetest.deserialize(meta:get_string("ignore_offevents")) or {}
if ports.a and not vports.a and not mesecon.is_powered(pos, rules.a) then ign.A = true end
if ports.b and not vports.b and not mesecon.is_powered(pos, rules.b) then ign.B = true end
if ports.c and not vports.c and not mesecon.is_powered(pos, rules.c) then ign.C = true end
if ports.d and not vports.d and not mesecon.is_powered(pos, rules.d) then ign.D = true end
meta:set_string("ignore_offevents", minetest.serialize(ign))
minetest.swap_node(pos, {name = new_name, param2 = node.param2})
if ports.a ~= vports.a then set_port(pos, rules.a, ports.a) end
@ -163,6 +180,19 @@ local function overheat(pos, meta)
end
end
------------------------
-- Ignored off events --
------------------------
local function ignore_event(event, meta)
if event.type ~= "off" then return false end
local ignore_offevents = minetest.deserialize(meta:get_string("ignore_offevents")) or {}
if ignore_offevents[event.pin.name] then
ignore_offevents[event.pin.name] = nil
meta:set_string("ignore_offevents", minetest.serialize(ignore_offevents))
return true
end
end
-------------------------
-- Parsing and running --
@ -361,6 +391,7 @@ end
local function run(pos, event)
local meta = minetest.get_meta(pos)
if overheat(pos) then return end
if ignore_event(event, meta) then return end
-- Load code & mem from meta
local mem = load_memory(meta)
@ -499,7 +530,7 @@ for d = 0, 1 do
rules = input_rules[cid],
action_change = function (pos, _, rule_name, new_state)
update_real_port_states(pos, rule_name, new_state)
run(pos, {type=new_state, pin=rule_name})
run(pos, {type=new_state, pin=rule_name})
end,
},
receptor = {