This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
H4X0RZ's profile picture

I can redirect my own program, but not the standard ones to a/the buffer.

Started by H4X0RZ, 22 July 2015 - 03:03 PM
H4X0RZ #1
Posted 22 July 2015 - 05:03 PM
I'm working on some kind of shell currently (practicing Lua and stuff like that) and I stumbled upon a big problem.

In main.lua I'm redirecting bar.lua and shell.lua to their corresponding buffers. (line 28 and 29).
If I change line 28 (the one for the shell) to
 redirector.addProgram("rom/programs/shell",shellBuffer.buffer,"Shell")
It just says "No such program". When I change it so it runs "edit", the buffer stays completely black.

why is this happening?

Greetings,
H4X0RZ

#EDIT:
Note: I'm using Grim's buffer API.
Edited on 22 July 2015 - 03:22 PM
Bomb Bloke #2
Posted 23 July 2015 - 03:05 AM
Your coroutine managers are busted. You can't just pull events and resume coroutines with them - you need to pay attention to whether those coroutines are asking for certain sorts of events, and ensure that if they are, you only resume them with events of that type. Eg.
Balthamel #3
Posted 23 July 2015 - 04:02 AM
That link is so horrific to read bombbloke, i stuck it on pastebin.
http://pastebin.com/T4wBG4SW
MKlegoman357 #4
Posted 23 July 2015 - 05:44 AM
You have to remember there are always these three conditions of when to resume a coroutine in CC. Only one of them has to be true:

  1. the event is 'terminate'
  2. the event filter of the coroutine is nil
  3. the event is equal to the event filter of the coroutine
H4X0RZ #5
Posted 23 July 2015 - 12:44 PM
Your coroutine managers are busted. You can't just pull events and resume coroutines with them - you need to pay attention to whether those coroutines are asking for certain sorts of events, and ensure that if they are, you only resume them with events of that type. Eg.

You have to remember there are always these three conditions of when to resume a coroutine in CC. Only one of them has to be true:

  1. the event is 'terminate'
  2. the event filter of the coroutine is nil
  3. the event is equal to the event filter of the coroutine

Oh! I totally forgot about the event filters. Thanks a lot!
H4X0RZ #6
Posted 23 July 2015 - 05:57 PM
Short question:

Is it a bad idea to run multiple coroutine managers?

#EDIT: I also fixed the event filters, but the shell still errors with "No such program", but I am able to run other programs like worm and multishell…

I think I should just make my own shell for this, and block the rom. This should be much easier than recoding my code until the standard programs can run on it.
Edited on 23 July 2015 - 04:11 PM
KingofGamesYami #7
Posted 23 July 2015 - 07:38 PM
Short question:

Is it a bad idea to run multiple coroutine managers?

Not really, if you use parallel and are on an advanced computer, that's already two coroutine managers running.
Bomb Bloke #8
Posted 24 July 2015 - 01:16 AM
Not really, if you use parallel and are on an advanced computer, that's already two coroutine managers running.

Three - each system is a coroutine being executed by the one Lua VM, multishell for advanced computers adds another, and parallel adds another.

I'd imagine each cuts into the function stack, so you'd technically be better off keeping the count down, but the odds of a completely filling the stack are pretty slim (assuming no infinite recursive calls, which'll fail no matter what you do), so it makes next to no difference.
Lyqyd #9
Posted 24 July 2015 - 02:15 AM
Plus the parallel call to run the rednet coroutine.
Bomb Bloke #10
Posted 24 July 2015 - 03:11 AM
*facepalm* …. Four.
H4X0RZ #11
Posted 24 July 2015 - 03:21 AM
So, anyone knows why "rom/programs/shell" errors with "No such program"?
Bomb Bloke #12
Posted 24 July 2015 - 04:02 AM
Sorry, I should've elaborated. Notice the use of the "myArg" variable in the code example I referred to?

The first time you resume a coroutine, it initiates the associated function with the resume parameters. Eg:

local function myFunc(text)
  print(text)
end

local myCo = coroutine.create(myFunc)

coroutine.resume(myCo, "Hello, World!")  --> Prints "Hello, World!".

If shell is passed a parameter when you launch it, then it attempts to run it. Your current setup is likely having it trying to find a script file called "key_up" or somesuch.

Simple fix is to redirect to your buffer and perform a single coroutine resume in redirector.addProgram():

function addProgram(path,buffer,name)
	assert(fs.exists(path),"Nope.")
	local f = loadstring("os.run({},'"..path.."')")
	local co = coroutine.create(f)
	term.redirect(buffer.tRedirect)
	local ok, filter = coroutine.resume(co)
	programs[name] = {name=name,routine=co,buffer=buffer,enabled=true,filter=filter}
end

I see that you've mostly finished correcting the rest of the event handling side of things, but you'll probably want to add handling for dead coroutines. The other issue is that some events really should be pushed through regardless as to whether a process is "enabled" - timers, for example. Pretty much anything that isn't user input, really.
Edited on 24 July 2015 - 02:06 AM
H4X0RZ #13
Posted 24 July 2015 - 05:06 AM
Sorry, I should've elaborated. Notice the use of the "myArg" variable in the code example I referred to?

The first time you resume a coroutine, it initiates the associated function with the resume parameters. Eg:

local function myFunc(text)
  print(text)
end

local myCo = coroutine.create(myFunc)

coroutine.resume(myCo, "Hello, World!")  --> Prints "Hello, World!".

If shell is passed a parameter when you launch it, then it attempts to run it. Your current setup is likely having it trying to find a script file called "key_up" or somesuch.

Simple fix is to redirect to your buffer and perform a single coroutine resume in redirector.addProgram():

function addProgram(path,buffer,name)
	assert(fs.exists(path),"Nope.")
	local f = loadstring("os.run({},'"..path.."')")
	local co = coroutine.create(f)
	term.redirect(buffer.tRedirect)
	local ok, filter = coroutine.resume(co)
	programs[name] = {name=name,routine=co,buffer=buffer,enabled=true,filter=filter}
end

I see that you've mostly finished correcting the rest of the event handling side of things, but you'll probably want to add handling for dead coroutines. The other issue is that some events really should be pushed through regardless as to whether a process is "enabled" - timers, for example. Pretty much anything that isn't user input, really.
As i load "os.run({},<path>)" as function and not the actual content of the file, it shouldn't pass any arguments to the program i think :/

But I'll try that out later,thanks ^^
Edited on 24 July 2015 - 03:06 AM
Bomb Bloke #14
Posted 24 July 2015 - 05:25 AM
Hmm, good point - I was still looking at a version of the code that used loadfile in one window, and got your updated copy from another. The switch to os.run() with loadstring should've avoided that particular error all on its own.