local network = { allow_blackhole = false, } local nodes = {} local active_node = {} local latest_message = {} local inject_message = {} function network.register(addr, callback) if nodes[addr] ~= nil then error("Address "..addr.." already registered!") end nodes[addr] = callback active_node = {} table.insert(active_node, addr) end function network.deregister(addr) nodes[addr] = nil end function network.send(addr, port, msg) local callback = nodes[addr] if callback == nil then if not network.allow_blackhole then error("Send message to offline node: "..tostring(addr)) end return nil end local current_node = active_node[#active_node] -- Push target onto node-stack table.insert(active_node, addr) -- print("Sending from "..current_node.." to "..addr..": "..msg) -- print(require("inspect").inspect(active_node)) latest_message[addr] = { from=current_node, port=port, msg=msg, } callback("modem_message", addr, current_node, port, 0, msg) -- Remove again active_node[#active_node] = nil end function network.broadcast(port, msg) local current_node = active_node[#active_node] -- print("Broadcasting from "..current_node) for addr in pairs(nodes) do if addr ~= current_node then network.send(addr, port, msg) end end end function network.pull() local current_node = active_node[#active_node] if inject_message[current_node] ~= nil and #inject_message[current_node] > 0 then local message = inject_message[current_node][1] table.remove(inject_message[current_node], 1) -- print("pulled "..require("serialization").serialize(message)) -- Actually send the injected message now table.insert(active_node, message.from) network.send(current_node, message.port, message.msg) active_node[#active_node] = nil return "modem_message", current_node, message.from, message.port, 0, message.msg end if latest_message[current_node] == nil then error("Tried to pull while no message was available") end local message = latest_message[current_node] -- Delete message latest_message[current_node] = nil return "modem_message", current_node, message.from, message.port, 0, message.msg end function network.set_scene(addr) active_node = {} table.insert(active_node, addr) end function network.get_scene(addr) return active_node[#active_node] end function network.inject(addr, from, port, msg) if inject_message[addr] == nil then inject_message[addr] = {} end table.insert(inject_message[addr], { from=from, port=port, msg=msg, }) end return network