Tutorial¶
A Stage is a major segment of a game. Stages… * are mutually
non-overlapping; There is exactly one active Stage at any time while
the game is running, * have an Stage.enter(data) method that sets
up, and an Stage.exit(data) method that tears down the Stage.
A Flow… * is the container for a game’s States, each stored
under a name, * has a Flow.transition(stage, data) method that
exits the current Stage and enters the target stage, * is fully and
reflexively conected; It may transition from any Stage to any other,
including the current one (basically restarting it), * manages how data
is passed on, to allow for limited communication between Stages;
Flow.transition(stage, data) passes the data on to
current_stage.exit(data), and the data returned by that method is
passed to target_stage.enter(data).
Let’s see that in action:
from stageflow import Flow
from stageflow import Stage
class MyStage(Stage):
def enter(self, data):
# Set uo the Stage here
print("MyStage.enter({})".format(data))
def exit(self, data):
# Tear down stage, and return data to be passed on
print("MyStage.exit({})".format(data))
return "Data returned by MyStage.exit()"
flow = Flow(
stages=dict(
mystage=MyStage(),
),
)
flow.transition('mystage', "Argument to flow.transition")
# Output:
# MyStage.enter(Argument to flow.transition)
flow.transition('mystage', "Argument to flow.transition")
# Output:
# MyStage.exit(Argument to flow.transition)
# MyStage.enter(Data returned by MyStage.exit())
We can also enter a Stage automatically when creating the Flow:
flow = Flow(
stages=dict(
mystage=MyStage(),
),
initial_stage='stages',
initial_stage_data='Initial data from Flow creation',
)
# Output:
# MyStage.enter(Initial data from Flow creation)
Substages are temporary interruptions to the underlying stage. They
stack one on top of another, and also need to be unstacked in reverse
order. While Substages are present, the current Stage can not be
transitioned out of.
Flow provides the methods Flow.push_substage(stage, data) and
Flow.pop_substage(data) to add and remove substages. Stages and
Substages (which are, under the hood, the same) provide
exit_to_substage(data) and reenter_from_substage(data) methods
to do appropriate actions to pause and unpause the Stage or
Substage.
The Substage pushed “on top”, however, will still be entered /
exited using its enter / exit methods when moving from / to the
stage “below”.
from stageflow import Flow
from stageflow import Stage
class MyStage(Stage):
def __init__(self, stage_name):
self.stage_name = stage_name
def enter(self, data):
print("{}.enter({})".format(self.stage_name, data))
def exit(self, data):
print("{}.exit({})".format(self.stage_name, data))
return "Data returned by {}.exit()".format(self.stage_name)
def exit_to_substage(self, substage, data):
print("{}.exit_to_substage({}, {})".format(
self.stage_name,
substage,
data,
))
return "Data returned by {}.exit_to_substage()".format(
self.stage_name,
)
def reenter_from_substage(self, substage, data):
print("{}.reenter_from_substage({}, {})".format(
self.stage_name,
substage,
data,
))
flow = Flow(
stages=dict(
mystage=MyStage("BaseStage"),
),
substages=dict(
substage_a=MyStage("SubstageA"),
substage_b=MyStage("SubstageB"),
),
initial_stage='mystage',
)
# Output:
# BaseStage.enter(None)
flow.push_substage('substage_a', "Argument to flow.push_substage")
# Output:
# BaseStage.exit_to_substage(substage_a, Argument to flow.push_substage)
# SubstageA.enter(Data returned by BaseStage.exit_to_substage())
flow.push_substage('substage_b', "Argument to flow.push_substage")
# Output:
# SubstageA.exit_to_substage(substage_b, Argument to flow.push_substage)
# SubstageB.enter(Data returned by SubstageA.exit_to_substage())
flow.pop_substage("Argument to flow.pop_substage")
# Output:
# SubstageB.exit(Argument to flow.pop_substage)
# SubstageA.reenter_from_substage(substage_b, Data returned by SubstageB.exit())
flow.pop_substage("Argument to flow.pop_substage")
# Output:
# SubstageA.exit(Argument to flow.pop_substage)
# BaseStage.reenter_from_substage(substage_a, Data returned by SubstageA.exit())
Now you know all about writing and interconnecting your Stages into
a flow, concluding the tutorial.