Prevent extra pin events with luacontrollers, microcontrollers, and FPGAs (#593)

This commit is contained in:
Jude Melton-Houghton 2022-02-27 15:12:37 -05:00 committed by GitHub
parent fef5c8cf68
commit 0d9e0274ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 20 deletions

View File

@ -114,8 +114,9 @@ plg.register_nodes({
effector = { effector = {
rules = {}, -- replaced later rules = {}, -- replaced later
action_change = function(pos, _, rule, newstate) action_change = function(pos, _, rule, newstate)
plg.ports_changed(pos, rule, newstate) if plg.ports_changed(pos, rule, newstate) then
plg.update(pos) plg.update(pos)
end
end end
} }
}, },
@ -326,8 +327,10 @@ plg.update = function(pos)
plg.setports(pos, A, B, C, D) plg.setports(pos, A, B, C, D)
end end
-- Updates the port states according to the signal change.
-- Returns whether the port states actually changed.
plg.ports_changed = function(pos, rule, newstate) plg.ports_changed = function(pos, rule, newstate)
if rule == nil then return end if rule == nil then return false end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local states local states
@ -347,10 +350,14 @@ plg.ports_changed = function(pos, rule, newstate)
local portno = ({4, 1, nil, 3, 2})[3 + rule.x + 2*rule.z] local portno = ({4, 1, nil, 3, 2})[3 + rule.x + 2*rule.z]
states[portno] = (newstate == "on") states[portno] = (newstate == "on")
meta:set_string("portstates", local new_portstates =
(states[1] and "1" or "0") .. (states[2] and "1" or "0") .. (states[1] and "1" or "0") .. (states[2] and "1" or "0") ..
(states[3] and "1" or "0") .. (states[4] and "1" or "0") (states[3] and "1" or "0") .. (states[4] and "1" or "0")
) if new_portstates ~= s then
meta:set_string("portstates", new_portstates)
return true
end
return false
end end
plg.getports = function(pos) -- gets merged states of INPUT & OUTPUT plg.getports = function(pos) -- gets merged states of INPUT & OUTPUT

View File

@ -43,13 +43,16 @@ local rules = {
------------------ ------------------
-- These helpers are required to set the port states of the luacontroller -- These helpers are required to set the port states of the luacontroller
-- Updates the real port states according to the signal change.
-- Returns whether the real port states actually changed.
local function update_real_port_states(pos, rule_name, new_state) local function update_real_port_states(pos, rule_name, new_state)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if rule_name == nil then if rule_name == nil then
meta:set_int("real_portstates", 1) meta:set_int("real_portstates", 1)
return return true
end end
local n = meta:get_int("real_portstates") - 1 local real_portstates = meta:get_int("real_portstates")
local n = real_portstates - 1
local L = {} local L = {}
for i = 1, 4 do for i = 1, 4 do
L[i] = n % 2 L[i] = n % 2
@ -66,12 +69,12 @@ local function update_real_port_states(pos, rule_name, new_state)
local port = pos_to_side[rule_name.x + (2 * rule_name.z) + 3] local port = pos_to_side[rule_name.x + (2 * rule_name.z) + 3]
L[port] = (new_state == "on") and 1 or 0 L[port] = (new_state == "on") and 1 or 0
end end
meta:set_int("real_portstates", local new_portstates = 1 + 1 * L[1] + 2 * L[2] + 4 * L[3] + 8 * L[4]
1 + if new_portstates ~= real_portstates then
1 * L[1] + meta:set_int("real_portstates", new_portstates)
2 * L[2] + return true
4 * L[3] + end
8 * L[4]) return false
end end
@ -826,8 +829,9 @@ for d = 0, 1 do
effector = { effector = {
rules = input_rules[cid], rules = input_rules[cid],
action_change = function (pos, _, rule_name, new_state) action_change = function (pos, _, rule_name, new_state)
update_real_port_states(pos, rule_name, new_state) if update_real_port_states(pos, rule_name, new_state) then
run(pos, {type=new_state, pin=rule_name}) run(pos, {type=new_state, pin=rule_name})
end
end, end,
}, },
receptor = { receptor = {

View File

@ -44,8 +44,9 @@ local mesecons = {effector =
{ {
rules = input_rules, rules = input_rules,
action_change = function (pos, node, rulename, newstate) action_change = function (pos, node, rulename, newstate)
yc.update_real_portstates(pos, node, rulename, newstate) if yc.update_real_portstates(pos, node, rulename, newstate) then
yc.update(pos) yc.update(pos)
end
end end
}} }}
if nodename ~= "mesecons_microcontroller:microcontroller0000" then if nodename ~= "mesecons_microcontroller:microcontroller0000" then
@ -655,13 +656,16 @@ yc.set_portstate = function(port, state, L)
return L return L
end end
-- Updates the real port states according to the signal change.
-- Returns whether the real port states actually changed.
yc.update_real_portstates = function(pos, _, rulename, newstate) yc.update_real_portstates = function(pos, _, rulename, newstate)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if rulename == nil then if rulename == nil then
meta:set_int("real_portstates", 1) meta:set_int("real_portstates", 1)
return return true
end end
local n = meta:get_int("real_portstates") - 1 local real_portstates = meta:get_int("real_portstates")
local n = real_portstates - 1
local L = {} local L = {}
for i = 1, 4 do for i = 1, 4 do
L[i] = n%2 L[i] = n%2
@ -676,7 +680,12 @@ yc.update_real_portstates = function(pos, _, rulename, newstate)
local port = ({4, 1, nil, 3, 2})[rulename.x+2*rulename.z+3] local port = ({4, 1, nil, 3, 2})[rulename.x+2*rulename.z+3]
L[port] = (newstate == "on") and 1 or 0 L[port] = (newstate == "on") and 1 or 0
end end
meta:set_int("real_portstates", 1 + L[1] + 2*L[2] + 4*L[3] + 8*L[4]) local new_portstates = 1 + L[1] + 2*L[2] + 4*L[3] + 8*L[4]
if new_portstates ~= real_portstates then
meta:set_int("real_portstates", new_portstates)
return true
end
return false
end end
yc.get_real_portstates = function(pos) -- determine if ports are powered (by itself or from outside) yc.get_real_portstates = function(pos) -- determine if ports are powered (by itself or from outside)