forked from orbitbot/pastafarian
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpastafarian.js
76 lines (69 loc) · 2.03 KB
/
pastafarian.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
;(function (root) {
function ITE(prev, next) {
var error = Error.call(this, 'Transition from ' + prev + ' to ' + next + ' is not allowed');
error.name = 'IllegalTransitionException';
error.prev = prev;
error.attempt = next;
return error;
}
function FSM(config) {
var events = {};
var fsm = {
transitions : config.states,
current : config.initial,
error : config.error,
};
fsm.bind = function(evt, fn) {
events[evt] = events[evt] || [];
events[evt] = events[evt].concat(fn);
return fsm;
};
fsm.unbind = function(evt, fn) {
if (evt in events && events[evt].indexOf(fn) > -1)
events[evt].splice(events[evt].indexOf(fn), 1);
return fsm;
};
fsm.on = fsm.bind;
function onError(args) {
if (typeof fsm.error === 'function')
fsm.error.apply(this, args);
else
throw args[0];
}
function emit(evt, args) {
if (evt in events) {
for (var i = 0; i < events[evt].length; ++i) {
try {
events[evt][i].apply(this, args);
} catch (e) {
onError([e]);
}
}
}
};
fsm.go = function(next) {
var prev = fsm.current;
var params = Array.prototype.slice.call(arguments, 1);
if (fsm.transitions[prev].indexOf(next) > -1) {
emit('after:' + prev, [next].concat(params));
emit('before:' + next, [prev].concat(params));
fsm.current = next;
emit(next, [prev].concat(params));
emit('*', [prev, next].concat(params));
} else {
onError([new ITE(prev, next), prev, next].concat(params));
}
return fsm;
};
return fsm;
}
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
define(function () { return FSM; });
} else if (typeof module === 'object' && module.exports) {
module.exports = FSM;
} else if (typeof self !== 'undefined') {
self.StateMachine = FSM;
} else {
root.StateMachine = FSM;
}
}(this));