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.

Advertisements