Skip to content

Commit 568eb5e

Browse files
committed
Large refactor after some performance profiling. Works a lot better as a single array. No deep iteration any more, and cleaner data structure.
1 parent b05e47c commit 568eb5e

9 files changed

Lines changed: 163 additions & 79 deletions

File tree

v3/src/checksum.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
var CHECKSUM = {
2-
build: '8ccbee50-4017-11e7-a8e1-659b1139a509'
2+
build: '68461dd0-4026-11e7-bdc5-9f162ef42266'
33
};
44
module.exports = CHECKSUM;

v3/src/tween/ReservedProps.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ module.exports = [
1212
'props',
1313
'repeat',
1414
'repeatDelay',
15-
'stagger',
1615
'startAt',
1716
'startDelay',
1817
'targets',

v3/src/tween/Tween.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
var TWEEN_CONST = require('./const');
22

3-
var Tween = function (manager, targets, tweenData)
3+
var Tween = function (manager, data)
44
{
55
this.manager = manager;
66

7-
// Array of targets being tweened (TweenTarget objects)
8-
this.targets = targets;
9-
10-
// targets array doesn't change, so we can cache the length
11-
this.totalTargets = targets.length;
12-
13-
// An array of TweenData objects, each containing a unique property being tweened.
14-
this.data = tweenData;
7+
// An array of TweenData objects, each containing a unique property and target being tweened.
8+
this.data = data;
159

1610
// data array doesn't change, so we can cache the length
17-
this.totalData = tweenData.length;
11+
this.totalData = data.length;
12+
13+
// Cached target total (not necessarily the same as the data total)
14+
this.totalTargets = 0;
1815

1916
// If true then duration, delay, etc values are all frame totals
2017
this.useFrames = false;
@@ -31,7 +28,7 @@ var Tween = function (manager, targets, tweenData)
3128
// Time in ms/frames before the tween loops again if loop is true
3229
this.loopDelay = 0;
3330

34-
// Time in ms/frames before the 'onComplete' event fires.
31+
// Time in ms/frames before the 'onComplete' event fires. This never fires if loop = true (as it never completes)
3532
this.completeDelay = 0;
3633

3734
// Countdown timer (used by startDelay, loopDelay and completeDelay)
@@ -45,6 +42,7 @@ var Tween = function (manager, targets, tweenData)
4542
onStart: { callback: null, scope: null, params: null },
4643
onUpdate: { callback: null, scope: null, params: null },
4744
onRepeat: { callback: null, scope: null, params: null },
45+
onLoop: { callback: null, scope: null, params: null },
4846
onComplete: { callback: null, scope: null, params: null }
4947
};
5048

v3/src/tween/TweenBuilder.js

Lines changed: 96 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ var Tween = require('./Tween');
44
var RESERVED = require('./ReservedProps');
55
var GetEaseFunction = require('./GetEaseFunction');
66
var TweenData = require('./TweenData');
7-
var TweenTarget = require('./TweenTarget');
87

9-
var GetTargets = function (config, props)
8+
var GetTargets = function (config)
109
{
1110
var targets = GetValue(config, 'targets', null);
1211

@@ -20,21 +19,7 @@ var GetTargets = function (config, props)
2019
targets = [ targets ];
2120
}
2221

23-
var out = [];
24-
25-
for (var i = 0; i < targets.length; i++)
26-
{
27-
var keyData = {};
28-
29-
for (var p = 0; p < props.length; p++)
30-
{
31-
keyData[props[p].key] = { start: 0, current: 0, end: 0, startCache: null, endCache: null };
32-
}
33-
34-
out.push(TweenTarget(targets[i], keyData));
35-
}
36-
37-
return out;
22+
return targets;
3823
};
3924

4025
var GetProps = function (config)
@@ -133,13 +118,14 @@ var GetValueOp = function (key, value)
133118
}
134119
else if (t === 'function')
135120
{
136-
// Technically this could return a number, string or object
137121
// props: {
138-
// x: function () { return Math.random() * 10 },
139-
// y: someOtherCallback
122+
// x: function (startValue, target, index, totalTargets) { return startValue + (index * 50); },
140123
// }
141124

142-
valueCallback = GetValueOp(key, value.call());
125+
valueCallback = function (startValue, target, index, total)
126+
{
127+
return value(startValue, target, index, total);
128+
};
143129
}
144130
else if (value.hasOwnProperty('value'))
145131
{
@@ -155,20 +141,75 @@ var GetValueOp = function (key, value)
155141
return valueCallback;
156142
};
157143

144+
var GetBoolean = function (source, key, defaultValue)
145+
{
146+
if (!source)
147+
{
148+
return defaultValue;
149+
}
150+
else if (source.hasOwnProperty(key))
151+
{
152+
return source[key];
153+
}
154+
else
155+
{
156+
return defaultValue;
157+
}
158+
};
159+
160+
var GetNewValue = function (source, key, defaultValue)
161+
{
162+
var valueCallback;
163+
164+
if (source.hasOwnProperty(key))
165+
{
166+
var t = typeof(source[key]);
167+
168+
if (t === 'function')
169+
{
170+
valueCallback = function (index, totalTargets, target)
171+
{
172+
return source[key](index, totalTargets, target);
173+
};
174+
}
175+
else
176+
{
177+
valueCallback = function ()
178+
{
179+
return source[key];
180+
};
181+
}
182+
}
183+
else if (typeof defaultValue === 'function')
184+
{
185+
valueCallback = defaultValue;
186+
}
187+
else
188+
{
189+
valueCallback = function ()
190+
{
191+
return defaultValue;
192+
};
193+
}
194+
195+
return valueCallback;
196+
};
197+
158198
var TweenBuilder = function (manager, config)
159199
{
160200
// Create arrays of the Targets and the Properties
201+
var targets = GetTargets(config);
161202
var props = GetProps(config);
162203

163204
// Default Tween values
164205
var ease = GetEaseFunction(GetValue(config, 'ease', 'Power0'));
165-
var duration = GetAdvancedValue(config, 'duration', 1000);
166-
var yoyo = GetValue(config, 'yoyo', false);
167-
var yoyoDelay = GetAdvancedValue(config, 'yoyoDelay', 0);
168-
var repeat = GetAdvancedValue(config, 'repeat', 0);
169-
var repeatDelay = GetAdvancedValue(config, 'repeatDelay', 0);
170-
var delay = GetAdvancedValue(config, 'delay', 0);
171-
var startAt = GetAdvancedValue(config, 'startAt', null);
206+
var duration = GetNewValue(config, 'duration', 1000);
207+
var yoyo = GetBoolean(config, 'yoyo', false);
208+
var yoyoDelay = GetNewValue(config, 'yoyoDelay', 0);
209+
var repeat = GetNewValue(config, 'repeat', 0);
210+
var repeatDelay = GetNewValue(config, 'repeatDelay', 0);
211+
var delay = GetNewValue(config, 'delay', 0);
212+
var startAt = GetNewValue(config, 'startAt', null);
172213

173214
var data = [];
174215

@@ -178,36 +219,38 @@ var TweenBuilder = function (manager, config)
178219
var key = props[p].key;
179220
var value = props[p].value;
180221

181-
var tweenData = TweenData(
182-
key,
183-
GetValueOp(key, value),
184-
GetEaseFunction(GetValue(value, 'ease', ease)),
185-
GetAdvancedValue(value, 'delay', delay),
186-
GetAdvancedValue(value, 'duration', duration),
187-
GetValue(value, 'yoyo', yoyo),
188-
GetAdvancedValue(value, 'yoyoDelay', yoyoDelay),
189-
GetAdvancedValue(value, 'repeat', repeat),
190-
GetAdvancedValue(value, 'repeatDelay', repeatDelay),
191-
GetAdvancedValue(value, 'startAt', startAt)
192-
);
193-
194-
// TODO: Calculate total duration
195-
196-
data.push(tweenData);
222+
for (var t = 0; t < targets.length; t++)
223+
{
224+
// Swap for faster getters, if they want Advanced Value style things, they can do it via their own functions
225+
var tweenData = TweenData(
226+
targets[t],
227+
key,
228+
GetValueOp(key, value),
229+
GetEaseFunction(GetValue(value, 'ease', ease)),
230+
GetNewValue(value, 'delay', delay),
231+
GetNewValue(value, 'duration', duration),
232+
GetBoolean(value, 'yoyo', yoyo),
233+
GetNewValue(value, 'yoyoDelay', yoyoDelay),
234+
GetNewValue(value, 'repeat', repeat),
235+
GetNewValue(value, 'repeatDelay', repeatDelay),
236+
GetNewValue(value, 'startAt', startAt)
237+
);
238+
239+
// TODO: Calculate total duration
240+
241+
data.push(tweenData);
242+
}
197243
}
198244

199-
var targets = GetTargets(config, props);
200-
201-
var tween = new Tween(manager, targets, data);
202-
203-
var stagger = GetAdvancedValue(config, 'stagger', 0);
245+
var tween = new Tween(manager, data);
204246

205-
tween.useFrames = GetValue(config, 'useFrames', false);
206-
tween.loop = GetValue(config, 'loop', false);
247+
tween.totalTargets = targets.length;
248+
tween.useFrames = GetBoolean(config, 'useFrames', false);
249+
tween.loop = GetBoolean(config, 'loop', false);
207250
tween.loopDelay = GetAdvancedValue(config, 'loopDelay', 0);
208251
tween.completeDelay = GetAdvancedValue(config, 'completeDelay', 0);
209-
tween.startDelay = GetAdvancedValue(config, 'startDelay', 0) + (stagger * targets.length);
210-
tween.paused = GetValue(config, 'paused', false);
252+
tween.startDelay = GetAdvancedValue(config, 'startDelay', 0);
253+
tween.paused = GetBoolean(config, 'paused', false);
211254

212255
return tween;
213256
};

v3/src/tween/TweenData.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
var TweenData = function (key, value, ease, delay, duration, yoyo, yoyoDelay, repeat, repeatDelay, startAt)
1+
var TweenData = function (target, key, value, ease, delay, duration, yoyo, yoyoDelay, repeat, repeatDelay, startAt)
22
{
33
return {
44

5+
// The target to tween
6+
target: target,
7+
58
// The property of the target to tween
69
key: key,
710

@@ -12,25 +15,25 @@ var TweenData = function (key, value, ease, delay, duration, yoyo, yoyoDelay, re
1215
ease: ease,
1316

1417
// Duration of the tween in ms/frames, excludes time for yoyo or repeats.
15-
duration: duration,
18+
duration: 0,
1619

1720
// The total calculated duration of this TweenData (based on duration, repeat, delay and yoyo)
1821
totalDuration: 0,
1922

2023
// Time in ms/frames before tween will start.
21-
delay: delay,
24+
delay: 0,
2225

2326
// Cause the tween to return back to its start value after yoyoDelay has expired.
2427
yoyo: yoyo,
2528

2629
// Time in ms/frames the tween will pause before running the yoyo (only applied if yoyo is true)
27-
yoyoDelay: yoyoDelay,
30+
yoyoDelay: 0,
2831

2932
// Number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice.
30-
repeat: repeat,
33+
repeat: 0,
3134

3235
// Time in ms/frames before the repeat will start.
33-
repeatDelay: repeatDelay,
36+
repeatDelay: 0,
3437

3538
// Changes the property to be this value before starting the tween.
3639
startAt: startAt,
@@ -44,6 +47,21 @@ var TweenData = function (key, value, ease, delay, duration, yoyo, yoyoDelay, re
4447
// How many repeats are left to run?
4548
repeatCounter: 0,
4649

50+
// Value Data:
51+
52+
start: 0,
53+
current: 0,
54+
end: 0,
55+
56+
// LoadValue generation functions
57+
gen: {
58+
delay: delay,
59+
duration: duration,
60+
yoyoDelay: yoyoDelay,
61+
repeat: repeat,
62+
repeatDelay: repeatDelay
63+
},
64+
4765
// TWEEN_CONST.CREATED
4866
state: 0
4967
};

v3/src/tween/TweenTarget.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
var TweenTarget = function (target, keys)
22
{
3+
// keys: {
4+
// x: { start: 0, current: 0, end: 0, startCache: null, endCache: null },
5+
// y: { start: 0, current: 0, end: 0, startCache: null, endCache: null }
6+
// }
7+
38
return {
49

510
ref: target,

v3/src/tween/components/ResetTweenData.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,20 @@ var TWEEN_CONST = require('../const');
22

33
var ResetTweenData = function ()
44
{
5-
for (var key in this.data)
5+
var data = this.data;
6+
var totalTargets = this.totalTargets;
7+
8+
for (var i = 0; i < this.totalData; i++)
69
{
7-
var tweenData = this.data[key];
10+
var tweenData = data[i];
11+
var target = tweenData.target;
12+
var gen = tweenData.gen;
13+
14+
tweenData.delay = gen.delay(i, totalTargets, target);
15+
tweenData.duration = gen.duration(i, totalTargets, target);
16+
tweenData.yoyoDelay = gen.yoyoDelay(i, totalTargets, target);
17+
tweenData.repeat = gen.repeat(i, totalTargets, target);
18+
tweenData.repeatDelay = gen.repeatDelay(i, totalTargets, target);
819

920
tweenData.progress = 0;
1021
tweenData.elapsed = 0;

v3/src/tween/components/SetEventCallback.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
var SetEventCallback = function (type, callback, params, scope)
22
{
3-
var types = [ 'onStart', 'onUpdate', 'onRepeat', 'onComplete' ];
3+
var types = [ 'onStart', 'onUpdate', 'onRepeat', 'onLoop', 'onComplete' ];
44

55
if (types.indexOf(type) !== -1)
66
{

0 commit comments

Comments
 (0)