Skip to content
wezside edited this page Apr 7, 2011 · 3 revisions

###Overview

The StateManager class is an implementation of the Memento pattern. In short, the Memento pattern solves managing complex states through the use of three elements, the memento, the originator and the caretaker (Lott & Patterson, 2007). The easiest way to describe this is through an example. Imagine you are taking a picture using a digital camera. The memento element is the picture you've taken, the originator is the camera, and the caretaker is your camera's memory card. The caretaker allows the originator (camera) to retrieve the snapshot at any given time. In this implementation, the IState object is the memento, the StateManager is the caretaker of all IState objects and the originator is the component or application class instantiating the StateManager.

###How to use it

First required is to instantiate the StateManager. Then add some states using the addState method. This method has two parameters:

###@param key

The string literal used to identify the state. It is advisable to use constants to avoid any silly errors.

###@param reserved

This is a Boolean flag to determine the type of state. Reserved states are not mutually exclusive, they are allowed to co exist with other non-reserved and other reserved states. Non-reserved states are not allowed to co-exist with each other. An example of this could be a button with states "up", "over" and "down". These are all non-reserved states. However if the "selected" state is added, it is quite possible for both "selected" and "up" to be active at the same time. Therefor "selected" will become a reserved state. Another example could be a logged in vs not logged in use case.

###Add a state

sm = new StateManager();
sm.addState( STATE_ROLLOVER );			
sm.addState( STATE_SELECTED, true );			
sm.addState( STATE_ROLLOUT );		

###Set state

sm.stateKey = STATE_ROLLOVER;
sm.stateKey = STATE_SELECTED;	

###Retrieve state

trace( sm.stateKey );            // output: STATE_ROLLOVERSTATE_SELECTED
trace( sm.stateValue );         // output: 3
trace( sm.state );                  // output: [object State]

###Compare state

There are two ways to compare the current state. The key value for reserved and non-reserved states are simply concatenated when requesting the state through the getter "stateKey". Note that concatenation means the order is important. Therefor evaluating the above "stateKey", the correct order of individual states are required, i.e.

if ( sm.stateKey == STATE_ROLLOVER+STATE_SELECTED )           // output: true

and not

if ( sm.stateKey == STATE_SELECTED+STATE_ROLLOVER )           // output: false

If a comparison is needed to determine the state without knowing the order then use the "compare" method.

if ( sm.compare( STATE_SELECTED+STATE_ROLLOVER ))           // output: true

###Behind the scenes

The StateManager makes use of a binary solution to make the management easier of complex combinations. Each state is defined with a key-value pair. The key being defined when the state is added as a string literal and the value for that key is assigned automatically by the StateManager. This value is a base-2 numeric value, i.e. a 1 or a 0. For every state added the base-2 number increases, building a binary number from right to left.

Reserved states act as a toggle. Every time a reserved state is set, the other non-reserved states remain the same. A reserved state can either be 1 or 0, on or off. If the reserved state is active or on, then set it again to deactivate or switch off.

###Resources

Clone this wiki locally