From fc74976f9c554ffa964dc0553acabc538bd67ed9 Mon Sep 17 00:00:00 2001 From: Jeija Date: Sun, 12 Aug 2012 23:02:38 +0200 Subject: [PATCH] Further (small) speed improvement, shrink code & more comments on it --- mesecons/init.lua | 16 +++- mesecons/internal_api.lua | 196 +++++++++++++++++++------------------- 2 files changed, 112 insertions(+), 100 deletions(-) diff --git a/mesecons/init.lua b/mesecons/init.lua index 78b84d9..0af1503 100644 --- a/mesecons/init.lua +++ b/mesecons/init.lua @@ -132,7 +132,19 @@ function mesecon:add_receptor_node_off(nodename, rules, get_rules) end function mesecon:receptor_on(pos, rules) - mesecon:turnon(pos, 0, 0, 0, true, rules) + if rules == nil then + rules = mesecon:get_rules("default") + end + + local i = 1 + while rules[i]~=nil do + local np = {} + np.x = pos.x + rules[i].x + np.y = pos.y + rules[i].y + np.z = pos.z + rules[i].z + mesecon:turnon(np) + i=i+1 + end end function mesecon:receptor_off(pos, rules) @@ -146,7 +158,7 @@ function mesecon:receptor_off(pos, rules) np.x = pos.x + rules[i].x np.y = pos.y + rules[i].y np.z = pos.z + rules[i].z - if mesecon:connected_to_pw_src(np, 0, 0, 0, {}) == false then + if not mesecon:connected_to_pw_src(np, {}) then mesecon:turnoff(np) end i=i+1 diff --git a/mesecons/internal_api.lua b/mesecons/internal_api.lua index acfe810..d382328 100644 --- a/mesecons/internal_api.lua +++ b/mesecons/internal_api.lua @@ -234,30 +234,29 @@ function mesecon:is_power_off(pos) return 0 end -function mesecon:turnon(p, x, y, z, firstcall, rules) - if rules==nil then - rules=mesecon:get_rules("default") - end - local lpos = {} - lpos.x=p.x+x - lpos.y=p.y+y - lpos.z=p.z+z +function mesecon:turnon(pos) + local node = minetest.env:get_node(pos) - mesecon:changesignal(lpos) - mesecon:activate(lpos) - - local node = minetest.env:get_node(lpos) if mesecon:is_conductor_off(node.name) then - minetest.env:add_node(lpos, {name=mesecon:get_conductor_on(node.name)}) - nodeupdate(lpos) - end - if mesecon:is_conductor_off(node.name) or firstcall then + minetest.env:add_node(pos, {name=mesecon:get_conductor_on(node.name)}) + nodeupdate(pos) + + rules = mesecon:get_rules("default") --TODO: Use rules of conductor local i=1 - while rules[i]~=nil do - mesecon:turnon(lpos, rules[i].x, rules[i].y, rules[i].z, false) + while rules[i]~=nil do + local np = {} + np.x = pos.x + rules[i].x + np.y = pos.y + rules[i].y + np.z = pos.z + rules[i].z + mesecon:turnon(np) i=i+1 end end + + mesecon:changesignal(pos) + if minetest.get_item_group(node.name, "mesecon_effector_off") == 1 then + mesecon:activate(pos) + end end function mesecon:turnoff(pos) @@ -267,8 +266,8 @@ function mesecon:turnoff(pos) minetest.env:add_node(pos, {name=mesecon:get_conductor_off(node.name)}) nodeupdate(pos) - rules = mesecon:get_rules("default") - local i=1 + rules = mesecon:get_rules("default") --TODO: Use ruels of conductor + local i = 1 while rules[i]~=nil do local np = {} np.x = pos.x + rules[i].x @@ -281,119 +280,116 @@ function mesecon:turnoff(pos) mesecon:changesignal(pos) --Changesignal is always thrown because nodes can be both receptors and effectors if minetest.get_item_group(node.name, "mesecon_effector_on") == 1 and - not mesecon:check_if_turnon(pos) then --Check if the signal comes from another source + not mesecon:is_powered(pos) then --Check if the signal comes from another source --Send Signals to effectors: mesecon:deactivate(pos) end end -function mesecon:connected_to_pw_src(pos, x, y, z, checked) - local i=1 - local lpos = {} +function mesecon:connected_to_pw_src(pos, checked) + local i = 1 + while checked[i] ~= nil do --find out if node has already been checked + if checked[i].x == pos.x and checked[i].y == pos.y and checked[i].z == pos.z then + return false + end + i = i + 1 + end + checked[i] = {x=pos.x, y=pos.y, z=pos.z} --add current node to checked - lpos.x=pos.x+x - lpos.y=pos.y+y - lpos.z=pos.z+z + local node = minetest.env:get_node_or_nil(pos) + if node == nil then return false end - - local node = minetest.env:get_node_or_nil(lpos) - - if not(node==nil) then - repeat - i=i+1 - if checked[i]==nil then checked[i]={} break end - if checked[i].x==lpos.x and checked[i].y==lpos.y and checked[i].z==lpos.z then - return false - end - until false - - checked[i].x=lpos.x - checked[i].y=lpos.y - checked[i].z=lpos.z - - if mesecon:is_receptor_node(node.name, lpos, pos) == true then -- receptor nodes (power sources) can be added using mesecon:add_receptor_node + if mesecon:is_conductor_on(node.name) or mesecon:is_conductor_off(node.name) then + if mesecon:is_powered_from_receptor(pos) then --return if conductor is powered return true end - if mesecon:is_conductor_on(node.name) then - local rules=mesecon:get_rules("default") - local i=1 - while rules[i]~=nil do - if mesecon:connected_to_pw_src(lpos, rules[i].x, rules[i].y, rules[i].z, checked) == true then return true end - i=i+1 - end + local rules = mesecon:get_rules("default") --TODO: Use conductor specific rules + local i = 1 + while rules[i] ~= nil do + local np = {} + np.x = pos.x + rules[i].x + np.y = pos.y + rules[i].y + np.z = pos.z + rules[i].z + if mesecon:connected_to_pw_src(np, checked) == true then + return true + end + i=i+1 end end return false end -function mesecon:check_if_turnon(pos) - local i=1 - local j=1 - local k=1 - local l=1 - local m=1 - local n=1 +function mesecon:is_powered_from_receptor(pos) local rcpt - local rcpt_pos={} - local rules + local rcpt_pos = {} + local rcpt_checked = {} --using a checked array speeds this up + local i = 1 + local j = 1 + local k = 1 + local pos_checked = false - rules=mesecon:get_rules("default") --Power form a on-conductor + while mesecon.rules[i]~=nil do + j=1 + while mesecon.rules[i].rules[j]~=nil do + rcpt_pos = { + x = pos.x-mesecon.rules[i].rules[j].x, + y = pos.y-mesecon.rules[i].rules[j].y, + z = pos.z-mesecon.rules[i].rules[j].z} + + k = 1 + pos_checked = false + while rcpt_checked[k] ~= nil do + if compare_pos(rcpt_checked[k], rcpt_pos) then + pos_checked = true + end + k = k + 1 + end + + if not pos_checked then + table.insert(rcpt_checked, rcpt_pos) + rcpt = minetest.env:get_node(rcpt_pos) + if mesecon:is_receptor_node(rcpt.name, rcpt_pos, pos) then + return true + end + end + j=j+1 + end + i=i+1 + end + return false +end + +function mesecon:is_powered_from_conductor(pos) + local k=1 + + rules=mesecon:get_rules("default") --TODO: use conductor specific rules while rules[k]~=nil do if mesecon:is_conductor_on(minetest.env:get_node({x=pos.x+rules[k].x, y=pos.y+rules[k].y, z=pos.z+rules[k].z}).name) then return true end k=k+1 end - - while mesecon.rules[i]~=nil do --Power from a receptor - j=1 - while mesecon.rules[i].rules[j]~=nil do - rcpt_pos={x=pos.x-mesecon.rules[i].rules[j].x, y=pos.y-mesecon.rules[i].rules[j].y, z=pos.z-mesecon.rules[i].rules[j].z} - rcpt=minetest.env:get_node(rcpt_pos) - if mesecon:is_receptor_node(rcpt.name, rcpt_pos, pos) then - return true - end - j=j+1 - end - i=i+1 - end - - --[[while mesecon.pwr_srcs[l]~= nil do - if mesecon.pwr_srcs[l].get_rules ~= nil then - rules = mesecon.pwr_srcs[l].get_rules("all") - - while rules[m]~=nil do - rcpt_pos = {x = pos.x-rules[j].x, y = pos.y-rules[j].y, z = pos.z-rules[j].z} - rcpt = minetest.env:get_node(rcpt_pos) - if rcpt.name == mesecon.pwr_srcs[l].name then --this name is always the onstate, offstate would be pwr_srcs_off - actual_rules = mesecon.pwr_srcs[l].get_rules(rcpt_pos) - if (actual_rules.x == rules.x and actual_rules.y == rules.y and actual_rules.z == rules.z) then - return true - end - end - m = m + 1 - end - end - l = l + 1 - end]] --that was rubbish - return false end +function mesecon:is_powered(pos) + return mesecon:is_powered_from_conductor(pos) or mesecon:is_powered_from_receptor(pos) +end + function mesecon:updatenode(pos) - if mesecon:connected_to_pw_src(pos, 0, 0, 0, {}) then - mesecon:turnon(pos, 0, 0, 0) + if mesecon:connected_to_pw_src(pos, {}) then + mesecon:turnon(pos) else mesecon:turnoff(pos) end end minetest.register_on_placenode(function(pos, newnode, placer) - if mesecon:check_if_turnon(pos) then + if mesecon:is_powered(pos) then if mesecon:is_conductor_off(newnode.name) then - mesecon:turnon(pos, 0, 0, 0) + mesecon:turnon(pos) else mesecon:changesignal(pos) mesecon:activate(pos) @@ -409,3 +405,7 @@ minetest.register_on_dignode( end end ) + +function compare_pos(pos1, pos2) + return pos1.x == pos2.x and pos1.y == pos2.y and pos1.z == pos2.z +end