The sequence above was flat, not involving any subroutines. Any significant game is going to make a *very* long main generator, without subroutines. However, any subroutine called from the generator cannot chain to an engine or other functionality via the reactor. Returning control to the reactor is done by yielding. If the sub-generator yields, it yields to its caller, which needs in turn to yield, recursively all the way to the reactor.
The code can be subdivided for organizational purposes, but not necessarily by functions. A sub-generator can provide encapsulation to local variables, while maintaining the ability to yield to the reactor repeatedly for different stages.
def intro(engine): # generator
res = 0
engine.interface = intro_iface
while res != 'quit':
if res == 0:
engine.objects = [intro_pic0]
engine.interface.buttons = (None,1)
elif res == 1:
engine.objects = [intro_pic1]
engine.interface.buttons = (0,2)
elif res == 2:
engine.objects = [intro_pic2]
engine.interface.buttons = (1,None)
yield None
reactor.callLater(0, engine.go)
res = engine.retval
def main(): # generator
engine = Engine()
# iterate over intro, while intro shows
# its various page pics
for i in intro(engine):
yield i
# execution resumes here after intro
# set up stage 1
engine.interface = stage1_iface
.....
# done
reactor.stop()
yield None
continue_main = main().next # creates iterator
continue_main() # runs to first yield, installing first engine (via first .callLater) in reactor
reactor.run()
As you see, isolating the multiple stages of introduction into a generator makes the main a bit simpler, but the calling syntax: for i in intro(engine): yield i; is ugly.