71 posts
Location
Everywhere and nowhere.
Posted 27 August 2017 - 02:07 PM
I am making a new OS that is mostly focused on multi-tasking. I am trying to figure out how I can run programs inside the window.
Please help! (;
7083 posts
Location
Tasmania (AU)
Posted 27 August 2017 - 02:15 PM
A good start is to read through
multishell's source. Note that you'll need a fairly solid understanding
as to how ComputerCraft's event system makes use of coroutines.
Edited on 27 August 2017 - 12:15 PM
467 posts
Location
Van Diemen's Land
Posted 28 August 2017 - 05:29 AM
Basically what you do is you create a window (or 2, or 3 or however many) and have each of them running a different coroutine.
Coroutines are based on functions, so you can run a program in a function. Then you can create a window and redirect to the window, then resume the coroutine. See below:
local function run1()
shell.run("/rom/programs/shell")
end
local function run2()
shell.run("/rom/programs/shell")
end
local cor1 = coroutine.create(run1)
local cor2 = coroutine.create(run2)
local selectedWindow = nil -- You need to create 2 windows, then select which one you want here
local selectedCoroutine = cor1
local e = {}
while true do
term.redirect(selectedWindow)
coroutine.resume(selectedCoroutine, unpack(e))
e = { os.pullEvent() }
end
That should get you started (I didn't test it, but it should be on the right track). You do need to create the windows.
There are multiple ways you could swap between the windows. Either a key press, mouse click (click inside a window to select it which is what my djOS has) or even a timer if you really wanted to.
Edited on 28 August 2017 - 03:32 AM
7083 posts
Location
Tasmania (AU)
Posted 28 August 2017 - 06:33 AM
That should get you started (I didn't test it, but it should be on the right track).
Checking event filters is fairly important. You can't just resume any coroutine with any event.
467 posts
Location
Van Diemen's Land
Posted 28 August 2017 - 07:19 AM
That should get you started (I didn't test it, but it should be on the right track).
Checking event filters is fairly important. You can't just resume any coroutine with any event.
Correct, but he will quickly realise that when his shells start picking up all this random event catching. HOWEVER, the shells will only pick up the events they put down. You might notice that that program doesn't have any code running except for themselves (the 2 shells, and they only pass their own events, for now). Once there are timers and things that are meant to run inside their own windows that's when it will be an issue, however my djOS didn't have that issue very bad at all.
797 posts
Posted 30 August 2017 - 08:57 PM
I think Bomb Bloke is referring to how os.pullEvent("key") calls coroutine.yield("key") and expects the resumer to only resume it with a "key" event. You should have an event filter variable associated with each coroutine, that's checked before resuming the coroutine.
Like this…
local co1, filter1 = coroutine.create( func )
local ev = { opening_params, ... }
local ok
while true do
if not filter1 or filter1 == ev[1] then
-- redirection stuff
ok, data = coroutine.resume( co1, unpack( ev ) )
-- end redirection stuff
if not ok then
error( data, 0 )
else
filter1 = data
end
end
ev = { coroutine.yield() }
end