Package | com.eqsim.FStEng |
Class | public class StateEngine |
Inheritance | StateEngine ![]() |
The StateEngine encapsulates the functionality for a state machine (hierarchical or finite states). Once you create an instance of a StateEngine, you then instantiate the state network as a series of State's (simple states), HState's (hierarchical states), and HStateC's (Hierarchical, concurrent states).
To keep track of the current state(s), a data structure called a StateManager
is used. A State Manager
keeps track of which state(s) in a network is/are current. Trying to avoid confusion, the API hides this as
much as possible by automatically creating State Managers when the developer uses State's and HState's, for example, via stateInstance.addSubState()
and
stateInstance.addSubHState()
. However, since
a State Manager is required to manage each sub-network, if the developer creates an HStateC, he must manually create
State Manager's to organize the HStateC's sub-networks.
To activate the state network, use active = true;
, or activate()
. To send events
into the StateEngine, use PostEvent()
. Events can optionally be postponed by passing in a delay value, but there
currently is no mechanism to defer events (as in UML 2.0). Events are processed in a FIFO, priority-based queue (default priority is 1000:
lower number means higher priority). The engine guarantees
that the network runs-to-completion before processing the next event in the queue.
If you only want a finite state machine, you can create a top state as a hierarchical state (HState) and then just add simple states (State) to the network.
Property | Defined By | ||
---|---|---|---|
active : Boolean
Flag indicating if state engine is active. | StateEngine | ||
activeStates : Dictionary
A Dictionary (flash.utils.Dictionary) of the currently active states. | StateEngine | ||
name : String
User-defined (String) name of the state engine. | StateEngine | ||
topState : HStateC
Topmost state in the state network. | StateEngine |
Method | Defined By | ||
---|---|---|---|
StateEngine(n:String = State Engine, stateNetwork:HStateC = null)
Creates a new instance of a state engine data structure. | StateEngine | ||
activate(resetHistory:Boolean = true):void
Activates the state engine. | StateEngine | ||
deactivate():void
Deactivate the state engine. | StateEngine | ||
postEvent(ev:Event, timeDelay:Number = 0, pty:int = 1000):void
Main routine for injecting an event into the state network. | StateEngine | ||
prepareNetwork():void
Initializes the states and transitions before the engine activates the first time. | StateEngine | ||
removeStateEngine():void
Removes memory associated with the state engine passed in. | StateEngine | ||
setStateNetwork(sn:HStateC, suppressReassign:Boolean = false):void
Attaches the state network (referred to by topmost state) to this state engine. | StateEngine |
Constant | Defined By | ||
---|---|---|---|
ACTIVATE : String = ACTIVATE [static]
Event sent when the state engine gets activated. | StateEngine | ||
DEACTIVATE : String = DEACTIVATE [static]
Event sent when the state engine gets deactivated. | StateEngine | ||
UNHANDLED_EVENT : String = UNHANDLED [static]
Event sent when no state has handled an injected event. | StateEngine |
active | property |
active:Boolean
Flag indicating if state engine is active.
Setting this flag to true will activate the engine. Setting it to false will deactive the engine. Retrieving the value will tell you if the state engine is active or not
The default value is false
.
public function get active():Boolean
public function set active(value:Boolean):void
activeStates | property |
public var activeStates:Dictionary
A Dictionary (flash.utils.Dictionary) of the currently active states.
The State objects are keys, with values being true
name | property |
public var name:String
User-defined (String) name of the state engine.
The default value is "State Engine"
.
topState | property |
topState:HStateC
Topmost state in the state network. Set and retrieve the topmost state (HState, HStateC) in the state network. The top state can be a State, but that would be a pretty boring state machine. If you want the top state to be a State, you can cast your State into an HStateC and pass it in, since HStateC is a sub-state of State. You can set this parameter as an alternative to supplying the top state's pointer in the StateEngine constructor.
The default value is null
.
public function get topState():HStateC
public function set topState(value:HStateC):void
StateEngine | () | Constructor |
public function StateEngine(n:String = State Engine, stateNetwork:HStateC = null)
Creates a new instance of a state engine data structure.
This is the constructor. Make sure to hold onto the pointer to this somewhere safe (i.e., away from the possibility that it will be garbage-collected). For example, you typically will set the return value to a property of an class instance in your application. If you do not hold onto this, Flash may mark the instance for garbage collection and your network could start acting strange.
Parametersn:String (default = State Engine ) — Optional name (String) for the state engine. Default is "State Engine".
| |
stateNetwork:HStateC (default = null ) — Optional top state (HState, HStateC, or State [under rare circumstances]) of the network.
A top state is mandatory, but supplying it in the constructor is optional. If you don't
supply it here, you must use setStateNetwork() and pass in the top state.
|
// this includes top state in instantiation se = new StateEngine("engine1", new HState("TOP CONTAINER STATE", 0));
// this assumes top state pointer will be supplied via setStateNetwork() se = new StateEngine("engine1");
activate | () | method |
public function activate(resetHistory:Boolean = true):void
Activates the state engine.
Typically you will use the active
property to activate active = true;
your state engine. However,
you can use this method all the same. When an engine is activated, it combs through the state network and
clears all the history markers by default. If you don't want this to happen, you cannot use active
, you
must use this routine and set the 'resetHistory' parameter to false
.
Parameters
resetHistory:Boolean (default = true ) — (optional) Set this to 'false' if you do not want to reset the history mechanism throughout the system. Default is true.
|
deactivate | () | method |
public function deactivate():void
Deactivate the state engine.
Typically you will use the active
property to deactivate active = false;
your state engine.
postEvent | () | method |
public function postEvent(ev:Event, timeDelay:Number = 0, pty:int = 1000):void
Main routine for injecting an event into the state network.
The state engine sits in the current state(s) and basically waits until some event comes in. This method
is how you inject an event into the network. When you pass in an event, this routine sends the event to
the active state(s) in the network. If that/those state(s) don't handle it, the event bubbles up to the
parent to take a shot at handling the event, and so on, up to the topmost state. If no state handles the event,
the state engine generates a special event, StateEngine.UNHANDLED_EVENT
, which you can subscribe to. In
that way, the caller can tell if any state handled the event or not.
Events are Priority FIFO-queued. The engine guarantees run-to-completion by verifying no event is currently being handled when the engine injects the event. If a new event comes in while one is already being handled, the event gets queued.
Callers may indicate to postpone an event for a set amount of time (in milliseconds). This might be useful, for example, if you need to space out the time a bit due to Flash needing a moment to get to the next frame.
Events can be assigned priorities, so that higher-priority (lower number) events can jump in line in front of lower-priority events. However, because run-to-completion must be observed, there is no way to interrupt an event being handled currently even with a higher-priority event.
Parameters
ev:Event — Event object (pointer)
| |
timeDelay:Number (default = 0 ) — Amount of time (in milliseconds) to wait after finishing handling the prior event, and when this event gets processed. Default value is 0 (immediately).
| |
pty:int (default = 1000 ) — Integer indicating the priority of the event. By default, all events are given a priority of 1000.
|
prepareNetwork | () | method |
public function prepareNetwork():void
Initializes the states and transitions before the engine activates the first time.
The State Engine must do two things before activating:
This routine accomplishes both tasks. If the developer wants to avoid the time it takes to perform these when the engine activates the first time, he should call this routine. Once complete, the developer would activate the engine. If the developer does not call this routine, the engine activation will call it automatically.
removeStateEngine | () | method |
public function removeStateEngine():void
Removes memory associated with the state engine passed in.
setStateNetwork | () | method |
public function setStateNetwork(sn:HStateC, suppressReassign:Boolean = false):void
Attaches the state network (referred to by topmost state) to this state engine. You can use this method as an alternative to supplying the top state's pointer in the StateEngine constructor.
Parameters
sn:HStateC — Pointer to topmost state (virtually always HState or HStateC, if you need it to be State, cast your State into an HStateC) for the state network.
| |
suppressReassign:Boolean (default = false ) — Optional parameter that locks out possibility to change the top state, once it has been assigned. If an
attempt is made to change the name, the routine throws an Error.
|
myTopStatePtr = new HState("State Network", 0);se.setStateNetwork(myTopStatePtr);
ACTIVATE | Constant |
public static const ACTIVATE:String = ACTIVATE
Event sent when the state engine gets activated.
DEACTIVATE | Constant |
public static const DEACTIVATE:String = DEACTIVATE
Event sent when the state engine gets deactivated.
UNHANDLED_EVENT | Constant |
public static const UNHANDLED_EVENT:String = UNHANDLED
Event sent when no state has handled an injected event.
If an event is posted but no state has an event handler to handle it. To help the handler recognize which event went
unhandled, the StateEngine has an event
property that hangs off of the EventWithData's data object. For example,
myEventWithDataPtr.data.event
gives the Event object that went unhandled. The default handler can examine
that event and decide what the default behavior needs to be.