-
Notifications
You must be signed in to change notification settings - Fork 116
/
state.js
98 lines (97 loc) · 2.39 KB
/
state.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* jshint globalstrict: true */
/* jshint browser: true */
/* jshint devel: true */
/* jshint jquery: true */
/* global util */
'use strict';
var makeState = function(initial) {
var checkpoints = [];
var maxTime = 0;
var timers = [];
var prev = function(time) {
return util.greatestLower(checkpoints,
function(m) { return m.time > time; });
};
var runTimers = function(time) {
var fire = [];
timers = timers.filter(function(timer) {
if (timer.time <= time) {
fire.push(timer);
return false;
} else {
return true;
}
});
fire.forEach(function(timer) {
timer.callback();
});
};
var self = {
current: initial,
getMaxTime: function() {
return maxTime;
},
init: function() {
checkpoints.push(util.clone(self.current));
},
fork: function() {
var i = prev(self.current.time);
while (checkpoints.length - 1 > i)
checkpoints.pop();
maxTime = self.current.time;
timers = [];
},
rewind: function(time) {
self.current = util.clone(checkpoints[prev(time)]);
self.current.time = time;
runTimers(time);
},
base: function() {
return checkpoints[prev(self.current.time)];
},
advance: function(time) {
maxTime = time;
self.current.time = time;
if (self.updater(self))
checkpoints.push(util.clone(self.current));
runTimers(time);
},
save: function() {
checkpoints.push(util.clone(self.current));
},
seek: function(time) {
if (time <= maxTime) {
self.rewind(time);
} else if (time > maxTime) {
self.advance(time);
}
},
updater: function() { return false; },
exportToString: function() {
return JSON.stringify({
checkpoints: checkpoints,
maxTime: maxTime,
});
},
importFromString: function(s) {
var o = JSON.parse(s);
checkpoints = o.checkpoints
maxTime = o.maxTime;
self.current = util.clone(checkpoints[0]);
self.current.time = 0;
timers = [];
},
clear: function() {
checkpoints = [];
self.current = initial;
self.current.time = 0;
maxTime = 0;
timers = [];
},
schedule: function(time, callback) {
timers.push({time: time, callback: callback});
},
};
self.current.time = 0;
return self;
};