digilines/internal.lua

127 lines
3.1 KiB
Lua
Raw Normal View History

2017-03-01 11:26:20 +01:00
function digilines.getspec(node)
local def = minetest.registered_nodes[node.name]
if not def then return false end
return def.digilines or def.digiline
2013-01-20 00:03:51 +01:00
end
2017-03-01 11:26:20 +01:00
function digilines.importrules(spec, node)
2013-01-20 00:03:51 +01:00
if type(spec) == 'function' then
return spec(node)
elseif spec then
return spec
else
return digilines.rules.default
2013-01-20 00:03:51 +01:00
end
end
2017-03-01 11:26:20 +01:00
function digilines.getAnyInputRules(pos)
local node = digilines.get_node_force(pos)
local spec = digilines.getspec(node)
2013-01-20 00:03:51 +01:00
if not spec then return end
if spec.wire then
2017-03-01 11:26:20 +01:00
return digilines.importrules(spec.wire.rules, node)
2013-01-20 00:03:51 +01:00
end
if spec.effector then
2017-03-01 11:26:20 +01:00
return digilines.importrules(spec.effector.rules, node)
2013-01-20 00:03:51 +01:00
end
end
2017-03-01 11:26:20 +01:00
function digilines.getAnyOutputRules(pos)
local node = digilines.get_node_force(pos)
local spec = digilines.getspec(node)
2013-01-20 00:03:51 +01:00
if not spec then return end
if spec.wire then
2017-03-01 11:26:20 +01:00
return digilines.importrules(spec.wire.rules, node)
2013-01-20 00:03:51 +01:00
end
if spec.receptor then
2017-03-01 11:26:20 +01:00
return digilines.importrules(spec.receptor.rules, node)
2013-01-20 00:03:51 +01:00
end
end
2017-03-01 11:26:20 +01:00
function digilines.rules_link(output, input)
local outputrules = digilines.getAnyOutputRules(output)
local inputrules = digilines.getAnyInputRules (input)
2013-01-20 00:03:51 +01:00
if not outputrules or not inputrules then return false end
for _, orule in ipairs(outputrules) do
2017-03-01 11:26:20 +01:00
if digilines.cmpPos(digilines.addPosRule(output, orule), input) then
2013-01-20 00:03:51 +01:00
for _, irule in ipairs(inputrules) do
2017-03-01 11:26:20 +01:00
if digilines.cmpPos(digilines.addPosRule(input, irule), output) then
2013-01-20 00:03:51 +01:00
return true
end
end
end
end
return false
end
2017-03-01 11:26:20 +01:00
function digilines.rules_link_anydir(output, input)
return digilines.rules_link(output, input)
or digilines.rules_link(input, output)
2013-01-20 00:03:51 +01:00
end
local function queue_new()
return {nextRead = 1, nextWrite = 1}
end
2013-01-20 00:03:51 +01:00
local function queue_empty(queue)
return queue.nextRead == queue.nextWrite
end
2013-01-20 00:03:51 +01:00
local function queue_enqueue(queue, object)
local nextWrite = queue.nextWrite
queue[nextWrite] = object
queue.nextWrite = nextWrite + 1
end
2013-01-20 00:03:51 +01:00
local function queue_dequeue(queue)
local nextRead = queue.nextRead
local object = queue[nextRead]
queue[nextRead] = nil
queue.nextRead = nextRead + 1
return object
end
2013-01-20 00:03:51 +01:00
2017-03-01 11:26:20 +01:00
function digilines.transmit(pos, channel, msg, checked)
local checkedID = minetest.hash_node_position(pos)
if checked[checkedID] then
return
end
checked[checkedID] = true
2017-03-01 11:26:20 +01:00
digilines.vm_begin()
local queue = queue_new()
queue_enqueue(queue, pos)
while not queue_empty(queue) do
local curPos = queue_dequeue(queue)
2017-03-01 11:26:20 +01:00
local node = digilines.get_node_force(curPos)
local spec = digilines.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
2017-03-01 11:26:20 +01:00
local rules = digilines.importrules(spec.wire.rules, node)
for _, rule in ipairs(rules) do
2017-03-01 11:26:20 +01:00
local nextPos = digilines.addPosRule(curPos, rule)
if digilines.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
2013-01-20 00:03:51 +01:00
end
end
end
2017-03-01 11:26:20 +01:00
digilines.vm_end()
2013-01-20 00:03:51 +01:00
end