The most prominent case of coroutines are probally old graphical point&click adventure games, where they where used to script cutscenes and other animated sequences in the game. A simple code example would look like this:
# script_file.scr
bob.walkto(jane)
bob.lookat(jane)
bob.say("How are you?")
wait(2)
jane.say("Fine")
...
This whole sequence can't be written as normal code, as you want to see bob do his walk animation after you did bob.walkto(jane)
instead of jumping right to the next line. For the walk animation to play you however need to give control back to the game engine and that is where coroutines come into play.
This whole sequence is executed as a coroutine, meaning you have the ability to suspend and resume it as you like. A command like bob.walkto(jane)
thus tells the engine side bob object its target and then suspends the coroutine, waiting for a wakeup call when bob has reached his target.
On the engine side things might look like this (pseudo code):
class Script:
def __init__(self, filename):
self.coroutine = Coroutine(filename)
self.is_wokenup = True
def wakeup(self):
self.is_wokenup = False;
def update():
if self.is_wokenup:
coroutine.run()
class Character:
def walkto(self, target, script):
self.script = script
self.target = target
def update(self):
if target:
move_one_step_closer_to(self.target)
if close_enough_to(self.target):
self.script.wakeup()
self.target = None
self.script = None
objects = [Character("bob"), Character("jane")]
scripts = [Script("script_file.scr")]
while True:
for obj in objects:
obj.update()
for scr in scripts:
scr.update()
A litte word of warning however, while coroutines make coding these sequences very simple, not every implementations you will find of them will be build with serialisation in mind, so game saving will become quite a troublesome issue if you make heavy use of coroutines.
This example is also just the most basic case of a coroutine in a game, coroutines themselves can be used for plenty of other tasks and algorithms as well.