Skip to content

Commit 57a134b

Browse files
mesecons: Unify duplicated code
The new comments should help understanding what is going on to ease maintenance in the long-run. Co-authored-by: Jude Melton-Houghton <jwmhjwmh@gmail.com>
1 parent 4301f02 commit 57a134b

1 file changed

Lines changed: 42 additions & 75 deletions

File tree

mesecons/internal.lua

Lines changed: 42 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ function mesecon.get_any_rules(node)
9090
mesecon.get_any_outputrules(node))
9191
end
9292

93+
local function get_rules_from_ndef(ndef, node)
94+
local rules = ndef and ndef.rules
95+
if type(rules) == 'function' then
96+
return rules(node)
97+
elseif rules then
98+
return rules
99+
end
100+
return mesecon.rules.default
101+
end
102+
93103
-- Receptors
94104
-- Nodes that can power mesecons
95105
function mesecon.is_receptor_on(nodename)
@@ -117,17 +127,7 @@ function mesecon.is_receptor(nodename)
117127
end
118128

119129
function mesecon.receptor_get_rules(node)
120-
local receptor = mesecon.get_receptor(node.name)
121-
if receptor then
122-
local rules = receptor.rules
123-
if type(rules) == 'function' then
124-
return rules(node)
125-
elseif rules then
126-
return rules
127-
end
128-
end
129-
130-
return mesecon.rules.default
130+
return get_rules_from_ndef(mesecon.get_receptor(node.name), node)
131131
end
132132

133133
-- Effectors
@@ -157,16 +157,7 @@ function mesecon.is_effector(nodename)
157157
end
158158

159159
function mesecon.effector_get_rules(node)
160-
local effector = mesecon.get_effector(node.name)
161-
if effector then
162-
local rules = effector.rules
163-
if type(rules) == 'function' then
164-
return rules(node)
165-
elseif rules then
166-
return rules
167-
end
168-
end
169-
return mesecon.rules.default
160+
return get_rules_from_ndef(mesecon.get_effector(node.name), node)
170161
end
171162

172163
-- #######################
@@ -330,16 +321,7 @@ function mesecon.get_conductor_off(node_on, rulename)
330321
end
331322

332323
function mesecon.conductor_get_rules(node)
333-
local conductor = mesecon.get_conductor(node.name)
334-
if conductor then
335-
local rules = conductor.rules
336-
if type(rules) == 'function' then
337-
return rules(node)
338-
elseif rules then
339-
return rules
340-
end
341-
end
342-
return mesecon.rules.default
324+
return get_rules_from_ndef(mesecon.get_conductor(node.name), node)
343325
end
344326

345327
-- some more general high-level stuff
@@ -545,46 +527,42 @@ function mesecon.turnoff(pos, link)
545527
return true
546528
end
547529

548-
-- Get all linking inputrules of inputnode (effector or conductor) that is connected to
549-
-- outputnode (receptor or conductor) at position `output` and has an output in direction `rule`
550-
function mesecon.rules_link_rule_all(output, rule)
551-
local input = vector.add(output, rule)
552-
local inputnode = mesecon.get_node_force(input)
553-
local inputrules = mesecon.get_any_inputrules(inputnode)
554-
if not inputrules then
555-
return {}
530+
-- @param getter_function Function that returns nested rules (vectors)
531+
-- @return The matching rule or `nil`
532+
local function find_rule_in_rules(pos, rule, getter_function)
533+
local r_pos = vector.add(pos, rule)
534+
local r_node = mesecon.get_node_force(r_pos)
535+
local r_rules = getter_function(r_node)
536+
if not r_rules then
537+
return
556538
end
557-
local rules = {}
558539

559-
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
560-
-- Check if input accepts from output
561-
if vector.equals(vector.add(input, inputrule), output) then
562-
table.insert(rules, inputrule)
540+
local dir = vector.subtract(pos, r_pos)
541+
for _, r_rule in ipairs(mesecon.flattenrules(r_rules)) do
542+
if vector.equals(dir, r_rule) then
543+
-- Other matches are duplicates
544+
return r_rule
563545
end
564546
end
547+
end
565548

566-
return rules
549+
-- Get all linking inputrules of inputnode (effector or conductor) that is connected to
550+
-- outputnode (receptor or conductor) at position `output` and has an output in direction `rule`
551+
function mesecon.rules_link_rule_all(output, rule)
552+
local match = find_rule_in_rules(output, rule, mesecon.get_any_inputrules)
553+
return { match }
567554
end
568555

569556
-- Get all linking outputnodes of outputnode (receptor or conductor) that is connected to
570557
-- inputnode (effector or conductor) at position `input` and has an input in direction `rule`
571558
function mesecon.rules_link_rule_all_inverted(input, rule)
572-
local output = vector.add(input, rule)
573-
local outputnode = mesecon.get_node_force(output)
574-
local outputrules = mesecon.get_any_outputrules(outputnode)
575-
if not outputrules then
576-
return {}
577-
end
578-
local rules = {}
579-
580-
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
581-
if vector.equals(vector.add(output, outputrule), input) then
582-
table.insert(rules, mesecon.invertRule(outputrule))
583-
end
584-
end
585-
return rules
559+
local match = find_rule_in_rules(input, rule, mesecon.get_any_outputrules)
560+
return { match and mesecon.invertRule(match) }
586561
end
587562

563+
-- @param pos Node position (a vector) to check
564+
-- @param rule Optional. Specific rule (i.e. node side) to check.
565+
-- @return Returns a list of vectors that power `pos`, or `false` if unpowered.
588566
function mesecon.is_powered(pos, rule)
589567
local node = mesecon.get_node_force(pos)
590568
local rules = mesecon.get_any_inputrules(node)
@@ -593,26 +571,15 @@ function mesecon.is_powered(pos, rule)
593571
-- List of nodes that send out power to pos
594572
local sourcepos = {}
595573

596-
if not rule then
597-
for _, rule in ipairs(mesecon.flattenrules(rules)) do
598-
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
599-
for _, rname in ipairs(rulenames) do
600-
local np = vector.add(pos, rname)
601-
local nn = mesecon.get_node_force(np)
602-
603-
if (mesecon.is_conductor_on(nn, mesecon.invertRule(rname))
604-
or mesecon.is_receptor_on(nn.name)) then
605-
table.insert(sourcepos, np)
606-
end
607-
end
608-
end
609-
else
574+
local rules_flat = rule and { rule } or mesecon.flattenrules(rules)
575+
for _, rule in ipairs(rules_flat) do
610576
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
611577
for _, rname in ipairs(rulenames) do
612578
local np = vector.add(pos, rname)
613579
local nn = mesecon.get_node_force(np)
614-
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
615-
or mesecon.is_receptor_on (nn.name)) then
580+
581+
if (mesecon.is_conductor_on(nn, mesecon.invertRule(rname))
582+
or mesecon.is_receptor_on(nn.name)) then
616583
table.insert(sourcepos, np)
617584
end
618585
end

0 commit comments

Comments
 (0)