diff --git a/README.md b/README.md index 484c746..93af5ed 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ More information on statecharts is available here: # Example +## Lockable Door + ```javascript var State = (typeof require === 'function' ? require('statechart') : window.statechart).State; @@ -58,3 +60,172 @@ door.send('lockDoor'); door.current(); // => [ '/closed/locked' ] ``` +## Shallow History State + +```javascript +var State = (typeof require === 'function' ? require('statechart') : window.statechart).State; + +var sc = State.define(function() { + // State /a is marked as a history state, so any time /a is entered without + // specifying which substate to enter, the most recently exited substate of /a + // is chosen (or the first substate if /a has never been entered). + this.state('a', {H: true}, function() { + this.state('a.1') + this.state('a.2') + this.state('a.3') + }); + + this.state('b', function() { + this.state('b.1') + this.state('b.2') + this.state('b.3') + }); +}); + +sc.goto('/a/a.2'); +sc.current(); // => ['/a/a.2'] + +sc.goto('/b'); +sc.current(); // => ['/b/b.1'] + +sc.goto('/a'); +sc.current(); // => ['/a/a.2'] +``` + +## Deep History State + +```javascript +var State = (typeof require === 'function' ? require('statechart') : window.statechart).State; + +var sc = State.define(function() { + // State /a has shallow history tracking. + this.state('a', {H: true}, function() { + this.state('a.1', function() { + this.state('a.1.1'); + this.state('a.1.2'); + this.state('a.1.3'); + }); + + this.state('a.2', function() { + this.state('a.2.1'); + this.state('a.2.2'); + this.state('a.2.3'); + }); + }); + + // State /b has deep history tracking. This is the same as making each + // descendant state of /b a history state. + this.state('b', {H: '*'}, function() { + this.state('b.1', function() { + this.state('b.1.1'); + this.state('b.1.2'); + this.state('b.1.3'); + }); + + this.state('b.2', function() { + this.state('b.2.1'); + this.state('b.2.2'); + this.state('b.2.3'); + }); + }); +}); + +sc.goto('/a/a.2/a.2.2'); +sc.current(); // => ['/a/a.2/a.2.2'] + +sc.goto('/b/b.2/b.2.3'); +sc.current(); // => ['/b/b.2/b.2.3'] + +sc.goto('/a'); +sc.current(); // => ['/a/a.2/a.2.1'] + +sc.goto('/b'); +sc.current(); // => ['/b/b.2/b.2.3'] +``` + +## Concurrency + +```javascript +var State = (typeof require === 'function' ? require('statechart') : window.statechart).State; + +var word = State.define({concurrent: true}, function() { + this.state('bold', function() { + this.state('off', function() { + this.event('toggleBold', function() { this.goto('../on'); }); + }); + + this.state('on', function() { + this.event('toggleBold', function() { this.goto('../off'); }); + }); + }); + + this.state('underline', function() { + this.state('off', function() { + this.event('toggleUnderline', function() { this.goto('../on'); }); + }); + + this.state('on', function() { + this.event('toggleUnderline', function() { this.goto('../off'); }); + }); + }); + + this.state('align', function() { + this.state('left'); + this.state('right'); + this.state('center'); + this.state('justify'); + + this.event('leftClicked', function() { this.goto('./left');}); + this.event('rightClicked', function() { this.goto('./right');}); + this.event('centerClicked', function() { this.goto('./center');}); + this.event('justifyClicked', function() { this.goto('./justify');}); + }); + + this.state('bullets', function() { + this.state('none', function() { + this.event('regularClicked', function() { this.goto('../regular'); }) + this.event('numberClicked', function() { this.goto('../number'); }) + }); + + this.state('regular', function() { + this.event('regularClicked', function() { this.goto('../none'); }) + this.event('numberClicked', function() { this.goto('../number'); }) + }); + + this.state('number', function() { + this.event('regularClicked', function() { this.goto('../regular'); }) + this.event('numberClicked', function() { this.goto('../none'); }) + }); + }); + + this.event('reset', function() { this.goto(); }); +}); + +word.goto(); +word.current(); // => ['/bold/off', '/underline/off', '/align/left', '/bullets/none'] + +word.send('toggleBold'); +word.current(); // => ['/bold/on', '/underline/off', '/align/left', '/bullets/none'] + +word.send('toggleUnderline'); +word.current(); // => ['/bold/on', '/underline/on', '/align/left', '/bullets/none'] + +word.send('rightClicked'); +word.current(); // => ['/bold/on', '/underline/on', '/align/right', '/bullets/none'] + +word.send('justifyClicked'); +word.current(); // => ['/bold/on', '/underline/on', '/align/justify', '/bullets/none'] + +word.send('regularClicked'); +word.current(); // => ['/bold/on', '/underline/on', '/align/justify', '/bullets/regular'] + +word.send('regularClicked'); +word.current(); // => ['/bold/on', '/underline/on', '/align/justify', '/bullets/none'] + +word.send('numberClicked'); +word.current(); // => ['/bold/on', '/underline/on', '/align/justify', '/bullets/number'] + +word.send('reset'); +word.current(); // => ['/bold/off', '/underline/off', '/align/left', '/bullets/none'] +``` +