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

Overriding coroutine.yield

Started by Dragon53535, 30 November 2014 - 09:04 PM
Dragon53535 #1
Posted 30 November 2014 - 10:04 PM
On a code I've been working on for a while I've noticed that when I override os.pullEvent to custom handle termination events, usually just me closing a file that's being written to. It doesn't work with the turtle API. That being whenever I try terminating while a turtle api call is happening (turtle.turnLeft, turtle.craft etc) it somehow reverts to the way the old os.pullEvent worked.

I attempted to fix this by overriding coroutine.yield to handle the termination. It works however I'm using error and it seems to not be exactly liking my use of error as that just shut downs the turtle.


local oldPull = coroutine.yield
function coroutine.yield( sFilter )
  local eventData = { oldPull(sFilter) }
  if eventData[1] == "terminate" then
	logger.close()
	error("Terminated",0)
  end
  return unpack( eventData )
end
My coroutine.yield overrider.

Is there any way for me to successfully exit a program, without actually killing the computer? (In this function, I know that error works normally, and I'd rather not use shell.run("shell"))
Edited on 30 November 2014 - 09:06 PM
Lyqyd #2
Posted 30 November 2014 - 10:52 PM
That's really the wrong place to handle termination. You should be passing the event along, since if the program is using os.pullEventRaw instead of os.pullEvent, they're wanting to handle/ignore terminate events.

Also, turtle calls are using the Java-side yielding, which you may not be able to affect in any way.
Dragon53535 #3
Posted 30 November 2014 - 11:30 PM
The thing is, is if I use this, it works for the turtle yielding. If I put this into my code (which it is already inside of) and try to terminate while a turtle call is happening. It works.

However is there any way for me to exit the running program from coroutine.yield.

The only problem I'm having, before putting this in I was overriding os.pullEvent(), is that if I try to terminate the program during a turtle call, is that it never closed the log file I was writing to. It would always call the old os.pullEvent. So I could never delete it without restarting the PC.
Dragon53535 #4
Posted 01 December 2014 - 03:55 AM
Valithor helped out and told me to instead of error, just return "terminate" Which makes it count as the termination event that's being handled by the turtle call, however it allows me to close the file i needed.


local oldPull = coroutine.yield
function coroutine.yield( sFilter )
  local eventData = { oldPull(sFilter) }
  if eventData[1] == "terminate" then
    logger.close()
    return "terminate"
  end
  return unpack( eventData )
end
theoriginalbit #5
Posted 01 December 2014 - 04:32 AM
you could have also done

local oldYield = coroutine.yield
function coroutine.yield( fliter )
  local event = { oldYield( filter ) }
  if event[1] == "terminate" then
	logger.close()
  end
  return unpack( event )
end
as unpack( event ) will still return the terminate event.
Edited on 01 December 2014 - 03:32 AM
Dragon53535 #6
Posted 01 December 2014 - 04:35 AM
Well that's a big derp lol. Thanks though :D/> Glad someone else also helped me. Didn't actually realize that the unpack still worked after the if. Yay for not noticing that. Thanks a lot theoriginalbit
Edited on 01 December 2014 - 03:35 AM
Lyqyd #7
Posted 01 December 2014 - 04:57 AM
Valithor helped out and told me to instead of error, just return "terminate"
You should be passing the event along

The name is Lyqyd, not Valithor. :P/>
Dragon53535 #8
Posted 01 December 2014 - 04:58 AM
The name is Lyqyd, not Valithor. :P/>
The one who helped me that actually got the code running at the time was valithor who talked to me on the LuaLand server.