Skip to content

Instantly share code, notes, and snippets.

@evilmarty
Created January 5, 2014 06:26
Show Gist options
  • Save evilmarty/8265097 to your computer and use it in GitHub Desktop.
Save evilmarty/8265097 to your computer and use it in GitHub Desktop.
A small and simple state machine in Javascript.
function StateMachine(options) {
options = options || {};
if (!(this instanceof StateMachine)) {
return new StateMachine(options);
}
var states = this.states = (options.states || this.states),
initialState = this.initialState = (options.initialState || this.initialState || Object.keys(states).shift());
this.transitionTo(initialState);
}
StateMachine.prototype = {
constructor: StateMachine,
initialState: null,
state: null,
states: {},
get currentState() {
return this.states[this.state];
},
transitionTo: function(state) {
var currentState = this.currentState,
newState = this.states[state];
if (typeof(newState) !== 'object') {
throw "Invalid state '" + state + "'";
}
if (currentState && typeof(currentState.exit) === 'function') {
currentState.exit(this);
}
this.state = state;
if (typeof(newState.enter) === 'function') {
newState.enter(this);
}
},
send: function(method) {
var args = [].slice.call(arguments, 1),
currentState = this.currentState,
func = currentState[method];
if (typeof(func) !== 'function') {
throw "Cannot call '" + method + "' on current state '" + this.state + "'";
}
args.unshift(this);
func.apply(currentState, args);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment