Skip to content

Instantly share code, notes, and snippets.

@mxriverlynn
Created November 14, 2012 17:22
Show Gist options
  • Save mxriverlynn/4073465 to your computer and use it in GitHub Desktop.
Save mxriverlynn/4073465 to your computer and use it in GitHub Desktop.
Triggering events to notify of state machine state change
// This is built on top of MarionetteJS' [Controller](https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.controller.md)
// object, which includes Backbone.Events in it, to
// trigger events.
//
// I think this is a sort of statemachine. But honestly, I'm not entirely
// sure about that. I've had very little luck / experience with statemachines
// in my career.
//
// Would love to get feedback on this.
MyWorkflow = Marionette.Controller.extend({
initialize: function(workflowData){
// this is the list of available "states" or steps in this workflow
this.steps = new WorkflowStepCollection(workflowData);
},
getSteps: function(){
return this.steps;
},
nextStep: function(){
var nextStep = this.steps.getNext();
this.moveTo(nextStep);
},
previousStep: function(){
var previousStep = this.steps.getPrevious();
this.moveTo(previousStep);
},
moveTo: function(step){
step.select();
this._triggerStep(step);
},
_triggerStep: function(step){
var key = step.get("key");
this.trigger("step:" + key);
}
});
// use of this
// -----------
var workflowConfig = [
{
id: 1,
key: "first",
name: "First Step"
},
{
id: 2,
key: "second",
name: "Second Step"
}
]
var wf = new MyWorkflow(workflowConfig);
wf.on("step:first", aCallback);
wf.on("step:second", anotherCallback);
@gilesbowkett
Copy link

so the thing is that the only clear-cut, unequivocal, "yes you should use state machines here" thing I know of is writing a regular expressions engine. and for purposes of clean TDD and highly modular code, a lot of people seem to want to get rid of state whenever possible. so I have a general suspicion of state machines at this point.

except for va workflowConfig which obviously should be var workflowConfig I don't actually see anything wrong with this code. but "hey I'm going to use an evented state machine" still kind of gives me a faint echo of the feeling I get when I'm watching a horror movie and everybody decides to split up and go somewhere dark on their own.

@samdelagarza
Copy link

looks good. in my approach I defined the callbacks that I wanted called in a stateMap (which is your workflowConfig) and on execution these published events. I also created a timer between transitions which would publish a timeout event in case events didn't fire after a sequence chain was initiated. I built this to measure certain KPIs in the app.

@mxriverlynn
Copy link
Author

@gilesbowkett - LOL! I generally agree with you. I've tried to use state machines many, many times over the years and I've always come away with the feeling of having been defeated, making things worse, etc.

In this case, I found this very simple implementation to be very useful.

I have a navigation system with a navbar at the top that lists each step. at the bottom, there's a Next and Previous button. i wired up the nav to the events from the workflow object.

I also have a page that goes with each step. every time the workflow object triggers a step, the correct page is shown in the content area of the screen. this is wired up by the object that knows about each of the individual pages, and is not directly related to the navigation system - so it kept both of those apart, which is what i wanted, while allowing the workflow from one "step" to the next to be centralized in to a single place.

the worry that i have, moving forward with this, is the additional complexity i need to introduce in order to determine when i can move to which step. there are rules about what has to be done before i can move in to a particular step.

i may end up regretting this and ripping it out. that has been my general experience w/ state machines. we'll see, this time around. :)

@davedx
Copy link

davedx commented Nov 14, 2012

It looks clean enough to me. Workflow engines are going to be state machines I would have thought. Maybe if I get a chance I'll try to implement it with coroutines and see if that works. Good luck with it! :)

@JohnDMathis
Copy link

Make sense for a wizard-like linear workflow. When I think of "state machine" I don't immediately think of "linear", though. Agree you'll want a "CanMoveToStep" type function that you can check to manage availability of steps. What if you kept that in the workflow controller, and various steps (views?) raised events to mark when it is ready, or not?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment