SMC is so straight forward and easy to use, that it is unnecessary to know anything about the code it generates in order to use it. But for the curious, here is an explanation.
The SMC-generated code follows the State pattern as described in Gamma, Helm, Johnson and Vlissides "Design Patterns" book (pp. 305 to 313):
The SMC State pattern is different due to support for multiple machines, a default state, default transition and push/pop transitions:
SMC deviates from the State pattern as follows:
-
The Context class was broken into two classes: an
abstract FSMContext class (not generated but
provided with the SMC compiler) and
<AppClass>Context class.
FSMContext stores both the current state and the state stack (used for pushing and popping states). FSMContext also defines methods for setting the state, and pushing and popping states
<AppClass>Context inherits from FSMContext, defines the
getState()
(which returns the current state as a <AppClass>State object and not a State object - that is why this method is not in FSMContext), provides access to all transitions defined in all machines and maintains a reference back to its owner <AppClass> object. -
The state pattern has an abstract State class
and ConcreteState classes which inherit from State.
SMC expands this hierarchy to four levels: State,
<AppClass>State, Map Default state and
concrete states.
This hierarchy is used to support SMC's default transitions. <AppClass>State has a virtual method for each transition appearing in all state machines. These transition methods call <AppClass>State's Default transition method. This global Default transition throws a "Transition Undefined" exception when called.
The map default state class contain the Default state's transitions.
Each concrete state is a class which inherits from its map's default state class. The state class methods implement state machine transitions.
Each map class statically declares one instance of each of its states since concrete state classes are singletons. The map class has no methods and is itself a singleton. The map class' purpose is to gather a map's state instances into a single location.
While SMC generates many classes, they take up little run time space. There is only one instance of each concrete state class. Only one <AppClass>Context class need be instantiated for each <AppClass> class instance.
Finally, the SMC State pattern is hidden from the application class. All a developer needs to do is instantiate <AppClass>Context, passing to it the <AppClass> object. After that, it's only a matter of calling the Context object's transition methods.
For further examples on using the State Machine Compiler, see Section 6: For Example ... .