From beddf124fc120407292c6f478215fa2b6f15adee Mon Sep 17 00:00:00 2001 From: payonel Date: Wed, 2 Sep 2015 15:11:14 -0700 Subject: [PATCH 01/11] remove useless locals, reduce processing with modem connection, support close all ports --- src/component/modem.lua | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/component/modem.lua b/src/component/modem.lua index ab088c4..b8f60e3 100644 --- a/src/component/modem.lua +++ b/src/component/modem.lua @@ -82,20 +82,15 @@ end function modem_host.datagramToPacketArray(datagram) compCheckArg(1,datagram,type("")) - local packed = ser.unserialize(datagram) - return packed + return ser.unserialize(datagram) end function modem_host.datagramToPacket(datagram) - local packed = modem_host.datagramToPacketArray(datagram) - local packet = modem_host.packedToPacket(packed) - return packet + return modem_host.packedToPacket(modem_host.datagramToPacketArray(datagram)) end function modem_host.packetToDatagram(packet) - local packed = modem_host.packetToPacketArray(packet) - local datagram = modem_host.packetArrayToDatagram(packed) - return datagram + return modem_host.packetArrayToDatagram(modem_host.packetToPacketArray(packet)) end function modem_host.readDatagram(client) -- client:receive() @@ -200,6 +195,12 @@ function modem_host.processPendingMessages() assert(modem_host.id) end + -- do not try to process anything if this machine is not even connected to a message board + -- not wrong without this, this is a simple optimization + if not modem_host.connected then + return + end + modem_host.recvPendingMessages() for _,packet in pairs(modem_host.messages) do @@ -380,11 +381,19 @@ function obj.close(port) -- Closes the specified port (default: all ports). Retu port=checkPort(port) end - if not obj.isOpen(port) then - return false; + -- nil port case + if not port then + if not next(modem_host.open_ports) then + return false, "no open ports" + else + modem_host.open_ports = {} -- close them all + end + elseif not obj.isOpen(port) then + return false, "port not open" + else + modem_host.open_ports[port] = nil end - modem_host.open_ports[port] = nil return true end From 03f5c34607560d8da7c1750bfcbe8a3182f2e85a Mon Sep 17 00:00:00 2001 From: payonel Date: Wed, 2 Sep 2015 15:14:09 -0700 Subject: [PATCH 02/11] move host id initialization to be called once --- src/component/modem.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/component/modem.lua b/src/component/modem.lua index b8f60e3..63da3b6 100644 --- a/src/component/modem.lua +++ b/src/component/modem.lua @@ -189,12 +189,6 @@ function modem_host.dispatchPacket(packet) end function modem_host.processPendingMessages() - -- computer address seems to be applied late - if not modem_host.id then - modem_host.id = component.list("computer",true)() - assert(modem_host.id) - end - -- do not try to process anything if this machine is not even connected to a message board -- not wrong without this, this is a simple optimization if not modem_host.connected then @@ -336,6 +330,12 @@ function modem_host.connectMessageBoard() modem_host.clients = {} modem_host.messages = {} + -- computer address seems to be applied late + if not modem_host.id then + modem_host.id = component.list("computer",true)() + assert(modem_host.id) + end + return true end From c1e8835b820cfd36e984e592d47e6e75057ea6e3 Mon Sep 17 00:00:00 2001 From: payonel Date: Wed, 2 Sep 2015 17:46:17 -0700 Subject: [PATCH 03/11] use gamax style code more with nil check and type strings --- src/component/modem.lua | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/component/modem.lua b/src/component/modem.lua index 63da3b6..4b9e218 100644 --- a/src/component/modem.lua +++ b/src/component/modem.lua @@ -24,14 +24,14 @@ modem_host.clients = {} -- [port_number] = true when open modem_host.open_ports = {} -function modem_host.createPacketArray(t, address, port, ...) - compCheckArg(1,t,type("")) - compCheckArg(2,address,type(""),type(0)) - compCheckArg(3,port,type(0)) +function modem_host.createPacketArray(packetType, address, port, ...) + compCheckArg(1,packetType,"string") + compCheckArg(2,address,"string","number") + compCheckArg(3,port,"number") local packed = { - t, + packetType, address, modem_host.id, port, @@ -43,7 +43,7 @@ function modem_host.createPacketArray(t, address, port, ...) end function modem_host.packetArrayToPacket(packed) - compCheckArg(1,packed,type({})) + compCheckArg(1,packed,"table") assert(#packed >= 5) local packet = {} @@ -62,7 +62,7 @@ function modem_host.packetArrayToPacket(packed) end function modem_host.packetArrayToDatagram(packed) - compCheckArg(1,packed,type({})) + compCheckArg(1,packed,"table") local datagram = ser.serialize(packed) return datagram .. '\n' @@ -81,7 +81,7 @@ function modem_host.packetToPacketArray(packet) end function modem_host.datagramToPacketArray(datagram) - compCheckArg(1,datagram,type("")) + compCheckArg(1,datagram,"string") return ser.unserialize(datagram) end @@ -101,13 +101,13 @@ end function modem_host.readPacketArray(client) -- client:receive() local datagram, err = modem_host.readDatagram(client) - if not datagram then return nil, err end + if datagram == nil then return nil, err end return modem_host.datagramToPacketArray(datagram) end function modem_host.readPacket(client) -- client:receive() local packed, err = modem_host.readPacketArray(client) - if not packed then return nil, err end + if packed == nil then return nil, err end return modem_host.packetArrayToPacket(packed) end @@ -219,12 +219,12 @@ function modem_host.recvPendingMessages() if modem_host.hosting then while true do local client = modem_host.socket:accept() - if not client then + if client == nil then break; end local handshake, err = modem_host.readPacket(client) -- client:receive() - if not handshake then + if handshake == nil then client:close() else @@ -331,7 +331,7 @@ function modem_host.connectMessageBoard() modem_host.messages = {} -- computer address seems to be applied late - if not modem_host.id then + if modem_host.id == nil then modem_host.id = component.list("computer",true)() assert(modem_host.id) end @@ -382,7 +382,7 @@ function obj.close(port) -- Closes the specified port (default: all ports). Retu end -- nil port case - if not port then + if port == nil then if not next(modem_host.open_ports) then return false, "no open ports" else From 8c548cfc3ddfc45a717730d91be7b2d642420f65 Mon Sep 17 00:00:00 2001 From: payonel Date: Thu, 3 Sep 2015 19:28:56 -0700 Subject: [PATCH 04/11] set sdl window to not grab mouse. this seems to be unnecessary most of the time, but not always. --- src/component/screen_sdl2.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/component/screen_sdl2.lua b/src/component/screen_sdl2.lua index 64b3d99..bdec8dd 100644 --- a/src/component/screen_sdl2.lua +++ b/src/component/screen_sdl2.lua @@ -102,6 +102,8 @@ local window, renderer, texture, copytexture local function createWindow() if not window then window = SDL.createWindow("OCEmu - screen@" .. address, SDL.WINDOWPOS_CENTERED, SDL.WINDOWPOS_CENTERED, width*8, height*16, SDL.WINDOW_SHOWN) + SDL.setWindowGrab(window, SDL.FALSE) + if window == ffi.C.NULL then error(ffi.string(SDL.getError())) end From b9fedc2da907e701e2fcc62c81de7ef31bd3ecf5 Mon Sep 17 00:00:00 2001 From: payonel Date: Thu, 3 Sep 2015 20:38:06 -0700 Subject: [PATCH 05/11] move address load a bit earlier in time for first use --- src/component/modem.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/component/modem.lua b/src/component/modem.lua index 4b9e218..7119f15 100644 --- a/src/component/modem.lua +++ b/src/component/modem.lua @@ -311,6 +311,12 @@ function modem_host.connectMessageBoard() return true end + -- computer address seems to be applied late + if modem_host.id == nil then + modem_host.id = component.list("computer",true)() + assert(modem_host.id) + end + local ok, info, critical = modem_host.joinExistingMessageBoard() if not ok and critical then @@ -330,12 +336,6 @@ function modem_host.connectMessageBoard() modem_host.clients = {} modem_host.messages = {} - -- computer address seems to be applied late - if modem_host.id == nil then - modem_host.id = component.list("computer",true)() - assert(modem_host.id) - end - return true end From cc4b06af67018956899b9d20e5872006c806d882 Mon Sep 17 00:00:00 2001 From: payonel Date: Thu, 3 Sep 2015 20:43:23 -0700 Subject: [PATCH 06/11] heavy logging for modem --- src/component/modem.lua | 59 +++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/src/component/modem.lua b/src/component/modem.lua index 7119f15..d6a8437 100644 --- a/src/component/modem.lua +++ b/src/component/modem.lua @@ -5,6 +5,23 @@ compCheckArg(1,wireless,"boolean") local socket = require("socket") local ser = require("loot.OpenOS.lib.serialization") +local function cerror(...) + local args = table.pack(...) + + local sep = '' + + for _,arg in ipairs(args) do + local p; + if (type(arg) == "userdata") then p = "userdata" + else p = ser.serialize(arg) end + io.stderr:write(p .. sep) + sep = '\t' + end + + io.stderr:write('\n') + io.stderr:flush() +end + -- yes, global modem_host = {} @@ -38,7 +55,7 @@ function modem_host.createPacketArray(packetType, address, port, ...) 0, -- distance ... } - + cerror("resultant packed", packed) return packed end @@ -95,7 +112,7 @@ end function modem_host.readDatagram(client) -- client:receive() local raw, err = client:receive() - if raw then cprint("received: " .. raw) end + if raw then cerror("received: " .. raw) end return raw, err end @@ -112,7 +129,7 @@ function modem_host.readPacket(client) -- client:receive() end function modem_host.sendDatagram(client, datagram) - cprint("sending: " .. datagram) + cerror("sending: " .. datagram) return client:send(datagram) end @@ -353,7 +370,6 @@ local function checkPort(port) end function obj.send(address, port, ...) -- Sends the specified data to the specified target. - cprint("modem.send",address, port, ...) compCheckArg(1,address,"string") compCheckArg(2,port,"number") port=checkPort(port) @@ -364,18 +380,15 @@ function obj.send(address, port, ...) -- Sends the specified data to the specifi end function obj.getWakeMessage() -- Get the current wake-up message. - cprint("modem.getWakeMessage") return wakeMessage end function obj.setWakeMessage(message) -- Set the wake-up message. - cprint("modem.setWakeMessage",message) compCheckArg(1,message,"string","nil") wakeMessage = message end function obj.close(port) -- Closes the specified port (default: all ports). Returns true if ports were closed. - cprint("modem.close",port) compCheckArg(1,port,"number","nil") if port ~= nil then port=checkPort(port) @@ -398,30 +411,25 @@ function obj.close(port) -- Closes the specified port (default: all ports). Retu end function obj.maxPacketSize() -- Gets the maximum packet size (config setting). - cprint("modem.maxPacketSize") return settings.maxNetworkPacketSize end if wireless then function obj.getStrength() -- Get the signal strength (range) used when sending messages. - cprint("modem.getStrength") return strength end function obj.setStrength(newstrength) -- Set the signal strength (range) used when sending messages. - cprint("modem.setStrength",newstrength) compCheckArg(1,newstrength,"number") strength = newstrength end end function obj.isOpen(port) -- Whether the specified port is open. - cprint("modem.isOpen",port) compCheckArg(1,port,"number") return modem_host.open_ports[port] ~= nil end function obj.open(port) -- Opens the specified port. Returns true if the port was opened. - cprint("modem.open",port) compCheckArg(1,port,"number") port=checkPort(port) @@ -441,12 +449,10 @@ function obj.open(port) -- Opens the specified port. Returns true if the port wa end function obj.isWireless() -- Whether this is a wireless network card. - cprint("modem.isWireless") return wireless end function obj.broadcast(port, ...) -- Broadcasts the specified data on the specified port. - cprint("modem.broadcast",port, ...) compCheckArg(1,port,"number") port=checkPort(port) @@ -476,4 +482,29 @@ local doc = { ["broadcast"]="function(port:number, data...) -- Broadcasts the specified data on the specified port.", } +local function containsValue(t, v) + for ek,ev in pairs(t) do + if ev == v then + return true + end + end + return false +end + +-- print all function calls +local function logAll(t, ...) + local ignores = table.pack(...) + for k,v in pairs(t) do + if (type(v) == "function") and not containsValue(ignores, k) then + t[k] = function(...) + cerror(k, ...) + return v(...) + end + end + end +end + +logAll(obj) +logAll(modem_host, "processPendingMessages", "recvPendingMessages") + return obj,cec,doc From 71e5adabd0d528773fd09e1af8a08c0db306e294 Mon Sep 17 00:00:00 2001 From: payonel Date: Thu, 3 Sep 2015 23:20:34 -0700 Subject: [PATCH 07/11] allow nils in modem message --- src/component/modem.lua | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/component/modem.lua b/src/component/modem.lua index d6a8437..8c7a9a0 100644 --- a/src/component/modem.lua +++ b/src/component/modem.lua @@ -10,12 +10,13 @@ local function cerror(...) local sep = '' - for _,arg in ipairs(args) do + for _,arg in pairs(args) do local p; if (type(arg) == "userdata") then p = "userdata" + elseif (type(arg) == "string") then p = arg else p = ser.serialize(arg) end - io.stderr:write(p .. sep) - sep = '\t' + io.stderr:write(sep .. tostring(_) .. '=' .. p) + sep = ',' end io.stderr:write('\n') @@ -55,6 +56,7 @@ function modem_host.createPacketArray(packetType, address, port, ...) 0, -- distance ... } + cerror("resultant packed", packed) return packed end @@ -71,8 +73,11 @@ function modem_host.packetArrayToPacket(packed) packet.distance = packed[5] packet.payload = {} - for i=6,#packed do - table.insert(packet.payload, packed[i]) + -- all other keys will be index values but may skip some (nils) + for k,v in pairs(packed) do + if k > 5 then + packet.payload[k-5] = v + end end return packet @@ -86,15 +91,22 @@ function modem_host.packetArrayToDatagram(packed) end function modem_host.packetToPacketArray(packet) - return + local packed = { packet.type, packet.target, packet.source, packet.port, packet.distance, - table.unpack(packet.payload or {}) } + + if packet.payload then + for i,v in pairs(packet.payload) do + packed[i+5] = v + end + end + + return packed end function modem_host.datagramToPacketArray(datagram) @@ -248,17 +260,17 @@ function modem_host.recvPendingMessages() local connectionResponse local accepted = false if handshake.type ~= "handshake" then - connectionResponse = modem_host.createPacketArray("handshake", modem_host.id, -1, + connectionResponse = modem_host.createPacketArray("handshake", 0, -1, false, "unsupported message type"); elseif modem_host.validTarget(handshake.source) then -- repeated client - connectionResponse = modem_host.createPacketArray("handshake", modem_host.id, -1, + connectionResponse = modem_host.createPacketArray("handshake", 0, -1, false, "computer address conflict detected, ignoring connection"); else client:settimeout(0, 't') modem_host.clients[handshake.source] = client accepted = true - connectionResponse = modem_host.createPacketArray("handshake", modem_host.id, -1, true); + connectionResponse = modem_host.createPacketArray("handshake", 0, -1, true); end modem_host.sendPacketArray(client, connectionResponse) @@ -505,6 +517,11 @@ local function logAll(t, ...) end logAll(obj) -logAll(modem_host, "processPendingMessages", "recvPendingMessages") +logAll(modem_host, + "processPendingMessages", + "recvPendingMessages", + "readDatagram", + "readPacket", + "readPacketArray") return obj,cec,doc From 49e5b8492f4852134389fa08cbda93aa3fa56206 Mon Sep 17 00:00:00 2001 From: payonel Date: Thu, 3 Sep 2015 23:24:52 -0700 Subject: [PATCH 08/11] clean up debug output for modem --- src/component/modem.lua | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/src/component/modem.lua b/src/component/modem.lua index 8c7a9a0..3b1b521 100644 --- a/src/component/modem.lua +++ b/src/component/modem.lua @@ -57,7 +57,6 @@ function modem_host.createPacketArray(packetType, address, port, ...) ... } - cerror("resultant packed", packed) return packed end @@ -124,7 +123,7 @@ end function modem_host.readDatagram(client) -- client:receive() local raw, err = client:receive() - if raw then cerror("received: " .. raw) end + if raw then cerror("readDatagram", raw) end return raw, err end @@ -141,7 +140,7 @@ function modem_host.readPacket(client) -- client:receive() end function modem_host.sendDatagram(client, datagram) - cerror("sending: " .. datagram) + cerror("sendDatagram", datagram) return client:send(datagram) end @@ -503,25 +502,4 @@ local function containsValue(t, v) return false end --- print all function calls -local function logAll(t, ...) - local ignores = table.pack(...) - for k,v in pairs(t) do - if (type(v) == "function") and not containsValue(ignores, k) then - t[k] = function(...) - cerror(k, ...) - return v(...) - end - end - end -end - -logAll(obj) -logAll(modem_host, - "processPendingMessages", - "recvPendingMessages", - "readDatagram", - "readPacket", - "readPacketArray") - return obj,cec,doc From bdee4aa7a5fdf9e4144871776a35a585029c52db Mon Sep 17 00:00:00 2001 From: payonel Date: Thu, 3 Sep 2015 23:40:33 -0700 Subject: [PATCH 09/11] remove unused method used during debuging --- src/component/modem.lua | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/component/modem.lua b/src/component/modem.lua index 3b1b521..0e1d756 100644 --- a/src/component/modem.lua +++ b/src/component/modem.lua @@ -493,13 +493,4 @@ local doc = { ["broadcast"]="function(port:number, data...) -- Broadcasts the specified data on the specified port.", } -local function containsValue(t, v) - for ek,ev in pairs(t) do - if ev == v then - return true - end - end - return false -end - return obj,cec,doc From 3be687ef9117fce42dc7875d254923807e9d4ac1 Mon Sep 17 00:00:00 2001 From: payonel Date: Fri, 11 Sep 2015 20:58:17 -0700 Subject: [PATCH 10/11] improve shutdown of host by sending out notice to clients --- src/component/modem.lua | 105 ++++++++++++++++++++++++++++++---------- src/main.lua | 2 + 2 files changed, 82 insertions(+), 25 deletions(-) diff --git a/src/component/modem.lua b/src/component/modem.lua index 0e1d756..7917bd7 100644 --- a/src/component/modem.lua +++ b/src/component/modem.lua @@ -155,33 +155,37 @@ function modem_host.sendPacket(client, packet) end function modem_host.broadcast(packet) - -- only host broadcasts - -- this method will be hit for all broadcasted messages - -- but nonhosting clients will simply not repeat the broadcast + -- we assume packet.target == 0 if modem_host.hosting then - local datagram = modem_host.packetToDatagram(packet) for addr,client in pairs(modem_host.clients) do - modem_host.sendDatagram(client, datagram) + packet.target = addr + modem_host.sendPacket(client, packet) end + -- and self + packet.target = modem_host.id + modem_host.dispatchPacket(packet) + else + -- let host broadcast to all clients + modem_host.sendPacket(modem_host.socket, packet) end end function modem_host.validTarget(target) if target == 0 then - return true + return true -- broadcast end if target == modem_host.id then - return true + return true -- dispatch will add to machine signals end if not modem_host.hosting then - return false + return true -- dispatch can handle sending to host end for address,client in pairs(modem_host.clients) do if address == target then - return true + return true -- we are hosting and know about this target end end @@ -201,9 +205,9 @@ end function modem_host.dispatchPacket(packet) if packet.target == modem_host.id then - if obj.isOpen(packet.port) then - table.insert(machine.signals, modem_host.packetToPacketArray(packet)) - end + if obj.isOpen(packet.port) then + table.insert(machine.signals, modem_host.packetToPacketArray(packet)) + end elseif modem_host.hosting then -- if hosting we will route for source,client in pairs(modem_host.clients) do if source == packet.target then @@ -223,27 +227,27 @@ function modem_host.processPendingMessages() return end + modem_host.acceptPendingClients() modem_host.recvPendingMessages() - for _,packet in pairs(modem_host.messages) do + for _,packet in ipairs(modem_host.messages) do if packet.type == 'modem_message' then -- broadcast if no target if packet.target == 0 then - modem_host.broadcast(packet) -- ignored by clients - - -- clean up for broadcasting to self - packet.target = modem_host.id + modem_host.broadcast(packet) + else + modem_host.dispatchPacket(packet) end - - modem_host.dispatchPacket(packet) + elseif packet.type == 'host_shutdown' then + modem_host.host_shutdown = true end end modem_host.messages = {} end -function modem_host.recvPendingMessages() +function modem_host.acceptPendingClients() if modem_host.hosting then while true do local client = modem_host.socket:accept() @@ -279,8 +283,11 @@ function modem_host.recvPendingMessages() end end end + end +end - -- recv all pending packets +function modem_host.recvPendingMessages() + if modem_host.hosting then for source, client in pairs(modem_host.clients) do local packet, err = modem_host.readPacket(client) if packet then @@ -296,6 +303,13 @@ function modem_host.recvPendingMessages() if packet then modem_host.pushMessage(packet) else + if err ~= "timeout" then + if not modem_host.host_shutdown then + error("modem host was unexpectedly lost") + end + modem_host.connected = false + modem_host.connectMessageBoard() + end break end end @@ -339,6 +353,15 @@ function modem_host.connectMessageBoard() return true end + if modem_host.host_shutdown then + modem_host.socket:close() + end + + modem_host.socket = nil + modem_host.clients = {} + modem_host.messages = {} + modem_host.host_shutdown = nil + -- computer address seems to be applied late if modem_host.id == nil then modem_host.id = component.list("computer",true)() @@ -361,12 +384,37 @@ function modem_host.connectMessageBoard() modem_host.socket:settimeout(0, 't') -- accept calls must be already pending modem_host.connected = true - modem_host.clients = {} - modem_host.messages = {} return true end +function modem_host.halt(bReboot) + compCheckArg(1,bReboot,"boolean") + obj.close() -- close all virtual ports + + -- if only rebooting, pending messages don't need to be pumped and no one needs to be notified + if modem_host.connected and not bReboot then + + if modem_host.hosting then + for addr,csocket in pairs(modem_host.clients) do + local notification = modem_host.createPacketArray("host_shutdown", addr, -1); + modem_host.sendPacketArray(csocket, notification) + end + + -- close all client connections + for _,c in pairs(modem_host.clients) do + c:close() + end + + modem_host.hosting = false + modem_host.clients = {} -- forget client socket data + end + + -- close real port + modem_host.socket:close() + end +end + local wakeMessage local strength if wireless then @@ -385,9 +433,15 @@ function obj.send(address, port, ...) -- Sends the specified data to the specifi compCheckArg(2,port,"number") port=checkPort(port) + -- we cannot send unless we are connected to the message board + if not modem_host.connectMessageBoard() then + return false + end + local packed = modem_host.createPacketArray("modem_message", address, port, ...) local packet = modem_host.packetArrayToPacket(packed) - return modem_host.dispatchPacket(packet) + modem_host.pushMessage(packet) + return true end function obj.getWakeMessage() -- Get the current wake-up message. @@ -474,7 +528,8 @@ function obj.broadcast(port, ...) -- Broadcasts the specified data on the specif local packed = modem_host.createPacketArray("modem_message", 0, port, ...) local packet = modem_host.packetArrayToPacket(packed) - return modem_host.dispatchPacket(packet) + modem_host.pushMessage(packet) + return true end local cec = {} diff --git a/src/main.lua b/src/main.lua index ca8beb6..6ef0bf8 100644 --- a/src/main.lua +++ b/src/main.lua @@ -294,8 +294,10 @@ function resume_thread(...) machine.deadline = elsa.timer.getTime() + results[2] elseif type(results[2]) == "boolean" then if results[2] then + modem_host.halt(true) boot_machine() else + modem_host.halt(false) elsa.quit() error("Machine power off",0) end From 62c6e78e9196f723e321da1baa2498c9955dac76 Mon Sep 17 00:00:00 2001 From: payonel Date: Fri, 11 Sep 2015 21:20:37 -0700 Subject: [PATCH 11/11] use iterator for pending messages to process messages as they come in --- src/component/modem.lua | 60 ++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/src/component/modem.lua b/src/component/modem.lua index 7917bd7..90c8e51 100644 --- a/src/component/modem.lua +++ b/src/component/modem.lua @@ -228,10 +228,8 @@ function modem_host.processPendingMessages() end modem_host.acceptPendingClients() - modem_host.recvPendingMessages() - - for _,packet in ipairs(modem_host.messages) do + for _,packet in modem_host.allPendingMessages() do if packet.type == 'modem_message' then -- broadcast if no target if packet.target == 0 then @@ -243,8 +241,6 @@ function modem_host.processPendingMessages() modem_host.host_shutdown = true end end - - modem_host.messages = {} end function modem_host.acceptPendingClients() @@ -286,34 +282,42 @@ function modem_host.acceptPendingClients() end end -function modem_host.recvPendingMessages() - if modem_host.hosting then - for source, client in pairs(modem_host.clients) do - local packet, err = modem_host.readPacket(client) - if packet then - modem_host.pushMessage(packet) - elseif err ~= "timeout" then - client:close() - modem_host.clients[source] = nil - end +function modem_host.allPendingMessages() + local msgIt = function(...) + if #modem_host.messages > 0 then + return 0, table.remove(modem_host.messages, 1) end - elseif modem_host.socket then - while true do - local packet, err = modem_host.readPacket(modem_host.socket) - if packet then - modem_host.pushMessage(packet) - else - if err ~= "timeout" then - if not modem_host.host_shutdown then - error("modem host was unexpectedly lost") - end - modem_host.connected = false - modem_host.connectMessageBoard() + + if modem_host.hosting then + for source, client in pairs(modem_host.clients) do + local packet, err = modem_host.readPacket(client) + if packet then + return 0, packet + elseif err ~= "timeout" then + client:close() + modem_host.clients[source] = nil + end + end + elseif modem_host.socket then + while true do + local packet, err = modem_host.readPacket(modem_host.socket) + if packet then + return 0, packet + else + if err ~= "timeout" then + if not modem_host.host_shutdown then + error("modem host was unexpectedly lost") + end + modem_host.connected = false + modem_host.connectMessageBoard() + end + break end - break end end end + + return msgIt, nil, 0 end function modem_host.createNewMessageBoard()