networks/control.lua

81 lines
2.4 KiB
Lua

--[[
Networks
========
Copyright (C) 2021 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Control API to control other network nodes which have a control interface
]]--
-- for lazy programmers
local S2P = minetest.string_to_pos
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local M = minetest.get_meta
local N = tubelib2.get_node_lvm
local CTL = function(pos) return (minetest.registered_nodes[N(pos).name] or {}).control end
networks.control = {}
-- return list of nodes {pos = ..., indir = ...} of given node_type
local function get_network_table(pos, tlib2, outdir, node_type)
local netw = networks.get_network_table(pos, tlib2, outdir)
if netw then
return netw[node_type] or {}
end
return {}
end
-------------------------------------------------------------------------------
-- For all types of nodes
-------------------------------------------------------------------------------
-- names: list of node names
-- control_callbacks = {
-- on_receive = function(pos, tlib2, topic, payload),
-- on_request = function(pos, tlib2, topic), -- returns: response
-- }
function networks.control.register_nodes(names, control_callbacks)
assert(type(control_callbacks) == "table")
for _, name in ipairs(names) do
minetest.override_item(name, {control = control_callbacks})
end
end
-- Send a message with 'topic' string and any 'payload 'to all 'tlib2' network
-- nodes of type 'node_type'.
-- Function returns the number of nodes the message was sent to.
function networks.control.send(pos, tlib2, outdir, node_type, topic, payload)
assert(outdir and node_type and topic)
assert(type(topic) == "string")
local cnt = 0
for _,item in ipairs(get_network_table(pos, tlib2, outdir, node_type)) do
local ctl = CTL(item.pos)
if ctl and ctl.on_receive then
ctl.on_receive(item.pos, tlib2, topic, payload)
cnt = cnt + 1
end
end
return cnt
end
-- Send a request with 'topic' string to all 'tlib2' network
-- nodes of type 'node_type'.
-- Function returns a list with all responses.
function networks.control.request(pos, tlib2, outdir, node_type, topic)
assert(outdir and node_type and topic)
assert(type(topic) == "string")
local t = {}
for _,item in ipairs(get_network_table(pos, tlib2, outdir, node_type)) do
local ctl = CTL(item.pos)
if ctl and ctl.on_request then
t[#t + 1] = ctl.on_request(item.pos, tlib2, topic)
end
end
return t
end