From a46f07cbfbd9ae59b7b1cc2fc32f68c39ae34de0 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Sat, 4 Mar 2017 23:58:38 -0500 Subject: updated digilines, framedglass, mesecons, pipeworks, quartz technic, unifiedinventory, and unifiedbricks --- digilines/internal.lua | 67 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 19 deletions(-) (limited to 'digilines/internal.lua') diff --git a/digilines/internal.lua b/digilines/internal.lua index 2319c16..45cd5d7 100644 --- a/digilines/internal.lua +++ b/digilines/internal.lua @@ -14,7 +14,7 @@ function digiline:importrules(spec, node) end function digiline:getAnyInputRules(pos) - local node = minetest.get_node(pos) + local node = digiline:get_node_force(pos) local spec = digiline:getspec(node) if not spec then return end @@ -27,7 +27,7 @@ function digiline:getAnyInputRules(pos) end function digiline:getAnyOutputRules(pos) - local node = minetest.get_node(pos) + local node = digiline:get_node_force(pos) local spec = digiline:getspec(node) if not spec then return end @@ -63,28 +63,57 @@ function digiline:rules_link_anydir(output, input) or digiline:rules_link(input, output) end -function digiline:transmit(pos, channel, msg, checked) - local checkedid = tostring(pos.x).."_"..tostring(pos.y).."_"..tostring(pos.z) - if checked[checkedid] then return end - checked[checkedid] = true +local function queue_new() + return {nextRead = 1, nextWrite = 1} +end - local node = minetest.get_node(pos) - local spec = digiline:getspec(node) - if not spec then return end +local function queue_empty(queue) + return queue.nextRead == queue.nextWrite +end +local function queue_enqueue(queue, object) + local nextWrite = queue.nextWrite + queue[nextWrite] = object + queue.nextWrite = nextWrite + 1 +end - -- Effector actions --> Receive - if spec.effector then - spec.effector.action(pos, node, channel, msg) - end +local function queue_dequeue(queue) + local nextRead = queue.nextRead + local object = queue[nextRead] + queue[nextRead] = nil + queue.nextRead = nextRead + 1 + return object +end - -- Cable actions --> Transmit - if spec.wire then - local rules = digiline:importrules(spec.wire.rules, node) - for _,rule in ipairs(rules) do - if digiline:rules_link(pos, digiline:addPosRule(pos, rule)) then - digiline:transmit(digiline:addPosRule(pos, rule), channel, msg, checked) +function digiline:transmit(pos, channel, msg, checked) + digiline:vm_begin() + local queue = queue_new() + queue_enqueue(queue, pos) + while not queue_empty(queue) do + local curPos = queue_dequeue(queue) + local node = digiline:get_node_force(curPos) + local spec = digiline:getspec(node) + if spec then + -- Effector actions --> Receive + if spec.effector then + spec.effector.action(curPos, node, channel, msg) + end + + -- Cable actions --> Transmit + if spec.wire then + local rules = digiline:importrules(spec.wire.rules, node) + for _, rule in ipairs(rules) do + local nextPos = digiline:addPosRule(curPos, rule) + if digiline:rules_link(curPos, nextPos) then + local checkedID = minetest.hash_node_position(nextPos) + if not checked[checkedID] then + checked[checkedID] = true + queue_enqueue(queue, nextPos) + end + end + end end end end + digiline:vm_end() end -- cgit v1.2.3