Skip to content

Commit d2373eb

Browse files
author
Jeija
committedNov 29, 2014
Don't trigger an "off" event to itself when luacontroller turns a port off
I hope this doesn't break anyone's setup.
1 parent 2a51e40 commit d2373eb

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed
 

‎mesecons/internal.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ function mesecon.is_powered(pos, rule)
598598
local nn = minetest.get_node(np)
599599
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
600600
or mesecon.is_receptor_on (nn.name)) then
601-
sourcepos.insert(np)
601+
table.insert(sourcepos, np)
602602
end
603603
end
604604
end

‎mesecons_luacontroller/init.lua

+32-1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,23 @@ local function set_port_states(pos, ports)
133133
local new_name = generate_name(ports)
134134

135135
if name ~= new_name and vports then
136+
-- Problem:
137+
-- We need to place the new node first so that when turning
138+
-- off some port, it won't stay on because the rules indicate
139+
-- there is an onstate output port there.
140+
-- When turning the output off then, it will however cause feedback
141+
-- so that the luacontroller will receive an "off" event by turning
142+
-- its output off.
143+
-- Solution / Workaround:
144+
-- Remember which output was turned off and ignore next "off" event.
145+
local meta = minetest.get_meta(pos)
146+
local ign = minetest.deserialize(meta:get_string("ignore_offevents")) or {}
147+
if ports.a and not vports.a and not mesecon.is_powered(pos, rules.a) then ign.A = true end
148+
if ports.b and not vports.b and not mesecon.is_powered(pos, rules.b) then ign.B = true end
149+
if ports.c and not vports.c and not mesecon.is_powered(pos, rules.c) then ign.C = true end
150+
if ports.d and not vports.d and not mesecon.is_powered(pos, rules.d) then ign.D = true end
151+
meta:set_string("ignore_offevents", minetest.serialize(ign))
152+
136153
minetest.swap_node(pos, {name = new_name, param2 = node.param2})
137154

138155
if ports.a ~= vports.a then set_port(pos, rules.a, ports.a) end
@@ -163,6 +180,19 @@ local function overheat(pos, meta)
163180
end
164181
end
165182

183+
------------------------
184+
-- Ignored off events --
185+
------------------------
186+
187+
local function ignore_event(event, meta)
188+
if event.type ~= "off" then return false end
189+
local ignore_offevents = minetest.deserialize(meta:get_string("ignore_offevents")) or {}
190+
if ignore_offevents[event.pin.name] then
191+
ignore_offevents[event.pin.name] = nil
192+
meta:set_string("ignore_offevents", minetest.serialize(ignore_offevents))
193+
return true
194+
end
195+
end
166196

167197
-------------------------
168198
-- Parsing and running --
@@ -361,6 +391,7 @@ end
361391
local function run(pos, event)
362392
local meta = minetest.get_meta(pos)
363393
if overheat(pos) then return end
394+
if ignore_event(event, meta) then return end
364395

365396
-- Load code & mem from meta
366397
local mem = load_memory(meta)
@@ -499,7 +530,7 @@ for d = 0, 1 do
499530
rules = input_rules[cid],
500531
action_change = function (pos, _, rule_name, new_state)
501532
update_real_port_states(pos, rule_name, new_state)
502-
run(pos, {type=new_state, pin=rule_name})
533+
run(pos, {type=new_state, pin=rule_name})
503534
end,
504535
},
505536
receptor = {

0 commit comments

Comments
 (0)
Please sign in to comment.