- Forwarding Engine States
- Modeling a Generic State
- Getting the State Engine Started
- The Forwarding EngineRunning All the States
- Pattern Extensibility
- Conclusion
- Additional Reading
The Forwarding Engine—Running All the States
Listing 8 illustrates the interface for the EngineEntity class.
Listing 8 EngineEntity class
#include "State.h" #include "ForwardingState.h" #include "InitialState.h" #include "ExitState.h" class EngineEntity { public: explicit EngineEntity(void); virtual ~EngineEntity(void); friend class State; void changeState(State*); char* getStateCapabilities(); private: State* _state; }; #endif
The interface in Listing 8 includes all the state-specific header files you already looked at. In addition, it declares the State class to be a friend to EngineEntity, which provides EngineEntity with privileged access to the State class and its members.
The EngineEntity class also implements the changeState() member function that allows it to explicitly change the current state. This facilitates the state transitions shown in Figure 1.
The getStateCapabilities() method is familiar by now—it indicates capabilities of the current state. Finally, the EngineEntity class provides a data member called _state that keeps track of the current state.
Let’s now look at the complete implementation of the EngineEntity class in Listing 9.
Listing 9 Implementation of the EngineEntity class
EngineEntity::EngineEntity(void) { _state = NULL; changeState(InitialState::Instance()); } char* EngineEntity::getStateCapabilities(void) { return _state->whatCanWeDo(); } EngineEntity::~EngineEntity(void) { } void EngineEntity::changeState(State* pState) { if (pState != _state) { _state = pState; } }
Listing 9 shows that the EngineEntity constructor initializes the _state data member to NULL, as well as setting the initial state to that provided by a call to changeState(InitialState::Instance(). This call reaches into the InitialState and sets the operating state accordingly.
The getStateCapabilities() method calls into the whatCanWeDo() member function associated with the _state data member. The changeState() method is fairly self-explanatory—it simply updates the state as required.
Instantiation of the EngineEntity class is done in the main() function, as illustrated in Listing 10.
Listing 10 Instantiating an Object of the EngineEntity class
int main( int argc, char *argv[ ]) { EngineEntity* myEngineEntity = new EngineEntity(); printf(myEngineEntity->getStateCapabilities()); printf("ENGINE STATE: Initial state\n"); printf("ENGINE STATE TRANSITION ->: Moving to the forwarding state\n\n"); myEngineEntity->changeState(ForwardingState::Instance()); printf(myEngineEntity->getStateCapabilities()); printf("ENGINE STATE TRANSITION ->: Moving to the exit state\n\n"); myEngineEntity->changeState(ExitState::Instance()); printf(myEngineEntity->getStateCapabilities()); printf("Deleting the engine instance.\n"); delete myEngineEntity; return 0; }
Listing 10 illustrates the unabbreviated version of the code from Listing 1. Listing 10 shows an instance of EngineEntity being created. At this point, the capabilities of this state are displayed. We know that we’re in the initial state at this stage, so—as the two printf() statements show—we can now move into the forwarding state. Once in the forwarding state, we again record the state capabilities.
We stay in this state until we move to the exit state. We then record the state capabilities again before deleting the instance of EngineEntity and exiting the program.
Clearly, at each state we have a set of capabilities that change as we move into other states.