Generates a state machine. You can add transitions and pass events so the machine changes its state and executes actions. Documentation is coming.
Downsized with the help of UglifyJS on marijn's website : http://marijnhaverbeke.nl/uglifyjs
Generates a state machine. You can add transitions and pass events so the machine changes its state and executes actions. Documentation is coming.
Downsized with the help of UglifyJS on marijn's website : http://marijnhaverbeke.nl/uglifyjs
| SM = function( | |
| a // stores the current state | |
| ,b // an object to store all states and their transitions | |
| ){ | |
| return b={} // Initializes b to an empty object | |
| ,{ | |
| add:function( // The function to add a state/transition | |
| a // The name of the state to add | |
| ,c // The event that will trigger the transition | |
| ,d // The action to perform | |
| ,e // The next state is optional | |
| ){ | |
| (b[a]=b[a]||{})[c]=[d,e] // Add a state c to object b (or assign default {}) | |
| // and use the result to store an array with [ action, nextState ] | |
| }, | |
| ev:function( // The function to send an event to the state machine | |
| c // The name of the event | |
| ,d | |
| ){ | |
| return d=b[a][c], // execute the action for the event corresponding in the current state | |
| d&&(d[0](),a=d[1]||a) // and return the next state that is assigned to the current state (for testing purpose) | |
| } | |
| } | |
| } |
| function(a,b){return b={},{add:function(a,c,d,e){(b[a]=b[a]||{})[c]=[d,e]},ev:function(c,d){return d=b[a][c],d&&(d[0](),a=d[1]||a)}}} |
| DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
| Version 2, December 2004 | |
| Copyright (C) 2011 YOUR_NAME_HERE <YOUR_URL_HERE> | |
| Everyone is permitted to copy and distribute verbatim or modified | |
| copies of this license document, and changing it is allowed as long | |
| as the name is changed. | |
| DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
| TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
| 0. You just DO WHAT THE FUCK YOU WANT TO. |
| { | |
| "name": "StateMachineGenerator", | |
| "description": "A state machine generator", | |
| "keywords": [ | |
| "state", | |
| "machine", | |
| "generator", | |
| "fsm", | |
| "design pattern" | |
| ] | |
| } |
| // JsTestDriver TestCase | |
| TestCase("SM", { | |
| "test SM API": function() { | |
| var sm = SM(); | |
| assertFunction(sm.add); | |
| assertFunction(sm.ev); | |
| }, | |
| "test SM transits between 2 states": function() { | |
| var open=function(){open.called=true}, | |
| close=function(){close.called=true}, | |
| sm = SM("closed"); | |
| // When in closed state, if the event is "open!" then execute the open action and go to opened state. | |
| sm.add("closed", "open!", open, "opened"); | |
| // the opposite | |
| sm.add("opened", "close!", close, "closed"); | |
| assertUndefined(open.called); | |
| assertEquals("opened", sm.ev("open!")); | |
| assertTrue(open.called); | |
| assertUndefined(close.called); | |
| assertEquals("closed", sm.ev("close!")); | |
| assertTrue(close.called); | |
| }, | |
| "test SM doesn't crash if wrong event in given state": function() { | |
| var sm = SM("state"); | |
| sm.add("state", "event", function(){}, "nextState"); | |
| assertUndefined(sm.ev("crash!")); | |
| }, | |
| "test the whole diagram": function() { | |
| var alarm = function () { alarm.called = true }, | |
| open = function () { open.called = true }, | |
| thank = function () { thank.called = true}, | |
| close = function () { close.called = true}, | |
| sm = SM("closed"); | |
| sm.add("closed", "pass", alarm); | |
| sm.add("closed", "coin", open, "opened"); | |
| sm.add("opened", "coin", thank); | |
| sm.add("opened", "pass", close, "closed"); | |
| assertEquals("closed", sm.ev("pass")); | |
| assertTrue(alarm.called); | |
| assertEquals("opened", sm.ev("coin")); | |
| assertTrue(open.called); | |
| assertEquals("opened", sm.ev("coin")); | |
| assertTrue(thank.called); | |
| assertEquals("closed", sm.ev("pass")); | |
| assertTrue(close.called); | |
| } | |
| }); |