Skip to content

Instantly share code, notes, and snippets.

@Fintan
Last active December 14, 2015 11:09
Show Gist options
  • Save Fintan/5077619 to your computer and use it in GitHub Desktop.
Save Fintan/5077619 to your computer and use it in GitHub Desktop.
A state machine based on the example shown here: http://lamehacks.net/blog/implementing-a-state-machine-in-javascript/ This version uses Underscore and Backbone
var states = [
{
'name':'working',
'initial':true,
'events':{
'bored':'coffee',
'call_for_meeting':'meeting',
}
},
{
'name':'coffee',
'events':{
'break_over':'working',
'call_for_meeting':'meeting'
}
},
{
'name':'meeting',
'events':{
'meetings_over':'working'
}
},
];
var State = Backbone.Model.extend({});
var StateMachine = Backbone.Collection.extend({
model:State,
initialize: function(states) {
this.on("reset", this.onReset, this);
},
onReset: function() {
this.currentState = this.where({initial: true})[0];
this._validate();
},
consumeEvent: function(e) {
var events = this.currentState.get("events");
if(events[e]){
this.currentState = this.where({name: events[e]})[0];
this._validate();
}else{
console.warn("StateMachine:consumeEvent event ("+e+") does not exist in current state ("+this.getStatus()+")");
}
},
getStatus: function() {
return this.currentState.get("name");
},
_validate: function() {
if(!this.currentState) {
console.warn("StateMachine:consumeEvent currentState is undefined");
}
}
});
var sm = new StateMachine(states, {silent: false});
sm.getStatus(); // will return 'working'
sm.consumeEvent('bored');
sm.getStatus(); // I went for coffee
sm.consumeEvent('call_for_meeting');
sm.getStatus(); //will return 'meeting'
sm.consumeEvent('bored'); //doesn't matter how boring a meeting can be...
sm.getStatus(); //will still return 'meeting'
sm.consumeEvent('meetings_over')
sm.getStatus(); // 'working'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment