Foundations.Control.FSM
Implements a Finite State Machine (FSM) with "states" and "events". States are defined in an object and are transitioned to via events.
Using Foundations.Control.FSM
FSMs model behavior where responses to future events depend upon previous events. FSMs consist of:
- Events that the app responds to.
- States where the app waits between events.
- Transitions between states in response to events.
- Actions taken during transitions.
- Variables that hold values needed by actions between events.
FSMs are most useful in situations where many different types of events drive behavior, and the response to a particular event depends on the sequence of previous events.
States are a way to remember previous events, and transitions are a way to organize responses to future events.
FSMs are typically represented in one of two ways:
- Directed graphs -- Balloons represent states, and arrows between them represent transitions, which are labeled with events and actions.
- Two-dimensional tables -- Rows and columns represent events and states, and cells contain actions and transitions.
A full discussion of FSMs is beyond the scope of this documentation, but there are numerous resources available on the Internet.
Implementing a Finite State Machine
Typically, to implement a FSM, you would create a "states" object that defines states, events, and transition processing similar to the following:
var states = { stateOne: { eventOne: function() { // Do some processing and transition to another state }, eventTwo: function() { } }, stateTwo: { eventThree: function() { }, eventFour: function() { } }, // .... };
Allocating a Finite State Machine
The following is a simple example of allocating a FSM:
// Load Foundation libraries var libraries = MojoLoader.require({ name: "foundations", version: "1.0" }); // Create reference to FSM code var FSM = libraries["foundations"].FSM; // Create states, events, and transition processing object var states = { one: { gotoTwo: function() { // Event/Transition processing here... this.go("two"); // FSM method }, gotoThree: function() { this.go("three"); } }, two: { gotoOne: function() { this.go("one"); }, gotoThree: function() { this.go("three"); } }, three: { gotoTwo: function() { this.go("two"); }, gotoOne: function() { this.go("one"); } } }; var context = {}; // some object // Allocate FSM var fsm = new FSM(states, context);
If no "context" is provided, then the states object is used as the context. If you only need one instance of a particular FSM, there is no reason for a separate context object.
FSM Methods
- currentState -- Get FSM's current state.
- event -- Calls the named event method for the current state.
- go -- Transition from the current state to to the specified new state.
FSM.currentState
Get FSM's current state.
Syntax
FSM.currentState();
Parameters
None.
Returns
FSM current state.
Example
// Use example from "Allocating..." var fsm = new FSM(states, context); // Get initial state Mojo.Log.info("fsm current state = "+ fsm.currentState());
Example Output
fsm current state = __uninitialized
FSM.event
Calls the named event method for the current state. This usually, but not always, results in a state transition.
Syntax
boolean FSM.event(event, arguments);
Parameters
| Argument | Required | Type | Description |
| event | Yes | string | Event to call. |
| arguments | No | any array | Arguments to pass to event function. |
Returns
true or false
Example
// Use example from "Allocating..." fsm.go("three"); Mojo.Log.info("fsm event gotoOne = "+ fsm.event("gotoOne"));
Example Output
fsm event gotoOne = true
FSM.go
Transition from the current state to to the specified new state. Though used in the FSM implementation, calling this is not really necessary - in general, you would want to use an event to switch between states. If not already there, this method transitions the FSM to the named state.
Syntax
FSM.go(nstate);
Parameters
| Argument | Required | Type | Description |
| nstate | No | any | Name of state to transition to. |
Returns
None.
Example
// Use example from "Allocating..." fsm.go("two"); // Get new state Mojo.Log.info("fsm current state = "+ fsm.currentState());
Example Output
fsm current state = two