M
Michael Schuerig
I've implemented a small internal "domain-specific language" (or rather
a fluent interface) for defining finite state machines in JavaScript.
The description of a simple machine looks like this
var Machine = FSM.build(function(fsm) { with (fsm) {
onUnexpectedEvent(function() { ... });
state('start', 'initial')
.event('go')
.goesTo('middle')
.doing(function() { ... })
.doing('phew')
.event('run')
.goesTo('finish')
.onExiting(function() { ... });
state('middle')
.onUnexpectedEvent(function() { ... })
.onEntering(function() { ... })
.event('back')
.goesTo('start')
.onlyIf(function() { return true_or_false })
.event('go')
.goesTo('finish');
state('finish', 'final');
}});
Here's how such a machine is inserted into the prototype chain of an
object that acts as the context for the machine.
function TestMachine() {}
// amend TestMachine.prototype here all the way you want
TestMachine.prototype.phew = function() { ... };
TestMachine.prototype = new Machine(TestMachine.prototype);
var m = new TestMachine();
m.isStart(); //-> true
m.go();
m.isMiddle(); //-> true
The script itself has no external dependencies, however, the tests and
example use js-spec and Prototoype.
The script itself and a package with tests and example are at
http://schuerig.de/michael/blog/index.php/2007/12/30/jsfsm-022/
http://schuerig.de/michael/blog/index.php/2007/12/22/javascript-fsm/
I'd appreciate constructive criticism, here and on my blog. There are
three topics I'm particularly interested in
- (more) elegant ways of managing what 'this' means
- how to minimize the size of closures
- memory leaks. Are there any? How would I track them down and fix them?
Michael
a fluent interface) for defining finite state machines in JavaScript.
The description of a simple machine looks like this
var Machine = FSM.build(function(fsm) { with (fsm) {
onUnexpectedEvent(function() { ... });
state('start', 'initial')
.event('go')
.goesTo('middle')
.doing(function() { ... })
.doing('phew')
.event('run')
.goesTo('finish')
.onExiting(function() { ... });
state('middle')
.onUnexpectedEvent(function() { ... })
.onEntering(function() { ... })
.event('back')
.goesTo('start')
.onlyIf(function() { return true_or_false })
.event('go')
.goesTo('finish');
state('finish', 'final');
}});
Here's how such a machine is inserted into the prototype chain of an
object that acts as the context for the machine.
function TestMachine() {}
// amend TestMachine.prototype here all the way you want
TestMachine.prototype.phew = function() { ... };
TestMachine.prototype = new Machine(TestMachine.prototype);
var m = new TestMachine();
m.isStart(); //-> true
m.go();
m.isMiddle(); //-> true
The script itself has no external dependencies, however, the tests and
example use js-spec and Prototoype.
The script itself and a package with tests and example are at
http://schuerig.de/michael/blog/index.php/2007/12/30/jsfsm-022/
http://schuerig.de/michael/blog/index.php/2007/12/22/javascript-fsm/
I'd appreciate constructive criticism, here and on my blog. There are
three topics I'm particularly interested in
- (more) elegant ways of managing what 'this' means
- how to minimize the size of closures
- memory leaks. Are there any? How would I track them down and fix them?
Michael