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

Nested Parallel

Started by wraithbone, 27 August 2012 - 10:09 AM
wraithbone #1
Posted 27 August 2012 - 12:09 PM
I have a problem similar to this thread:
http://www.computerc...ecuting-another
but there is no clear way that that solution matches mine seeing as my program uses loops extensively, already.

At the moment what the program does is load 2 threads one is a GUI and file access system and, running behind the scenes, the other one is a receiver, decoder and file saver.

What I planned was for the user to be able to return to shell and use the PC as per normal while the second thread runs in the BG. Then upon re-opening the program, the GUI functionality returns and the 2nd thread continues.

At the moment, of course, this second opening of the program initiates a copy of the second thread. Without the first having been terminated.

As my worded explanation is probably useless here is a diagram to explain it.



Any suggestions on the best workaround for this? Or an improved method upon the existing one?
Xfel #2
Posted 27 August 2012 - 12:24 PM
Make some kind of persistant maker whether your program is running. Then check it when starting your program, and if it is already running, terminate the shell and exit. You should be back in your program. Like

-- at the start of your program file
-- check whether the program is running
if myprogramrunning then
shell.exit()
return
end
-- function to launch the sub-shell
function launchShell()
shell.run("shell","setmyprogramrunning")
end
-- The file setmyprogramrunning
-- needed as each sub-shell clears the environment.
myprogramrunning=true
Jan #3
Posted 27 August 2012 - 01:02 PM
@wraithbone
You can also try to not use 'parallel' and do the threads yourself via 'coroutine'.
If you have 2 programs with GUI's, then you should try out my Frames program, because it emulates the 'term' and adds a taskbar (spam spam :D/>/>)

Maybe you could do this if one is GUI and one not:

This is an example non-gui program called 'juke'. It puts the redstone on the back on/off every few seconds.

while true do
rs.setOutput("back",true)
sleep(0.2)
rs.setOutput("back",false)
sleep(0.2)
end

Save this program underneath as 'multi'


a = coroutine.create(function() shell.run("shell") end)
b = coroutine.create(function() shell.run("juke") end)
while true do
q,w,e,r = os.pullEventRaw()
state,ans = coroutine.resume(a,q,w,e,r)
coroutine.resume(b,q,w,e,r)
if (ans=="stopit") then
a=nil
b=nil
break
end
end


Now run 'multi' and press anykey to see the working sub-shell
To return, do this:

lua> coroutine.yield("stopit")
Now you should see the highest-level shell again, and the 'juke' program had stopped too.
wraithbone #4
Posted 27 August 2012 - 09:31 PM
Ok Xfel, that sounds like a good method. How do I know which program will exit upon the running of the command?


Jan, with the co-routines do I make the second thread into a second program and run it with the shell command? Or could I pass it the function that does the job?
Does setting a and b to nil stop the code (i.e kill the routines?)
Jan #5
Posted 27 August 2012 - 10:56 PM
Jan, with the co-routines do I make the second thread into a second program and run it with the shell command? Or could I pass it the function that does the job?
Yup you can also let a function do the job. Then you can also access the local variables
Does setting a and b to nil stop the code (i.e kill the routines?)
Yes: the garbage collector will delete the routines:
http://lua-users.org/lists/lua-l/2005-08/msg00552.html
wraithbone #6
Posted 28 August 2012 - 06:08 AM
The problem with the use of co-routines is still the fact of how the use "resumes" the program is by typing the program name into the terminal. i.e running from the shell.
This means that the co-routine would be created in the same way and create another instance of it. I need a way of checking whether there is an instance of the program running or not. If it is then only running the GUI function otherwise running both the file manager and the GUI.

--for example
if (firstTime()) then
GUI();
fileManage();
else
GUI();
end

What I need is a robust way of checking the status of the program. If it is running then only re-run the GUI section you closed earlier.
I don't want to create a file because it will not reset if Ctrl+T or something similar happens.