Skip to content

Commit e6a4d99

Browse files
committed
nowtime() is time consuming operation, to provide a functional way to get values like getCurrentTime, getGlobalTime, getEntropy, getGlobalEntropy with ntime param. think about we have thousands of timeline based sprites need to do animiation, we can schedule a task to defeind nowtime just once, and pass it around to calc the time as needed, we can save tons of cpu time.
1 parent c2b63e2 commit e6a4d99

File tree

2 files changed

+113
-7
lines changed

2 files changed

+113
-7
lines changed

src/index.js

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,20 @@ class Timeline {
3232
// timeMark sorted by entropy
3333
// If you reset entropy, all the timeMarks behind the new entropy
3434
// should be dropped
35+
const ntime = options.ntime === undefined ? nowtime() : options.ntime;
36+
3537
this[_timeMark] = [{
36-
globalTime: this.globalTime,
38+
globalTime: this.getGlobalTime(ntime),
3739
localTime: -options.originTime,
3840
entropy: -options.originTime,
3941
playbackRate: options.playbackRate,
4042
globalEntropy: 0,
4143
}];
4244

43-
this[_createTime] = nowtime();
45+
this[_createTime] = ntime;
4446

4547
if(this[_parent]) {
46-
this[_timeMark][0].globalEntropy = this[_parent].entropy;
48+
this[_timeMark][0].globalEntropy = this[_parent].getEntropy(ntime);
4749
}
4850

4951
this[_originTime] = options.originTime;
@@ -59,13 +61,15 @@ class Timeline {
5961
return this[_timeMark][this[_timeMark].length - 1];
6062
}
6163

62-
markTime({time = this.currentTime, entropy = this.entropy, playbackRate = this.playbackRate} = {}) {
64+
markTime(options = {}) {
65+
const ntime = nowtime();
66+
const {time = this.getCurrentTime(ntime), entropy = this.getEntropy(ntime), playbackRate = this.playbackRate} = options;
6367
const timeMark = {
64-
globalTime: this.globalTime,
68+
globalTime: this.getGlobalTime(ntime),
6569
localTime: time,
6670
entropy,
6771
playbackRate,
68-
globalEntropy: this.globalEntropy,
72+
globalEntropy: this.getGlobalEntropy(ntime),
6973
};
7074
this[_timeMark].push(timeMark);
7175
}
@@ -75,6 +79,11 @@ class Timeline {
7579
return localTime + (this.globalTime - globalTime) * this.playbackRate;
7680
}
7781

82+
getCurrentTime(ntime) {
83+
const {localTime, globalTime} = this.lastTimeMark;
84+
return localTime + (this.getGlobalTime(ntime) - globalTime) * this.playbackRate;
85+
}
86+
7887
set currentTime(time) {
7988
const from = this.currentTime,
8089
to = time,
@@ -111,10 +120,22 @@ class Timeline {
111120
return entropy + Math.abs((this.globalEntropy - globalEntropy) * this.playbackRate);
112121
}
113122

123+
getEntropy(ntime) {
124+
const {entropy, globalEntropy} = this.lastTimeMark;
125+
return entropy + Math.abs((this.getGlobalEntropy(ntime) - globalEntropy) * this.playbackRate);
126+
}
127+
114128
get globalEntropy() {
115129
return this[_parent] ? this[_parent].entropy : nowtime() - this[_createTime];
116130
}
117131

132+
getGlobalEntropy(ntime) {
133+
if(this[_parent]) {
134+
return this[_parent].getEntropy(ntime);
135+
}
136+
return (ntime === undefined ? nowtime() : ntime) - this[_createTime];
137+
}
138+
118139
get globalTime() {
119140
if(this[_parent]) {
120141
return this[_parent].currentTime;
@@ -123,6 +144,13 @@ class Timeline {
123144
return nowtime();
124145
}
125146

147+
getGlobalTime(ntime) {
148+
if(this[_parent]) {
149+
return this[_parent].getCurrentTime(ntime);
150+
}
151+
return ntime === undefined ? nowtime() : ntime;
152+
}
153+
126154
// change entropy will NOT cause currentTime changing but may influence the pass
127155
// and the future of the timeline. (It may change the result of seek***Time)
128156
// While entropy is set, all the marks behind will be droped
@@ -291,7 +319,6 @@ class Timeline {
291319
globalTimeout = parent ? parent.setTimeout.bind(parent) : setTimeout;
292320

293321
const heading = time.heading;
294-
// console.log(heading, parent, delay)
295322
if(!parent && heading === false && delay < 0) {
296323
delay = Infinity;
297324
}
@@ -322,3 +349,4 @@ class Timeline {
322349
}
323350

324351
export default Timeline;
352+
export {nowtime};

test/get-methods.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import Timeline, {nowtime} from '../src/index'
2+
const colors = require('colors')
3+
const test = require("ava")
4+
5+
function makeTimeCompare(startTime) {
6+
return function (time, expect) {
7+
const precision = Math.abs(time - expect),
8+
passedTime = Math.max(Date.now() - startTime, 100),
9+
percent = precision / passedTime
10+
11+
let color = colors.green,
12+
pass = true
13+
14+
if(percent > 0.05 && percent <= 0.10) {
15+
color = colors.cyan
16+
}
17+
if(percent > 0.10 && percent <= 0.20) {
18+
color = colors.yellow
19+
}
20+
if(percent > 0.20) {
21+
color = colors.red
22+
pass = false
23+
}
24+
25+
return pass
26+
}
27+
}
28+
29+
function _caseSync(fn) {
30+
return function (t) {
31+
const startTime = Date.now()
32+
t.time_compare = makeTimeCompare(startTime)
33+
return fn(t)
34+
}
35+
}
36+
test('default nowtime', _caseSync(t => {
37+
38+
const timeline = new Timeline();
39+
40+
// no pass ntime will default to nowtime()
41+
t.truthy(t.time_compare(timeline.getCurrentTime(), 0));
42+
t.truthy(t.time_compare(timeline.getGlobalEntropy(), 0));
43+
}))
44+
45+
46+
test('timeline originTime', t => {
47+
const timeline = new Timeline({ntime: 0, originTime: 50})
48+
t.truthy(timeline.getCurrentTime(10) === -40);
49+
})
50+
51+
test('timeline paused', t => {
52+
const timeline = new Timeline({playbackRate: 0, ntime: 0});
53+
t.truthy(timeline.getCurrentTime(100) === 0);
54+
})
55+
56+
test('timeline playbackRate', t => {
57+
var timeline = new Timeline({ntime: 0, playbackRate: 2})
58+
t.truthy(timeline.getCurrentTime(100) === 200);
59+
60+
61+
timeline = new Timeline({ntime: 0, playbackRate: -2})
62+
t.truthy(timeline.getCurrentTime(100) === -200);
63+
})
64+
65+
test('timeline entropy', t => {
66+
const timeline = new Timeline({ntime: 0, playbackRate: -2});
67+
68+
t.truthy(timeline.getEntropy(200) === 400);
69+
})
70+
71+
test('timeline fork', t => {
72+
const timeline = new Timeline({playbackRate: 2, ntime: 0}),
73+
timeline2 = timeline.fork({playbackRate: 3, ntime: 80})
74+
75+
const passedTime = 100;
76+
t.truthy(timeline.getEntropy(passedTime) === passedTime * 2)
77+
t.truthy(timeline2.getEntropy(passedTime) === 20 * 6)
78+
})

0 commit comments

Comments
 (0)