------=_Part_61130_32090022.1175246195837 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline We have used continuation in our Ruby+OGRE game engine (CubicEngine) to implement something called Latent Functions. I stole the idea from UnrealScript (http://wiki.beyondunreal.com/wiki/Latent_Function). I don't know the correct CS name for it, but I guess it's a type of coroutine. You can use them to create blocking methods in a single threaded simulation without pausing the simulation. They are incredibly useful when you want a game actor to respond to an event, then take a short nap (for example: until some animation has finished playing) and continue reacting to the event. Without latent functions, we'd have to greatly increase complexity for each actor by storing more detailed state information. What's even worse is that without them we would have to turn a single logical action into a complex sequence of mildly reusable methods and timers. CubicEngine is just a small hobby project developed by two people and Ruby is not yet very popular in the games industry (I hope to change that :)), but latent functions have been proven to be a very handy technique by games like Unreal and DeusEx. Juozas Gaigalas On 3/30/07, Brent Roman <brent / mbari.org> wrote: > > A couple times on this list, I've read pleas for examples of > real Ruby applications that use Continuation objects. > > Ours is described here: > > http://www.zenspider.com/dl/rubyconf2005/EmbeddedRuby.pdf > > http://www.sciencedirect.com/science?_ob=MImg&_imagekey=B75DF-4MT6KFX-H-7&_cdi=13037&_user=488091&_orig=browse&_coverDate=02%2F28%2F2007&_sk=999879998&view=c&wchp=dGLbVlz-zSkWb&md5=99829235a3aae38f50df899786b91af2&ie=/sdarticle.pdf > > It's real enough, even if it's a little unusual :-) > > We've started using Continuations to store checkpoints as Ruby > scripts execute. These scripts control robotic manipulators, so there is > always the possibility of a failure, either due to a mechanical problem > or a coding error. The protocols controlled by these scripts > often take hours to complete and consume expensive reagents. > Simply reexecuting them from their beginning in the event of an > error is rarely a viable option. So, when an error occurred, we used > to hack up a new script on the spot to recover from > the failure. Now, using Continuations, we can usually > clear the error condition with a couple simple commands > and resume the execution of the script's failed thread > from its last recorded "checkpoint". > > This all works surprisingly well and has been quite easy to implement. > A couple days ago I fixed a typo [that caused an unhandled NameError > two hours into a scripts execution], reloaded the effected method(s) and > resumed execution without losing any important system state! > Honestly, I wish I'd implemented this years ago. > > Can anyone help answer the following: > > 1) Does the Continuation object include a method to return its associated > call stack analogous to an Exception object's :backtrace method? > > For now, I store the output of Kernel.caller() in my Checkpoints > just after the callcc that stores the Continuation > but I feel this must be very inefficient in time and space. > > 2) If the answer to #2 is no, would it be easy & sensible to implement > Continuation#backtrace or Continuation#caller ? > > 3) Is there another way to implement the generic > "checkpointing" described above that does not rely > on Continuation objects, as their future in Ruby seems > uncertain? (Is their future still uncertain?) > > -- > Brent Roman > Monterey Bay Aquarium Research Institute > > > ------=_Part_61130_32090022.1175246195837 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline <br>We have used continuation in our Ruby+OGRE game engine (CubicEngine) to implement something called Latent Functions. I stole the idea from UnrealScript (<a href="http://wiki.beyondunreal.com/wiki/Latent_Function">http://wiki.beyondunreal.com/wiki/Latent_Function </a>). I don't know the correct CS name for it, but I guess it's a type of coroutine. You can use them to create blocking methods in a single threaded simulation without pausing the simulation. They are incredibly useful when you want a game actor to respond to an event, then take a short nap (for example: until some animation has finished playing) and continue reacting to the event. Without latent functions, we'd have to greatly increase complexity for each actor by storing more detailed state information. What's even worse is that without them we would have to turn a single logical action into a complex sequence of mildly reusable methods and timers. <br><br>CubicEngine is just a small hobby project developed by two people and Ruby is not yet very popular in the games industry (I hope to change that :)), but latent functions have been proven to be a very handy technique by games like Unreal and DeusEx. <br><br><br>Juozas Gaigalas<br><br><br><div><span class="gmail_quote">On 3/30/07, <b class="gmail_sendername">Brent Roman</b> <brent / mbari.org> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> A couple times on this list, I've read pleas for examples of<br>real Ruby applications that use Continuation objects.<br><br>Ours is described here:<br><br><a href="http://www.zenspider.com/dl/rubyconf2005/EmbeddedRuby.pdf"> http://www.zenspider.com/dl/rubyconf2005/EmbeddedRuby.pdf</a><br><a href="http://www.sciencedirect.com/science?_ob=MImg&_imagekey=B75DF-4MT6KFX-H-7&_cdi=13037&_user=488091&_orig=browse&_coverDate=02%2F28%2F2007&_sk=999879998&view=c&wchp=dGLbVlz-zSkWb&md5=99829235a3aae38f50df899786b91af2&ie=/sdarticle.pdf"> http://www.sciencedirect.com/science?_ob=MImg&_imagekey=B75DF-4MT6KFX-H-7&_cdi=13037&_user=488091&_orig=browse&_coverDate=02%2F28%2F2007&_sk=999879998&view=c&wchp=dGLbVlz-zSkWb&md5=99829235a3aae38f50df899786b91af2&ie=/sdarticle.pdf </a><br><br>It's real enough, even if it's a little unusual :-)<br><br>We've started using Continuations to store checkpoints as Ruby<br>scripts execute. These scripts control robotic manipulators, so there is <br>always the possibility of a failure, either due to a mechanical problem<br>or a coding error. The protocols controlled by these scripts<br>often take hours to complete and consume expensive reagents.<br>Simply reexecuting them from their beginning in the event of an <br>error is rarely a viable option. So, when an error occurred, we used<br>to hack up a new script on the spot to recover from<br>the failure. Now, using Continuations, we can usually<br>clear the error condition with a couple simple commands <br>and resume the execution of the script's failed thread<br>from its last recorded "checkpoint".<br><br>This all works surprisingly well and has been quite easy to implement.<br>A couple days ago I fixed a typo [that caused an unhandled NameError <br>two hours into a scripts execution], reloaded the effected method(s) and<br>resumed execution without losing any important system state!<br>Honestly, I wish I'd implemented this years ago.<br><br>Can anyone help answer the following: <br><br>1) Does the Continuation object include a method to return its associated<br> call stack analogous to an Exception object's :backtrace method?<br><br> For now, I store the output of Kernel.caller() in my Checkpoints <br> just after the callcc that stores the Continuation<br> but I feel this must be very inefficient in time and space.<br><br>2) If the answer to #2 is no, would it be easy & sensible to implement<br> Continuation#backtrace or Continuation#caller ? <br><br>3) Is there another way to implement the generic<br> "checkpointing" described above that does not rely<br> on Continuation objects, as their future in Ruby seems<br> uncertain? (Is their future still uncertain?) <br><br>--<br> Brent Roman<br> Monterey Bay Aquarium Research Institute<br><br><br></blockquote></div><br> ------=_Part_61130_32090022.1175246195837--