Skip "Press any key to continue" prompt from shell.openTab
BlackAsLight opened this issue ยท 5 comments
Useful information to include:
- Explanation of how the feature/change should work.
- Some rationale/use case for a feature. My general approach to designing new features is to ask yourself "what issue are we trying to solve" and then "is this the best way to solve this issue?".
When starting a command with shell.openTab('program path')
it opens a new shell as expected, but once that program is finished it prompts with "Press any key to continue". I'd like the ability to disable this prompt and it just exit and closes the tab automatically. My use case is that the main shell will open new tabs to process messages it receives over rednet so it doesn't risk missing a message while processing another.
After a bit of testing I don't think it would work. The documentation for this API could be improved though. It lacks what they return and what those values indicate.
parallel.waitForAny()
Returns the number, corresponding to their argument position, that finished.
parallel.waitForAll()
Returns the number, corresponding to their argument position, that took the longest to finish.
Also. parallel.waitForAny()
doesn't seem to ever go back to the one that took longer. So I can't see a way I could always be listening for an incoming message while processing another message happens. Not without calling parellel.waitForAll()
in one of the two functions passed in, and I don't know if that will create a scope issue after x amount of requests.
Ahh, this is because coroutines themselves don't know anything about events: you've got pass in the next event in the queue with coroutine.resume
. In your case, this'd look something like this:
local threads = {}
-- Create a new coroutine and run it it pulls an event for the first time.
local function add_thread(func)
local co = coroutine.create(func)
local ok, result = coroutine.resume(co)
if not ok then error(result, 0) end
table.insert(threads, { co = co, filter = result })
end
-- Add your main worker
add_thread(function()
while true do
print('Listening...')
local id, payload = rednet.receive(protocol)
-- As before...
end
end)
-- Run all threads
while #threads > 0 do
-- Pull the next event
local event = table.pack(os.pullEventRaw())
-- Then resume all threads with this event.
for i = #threads, 1, -1 do
local thread = threads[i]
if thread.filter == nil or thread.filter == event[1] or event[1] == "terminate" then
local ok, result = coroutine.resume(thread.co, table.unpack(event, 1, event.n))
if not ok then error(result, 0) end
if coroutine.status(thread.co) == "dead" then
table.remove(threads, i)
else
thread.filter = result
end
end
end
end
I should probably add a library to make this easier into CC itself.
I tried making something like this so I'd have some concurrency, but rednet.receive never seems to receive it at all. Removing the sleep in the last while loop seems to make it throw an error.
require('utils')
local protocol = 'DocCrafts'
local hostname = 'DocCrafts.com'
if not OpenRednet() then
os.exit(64)
end
rednet.host(protocol, hostname)
local function handle(id, payload)
sleep(1)
print(id, payload)
end
local i = 1
local max = 1
Threads = {
[1] = coroutine.create(function()
while true do
print('Listening...')
local id, payload = rednet.receive(protocol)
print(id, payload)
local thread = coroutine.create(handle)
table.insert(Threads, thread)
max = max + 1
coroutine.resume(Threads[max], id, payload)
end
end)
}
while i <= max do
print(i, coroutine.resume(Threads[i]))
if coroutine.status(Threads[i]) == 'dead' then
table.remove(Threads, i)
else
i = i + 1
if i > max then
i = i % max + 1
end
end
sleep(1 / 20)
end
Could you use the parallel
API to receive and process messages in parallel, rather than starting a new multishell tab?
Thanks. I ended up with this and it seems to work great.
local threads = {}
local function addThread(func, args)
args = args or table.pack()
local thread = coroutine.create(func)
local ok, result = coroutine.resume(thread, table.unpack(args, 1, args.n))
if not ok then
error(result, 0)
end
table.insert(threads, { thread = thread, filter = result })
end
local function handle(id, payload)
sleep(1)
print(id, payload)
end
addThread(function()
print('Listening...')
while true do
local id, payload = rednet.receive(protocol)
print('Received: ' .. id)
addThread(handle, table.pack(id, payload))
end
end)
while #threads > 0 do
local events = table.pack(os.pullEventRaw())
for i = #threads, 1, -1 do
if threads[i].filter == nil or threads[i].filter == events[1] or events[1] == 'terminate' then
local ok, result = coroutine.resume(threads[i].thread, table.unpack(events, 1, events.n))
if not ok then
error(result, 0)
end
if coroutine.status(threads[i].thread) == 'dead' then
table.remove(threads, i)
else
threads[i].filter = result
end
end
end
end