io.read() works by waiting for key/char events, and while it's executing, any other events (eg modem_messages) it pulls from the queue it simply discards.
The
parallel API is the way to go here. That allows you to pass it multiple functions, which it'll run side-by-side: Whenever one yields (to pull event), it may pass control to the other (depending on whether it has a suitable event for it). All events get passed to both functions, so you can have one looking for only events of one type, another looking for events of only another type, and the two won't interfere.
You could, alternatively, build a single loop that listens for all event types and handles all of those you're interested in manually. Catch is you'd need to re-write io.read() from the ground up that way. The parallel API serves as a shortcut, but isn't
always the best way to do this sort of thing.
Your next problem is managing the display: Say the user is midway through typing something, and suddenly you want to print a message that arrived via rednet. You need to pay attention to where io.read() had the cursor, go off and write the new message, and then put the cursor back!
The
window API makes this sort of thing a little easier: You can actually divide up your screen real-estate into multiple "virtual" screens. When you factor in that your message area is eventually going to want to start scrolling, this makes it much easier to stop it from interfering with your typing area.
Here's a skeleton of the sort of structure you might use:
-- Open modem etc
local xSize, ySize = term.getSize()
local messageWindow = window.create(term.current(), 1, 1, xSize, ySize - 1)
local typingWindow = window.create(term.current(), 1, ySize, xSize, 1)
local function typeMessage()
while true do
modem.transmit(23,23,read())
end
end
local function receiveMessages()
while true do
local event,modemside,senderChannel,replyChanne,message,senderDistance = os.pullEvent("modem_message")
term.redirect(messageWindow)
print(message)
term.redirect(typingWindow)
typingWindow.restoreCursor()
end
end
term.redirect(typingWindow)
parallel.waitForAny(typeMessage, receiveMessages)