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

coroutine help

Started by Creeper9207, 06 August 2015 - 12:14 AM
Creeper9207 #1
Posted 06 August 2015 - 02:14 AM
can someone give me a very simple example of how one would pause a coroutine running in a window, and resume the coroutine for another, everything i try just freezes
thanks in advance
Edited on 06 August 2015 - 12:36 AM
KingofGamesYami #2
Posted 06 August 2015 - 02:56 AM
I'd guess you aren't sending events at all. You need to send events except user input events, and simply stop drawing the window.

For example, a 'paused' coroutine needs to receive "timer" events, but not "mouse_click" events. Of course, this doesn't completely pause the program, it basically just hides it. Alternatively, you may want to store all the non-user input event in a table, and don't resume it at all (until, of course, you decide to switch back to it, in which case you'll need to give it all the non-user inputs).
Creeper9207 #3
Posted 06 August 2015 - 03:09 AM
OH, thank you so much
but wait, how would you do this? im still kinda confused
what im trying to do:

args = {...}
paintutils.drawFilledBox(1, 1, 51, 19, colors.yellow)
function mainPocket()
  vmwin1 = window.create(term.current(), 13, 1, 26, 20)
  term.redirect(vmwin1)
  shell.run(args[1])
end
function mainEditor()
  sleep(0.3)
  term.redirect(term.native())
  vmwin2 = window.create(term.current(), 1, 1, 51, 19)
  term.redirect(vmwin2)
  shell.run("nxedit "..args[1])
end
function updater()
  while true do
    e, k = os.pullEvent()
    if k == keys.numPad8 then
	  vmwin1.reposition(13, 0)
    end
    if k == keys.numPad2 then
	  vmwin1.reposition(13, 1)
    end
    if k == keys.numPad4 then
	  term.redirect(term.native())
	  coroutine.yield()
	  coroutine.resume(c2)
	  term.redirect(vmwin2)
    end
    if k == keys.numPad6 then
	  term.redirect(term.native())
	  coroutine.yield()
	  coroutine.resume(c1)
	  term.redirect(vmwin1)
    end
  end
end
c1 = coroutine.create(mainPocket)
c2 = coroutine.create(mainEditor)
function start()
  coroutine.resume(c1)
end
start()
updater()

Edited on 06 August 2015 - 01:14 AM
KingofGamesYami #4
Posted 06 August 2015 - 04:25 AM
Well, the first problem that comes to mind is the gross mishandling of coroutines. Here's something that works like parallel.waitForAll:


local function doThingsParallel( ... )
  local tFilters = {}
  local tRoutines = {}
  local tEventData = {}
  for k, v in pairs( { ... } ) do
    tRoutines[ #tRoutines + 1 ] = coroutine.create( v )
  end
  while #tRoutines > 0 do
    for k, v in pairs( tRoutines ) do
      if not tFilters[ k ] or tFilters[ k ] == event[ 1 ] then
        tFilters[ k ] = coroutine.resume( v, unpack( tEventData ) )
      end
      if coroutine.status( v ) == "dead" then
        tRoutines[ k ] = nil
      end
    end
  end
  tEventData = { os.pullEvent() }
end

Yeah, that's about as simple as coroutines get, I'm afraid. Obviously this won't do what you want, you'll want to assign windows and redirect targets, and additionally check events against whether you want the routine running in the foreground at the time and what type of events you want it to get depending on that.
Creeper9207 #5
Posted 06 August 2015 - 04:35 AM
thanks so much for the help and support
Creeper9207 #6
Posted 06 August 2015 - 05:28 AM
but i need a way to implement the window api with this for multitasking
Bomb Bloke #7
Posted 06 August 2015 - 07:37 AM
So directly before you resume a given coroutine, you redirect to a window dedicated to that coroutine. By making only one of those windows "visible" at a time, only your "foreground" process will actually be shown to the user, while "background" processes will continue to buffer their content so they can be revealed later.
Creeper9207 #8
Posted 06 August 2015 - 04:59 PM
ok thanks