diff --git a/event.lua b/event.lua index 5a8e7bd367f8..083a564bbf91 100644 --- a/event.lua +++ b/event.lua @@ -2,9 +2,7 @@ local network = require("network") local component = require("component") local event = {} - local addr_num = 0 -local last_msg = nil function event.listen(event, callback) if event ~= "modem_message" then @@ -12,18 +10,10 @@ function event.listen(event, callback) end addr = "A"..addr_num addr_num = addr_num + 1 - function ev_callback(ev, addr1, addr2, port, dist, msg) - last_msg = { - ev=ev, - addr1=addr1, - addr2=addr2, - port=port, - dist=dist, - msg=msg, - } + function ev_callback(ev, local_addr, ...) -- Inject local address so the check passes - component.modem.address = addr1 - callback(ev, addr1, addr2, port, dist, msg) + component.modem.address = local_addr + callback(ev, local_addr, ...) end network.register(addr, ev_callback) end @@ -35,27 +25,14 @@ function event.ignore(event, callback) network.deregister(network.get_scene()) end -function event.pull(event) - -- Just return the last message and hope it is the - -- right one ... - if last_msg == nil then - return nil - end - local lmsg = last_msg - last_msg = nil - return lmsg.ev, lmsg.addr1, lmsg.addr2, lmsg.port, lmsg.dist, lmsg.msg -end - function event.pullFiltered(timeout, filter) - if last_msg == nil then - return nil - end - local lmsg = last_msg - last_msg = nil - if filter(lmsg.ev, lmsg.addr1, lmsg.addr2, lmsg.port, lmsg.dist, lmsg.msg) then - return lmsg.ev, lmsg.addr1, lmsg.addr2, lmsg.port, lmsg.dist, lmsg.msg - else - return nil + while true do + local msg = table.pack(network.pull()) + if msg == nil then + return nil + elseif filter(table.unpack(msg)) then + return table.unpack(msg) + end end end diff --git a/network.lua b/network.lua index 519035913a9e..3cc4fdc66d88 100644 --- a/network.lua +++ b/network.lua @@ -4,6 +4,8 @@ local network = { local nodes = {} local active_node = {} +local latest_message = {} +local inject_message = {} function network.register(addr, callback) if nodes[addr] ~= nil then @@ -31,9 +33,16 @@ function network.send(addr, port, msg) 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 @@ -48,6 +57,33 @@ function network.broadcast(port, msg) 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) @@ -57,4 +93,15 @@ 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