Skip to content

Commit d19a2ab

Browse files
committed
Merge pull request phaserjs#1389 from pnstickne/wip-event-signal-redux2
Event-Signal object count optimization
2 parents 0744ddd + d15037e commit d19a2ab

10 files changed

Lines changed: 118 additions & 115 deletions

File tree

src/animation/Animation.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ Phaser.Animation.prototype = {
203203
this._parent.tilingTexture = false;
204204
}
205205

206-
this._parent.events.onAnimationStart.dispatch(this._parent, this);
206+
this._parent.events.onAnimationStart$dispatch(this._parent, this);
207207

208208
this.onStart.dispatch(this._parent, this);
209209

@@ -319,7 +319,7 @@ Phaser.Animation.prototype = {
319319

320320
if (dispatchComplete)
321321
{
322-
this._parent.events.onAnimationComplete.dispatch(this._parent, this);
322+
this._parent.events.onAnimationComplete$dispatch(this._parent, this);
323323
this.onComplete.dispatch(this._parent, this);
324324
}
325325

@@ -393,7 +393,7 @@ Phaser.Animation.prototype = {
393393
this._frameIndex %= this._frames.length;
394394
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
395395
this.loopCount++;
396-
this._parent.events.onAnimationLoop.dispatch(this._parent, this);
396+
this._parent.events.onAnimationLoop$dispatch(this._parent, this);
397397
this.onLoop.dispatch(this._parent, this);
398398
}
399399
else
@@ -578,7 +578,7 @@ Phaser.Animation.prototype = {
578578
this.isFinished = true;
579579
this.paused = false;
580580

581-
this._parent.events.onAnimationComplete.dispatch(this._parent, this);
581+
this._parent.events.onAnimationComplete$dispatch(this._parent, this);
582582

583583
this.onComplete.dispatch(this._parent, this);
584584

src/animation/AnimationManager.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,6 @@ Phaser.AnimationManager.prototype = {
196196
}
197197
}
198198

199-
// Create the signals the AnimationManager will emit
200-
if (this.sprite.events.onAnimationStart === null)
201-
{
202-
this.sprite.events.onAnimationStart = new Phaser.Signal();
203-
this.sprite.events.onAnimationComplete = new Phaser.Signal();
204-
this.sprite.events.onAnimationLoop = new Phaser.Signal();
205-
}
206-
207199
this._outputFrames.length = 0;
208200

209201
this._frameData.getFrameIndexes(frames, useNumericIndex, this._outputFrames);

src/core/Group.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ Phaser.Group.prototype.add = function (child, silent) {
214214

215215
if (!silent && child.events)
216216
{
217-
child.events.onAddedToGroup.dispatch(child, this);
217+
child.events.onAddedToGroup$dispatch(child, this);
218218
}
219219

220220
if (this.cursor === null)
@@ -278,7 +278,7 @@ Phaser.Group.prototype.addAt = function (child, index, silent) {
278278

279279
if (!silent && child.events)
280280
{
281-
child.events.onAddedToGroup.dispatch(child, this);
281+
child.events.onAddedToGroup$dispatch(child, this);
282282
}
283283

284284
if (this.cursor === null)
@@ -344,7 +344,7 @@ Phaser.Group.prototype.create = function (x, y, key, frame, exists) {
344344

345345
if (child.events)
346346
{
347-
child.events.onAddedToGroup.dispatch(child, this);
347+
child.events.onAddedToGroup$dispatch(child, this);
348348
}
349349

350350
if (this.cursor === null)
@@ -639,7 +639,7 @@ Phaser.Group.prototype.replace = function (oldChild, newChild) {
639639
{
640640
if (newChild.parent !== undefined)
641641
{
642-
newChild.events.onRemovedFromGroup.dispatch(newChild, this);
642+
newChild.events.onRemovedFromGroup$dispatch(newChild, this);
643643
newChild.parent.removeChild(newChild);
644644

645645
if (newChild.parent instanceof Phaser.Group)
@@ -1669,7 +1669,7 @@ Phaser.Group.prototype.remove = function (child, destroy, silent) {
16691669

16701670
if (!silent && child.events && !child.destroyPhase)
16711671
{
1672-
child.events.onRemovedFromGroup.dispatch(child, this);
1672+
child.events.onRemovedFromGroup$dispatch(child, this);
16731673
}
16741674

16751675
var removed = this.removeChild(child);
@@ -1712,7 +1712,7 @@ Phaser.Group.prototype.removeAll = function (destroy, silent) {
17121712
{
17131713
if (!silent && this.children[0].events)
17141714
{
1715-
this.children[0].events.onRemovedFromGroup.dispatch(this.children[0], this);
1715+
this.children[0].events.onRemovedFromGroup$dispatch(this.children[0], this);
17161716
}
17171717

17181718
var removed = this.removeChild(this.children[0]);
@@ -1759,7 +1759,7 @@ Phaser.Group.prototype.removeBetween = function (startIndex, endIndex, destroy,
17591759
{
17601760
if (!silent && this.children[i].events)
17611761
{
1762-
this.children[i].events.onRemovedFromGroup.dispatch(this.children[i], this);
1762+
this.children[i].events.onRemovedFromGroup$dispatch(this.children[i], this);
17631763
}
17641764

17651765
var removed = this.removeChild(this.children[i]);

src/gameobjects/Events.js

Lines changed: 85 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
*
1414
* Where `yourFunction` is the function you want called when this event occurs.
1515
*
16-
* Note that the Input related events only exist if the Sprite has had `inputEnabled` set to `true`.
16+
* The Input-related events will only be dispatched if the Sprite has had `inputEnabled` set to `true`
17+
* and the Animation-related events only apply to game objects with animations like {@link Phaser.Sprite}.
1718
*
1819
* @class Phaser.Events
1920
* @constructor
20-
* @param {Phaser.Sprite} sprite - A reference to the Sprite that owns this Events object.
21+
* @param {Phaser.Sprite} sprite - A reference to the game object / Sprite that owns this Events object.
2122
*/
2223
Phaser.Events = function (sprite) {
2324

@@ -26,140 +27,160 @@ Phaser.Events = function (sprite) {
2627
*/
2728
this.parent = sprite;
2829

30+
// The signals are automatically added by the corresponding proxy properties
31+
32+
};
33+
34+
Phaser.Events.prototype = {
35+
36+
/**
37+
* Removes all events.
38+
*
39+
* @method Phaser.Events#destroy
40+
*/
41+
destroy: function () {
42+
43+
this._parent = null;
44+
45+
if (this._onDestroy) { this._onDestroy.dispose(); }
46+
if (this._onAddedToGroup) { this._onAddedToGroup.dispose(); }
47+
if (this._onRemovedFromGroup) { this._onRemovedFromGroup.dispose(); }
48+
if (this._onRemovedFromWorld) { this._onRemovedFromWorld.dispose(); }
49+
if (this._onKilled) { this._onKilled.dispose(); }
50+
if (this._onRevived) { this._onRevived.dispose(); }
51+
if (this._onOutOfBounds) { this._onOutOfBounds.dispose(); }
52+
53+
if (this._onInputOver) { this._onInputOver.dispose(); }
54+
if (this._onInputOut) { this._onInputOut.dispose(); }
55+
if (this._onInputDown) { this._onInputDown.dispose(); }
56+
if (this._onInputUp) { this._onInputUp.dispose(); }
57+
if (this._onDragStart) { this._onDragStart.dispose(); }
58+
if (this._onDragStop) { this._onDragStop.dispose(); }
59+
60+
if (this._onAnimationStart) { this._onAnimationStart.dispose(); }
61+
if (this._onAnimationComplete) { this._onAnimationComplete.dispose(); }
62+
if (this._onAnimationLoop) { this._onAnimationLoop.dispose(); }
63+
64+
},
65+
66+
// The following properties are sentinels that will be replaced with getters
67+
2968
/**
3069
* @property {Phaser.Signal} onAddedToGroup - This signal is dispatched when the parent is added to a new Group.
3170
*/
32-
this.onAddedToGroup = new Phaser.Signal();
71+
onAddedToGroup: null,
3372

3473
/**
3574
* @property {Phaser.Signal} onRemovedFromGroup - This signal is dispatched when the parent is removed from a Group.
3675
*/
37-
this.onRemovedFromGroup = new Phaser.Signal();
76+
onRemovedFromGroup: null,
3877

3978
/**
4079
* @property {Phaser.Signal} onRemovedFromWorld - This signal is dispatched if this item or any of its parents are removed from the game world.
4180
*/
42-
this.onRemovedFromWorld = new Phaser.Signal();
81+
onRemovedFromWorld: null,
4382

4483
/**
4584
* @property {Phaser.Signal} onDestroy - This signal is dispatched when the parent is destoyed.
4685
*/
47-
this.onDestroy = new Phaser.Signal();
86+
onDestroy: null,
4887

4988
/**
5089
* @property {Phaser.Signal} onKilled - This signal is dispatched when the parent is killed.
5190
*/
52-
this.onKilled = new Phaser.Signal();
91+
onKilled: null,
5392

5493
/**
5594
* @property {Phaser.Signal} onRevived - This signal is dispatched when the parent is revived.
5695
*/
57-
this.onRevived = new Phaser.Signal();
96+
onRevived: null,
5897

5998
/**
6099
* @property {Phaser.Signal} onOutOfBounds - This signal is dispatched when the parent leaves the world bounds (only if Sprite.checkWorldBounds is true).
61100
*/
62-
this.onOutOfBounds = new Phaser.Signal();
101+
onOutOfBounds: null,
63102

64103
/**
65104
* @property {Phaser.Signal} onEnterBounds - This signal is dispatched when the parent returns within the world bounds (only if Sprite.checkWorldBounds is true).
66105
*/
67-
this.onEnterBounds = new Phaser.Signal();
106+
onEnterBounds: null,
68107

69108
/**
70109
* @property {Phaser.Signal} onInputOver - This signal is dispatched if the parent is inputEnabled and receives an over event from a Pointer.
71-
* @default null
72110
*/
73-
this.onInputOver = null;
111+
onInputOver: null,
74112

75113
/**
76114
* @property {Phaser.Signal} onInputOut - This signal is dispatched if the parent is inputEnabled and receives an out event from a Pointer.
77-
* @default null
78115
*/
79-
this.onInputOut = null;
116+
onInputOut: null,
80117

81118
/**
82119
* @property {Phaser.Signal} onInputDown - This signal is dispatched if the parent is inputEnabled and receives a down event from a Pointer.
83-
* @default null
84120
*/
85-
this.onInputDown = null;
121+
onInputDown: null,
86122

87123
/**
88124
* @property {Phaser.Signal} onInputUp - This signal is dispatched if the parent is inputEnabled and receives an up event from a Pointer.
89-
* @default null
90125
*/
91-
this.onInputUp = null;
126+
onInputUp: null,
92127

93128
/**
94129
* @property {Phaser.Signal} onDragStart - This signal is dispatched if the parent is inputEnabled and receives a drag start event from a Pointer.
95-
* @default null
96130
*/
97-
this.onDragStart = null;
131+
onDragStart: null,
98132

99133
/**
100134
* @property {Phaser.Signal} onDragStop - This signal is dispatched if the parent is inputEnabled and receives a drag stop event from a Pointer.
101-
* @default null
102135
*/
103-
this.onDragStop = null;
136+
onDragStop: null,
104137

105138
/**
106139
* @property {Phaser.Signal} onAnimationStart - This signal is dispatched when the parent has an animation that is played.
107-
* @default null
108140
*/
109-
this.onAnimationStart = null;
141+
onAnimationStart: null,
110142

111143
/**
112144
* @property {Phaser.Signal} onAnimationComplete - This signal is dispatched when the parent has an animation that finishes playing.
113-
* @default null
114145
*/
115-
this.onAnimationComplete = null;
146+
onAnimationComplete: null,
116147

117148
/**
118149
* @property {Phaser.Signal} onAnimationLoop - This signal is dispatched when the parent has an animation that loops playback.
119-
* @default null
120150
*/
121-
this.onAnimationLoop = null;
151+
onAnimationLoop: null
122152

123153
};
124154

125-
Phaser.Events.prototype = {
155+
Phaser.Events.prototype.constructor = Phaser.Events;
126156

127-
/**
128-
* Removes all events.
129-
*
130-
* @method Phaser.Events#destroy
131-
*/
132-
destroy: function () {
157+
// Create an auto-create proxy getter and dispatch method for all events.
158+
// The backing property is the same as the event name, prefixed with '_'
159+
// and the dispatch method is the same as the event name postfixed with '$dispatch'.
160+
for (var prop in Phaser.Events.prototype)
161+
{
162+
163+
if (!Phaser.Events.prototype.hasOwnProperty(prop) ||
164+
prop.indexOf('on') !== 0 ||
165+
Phaser.Events.prototype[prop] !== null)
166+
{
167+
continue;
168+
}
133169

134-
this.parent = null;
135-
136-
this.onDestroy.dispose();
137-
this.onAddedToGroup.dispose();
138-
this.onRemovedFromGroup.dispose();
139-
this.onRemovedFromWorld.dispose();
140-
this.onKilled.dispose();
141-
this.onRevived.dispose();
142-
this.onOutOfBounds.dispose();
143-
144-
if (this.onInputOver)
145-
{
146-
this.onInputOver.dispose();
147-
this.onInputOut.dispose();
148-
this.onInputDown.dispose();
149-
this.onInputUp.dispose();
150-
this.onDragStart.dispose();
151-
this.onDragStop.dispose();
152-
}
153-
154-
if (this.onAnimationStart)
155-
{
156-
this.onAnimationStart.dispose();
157-
this.onAnimationComplete.dispose();
158-
this.onAnimationLoop.dispose();
159-
}
170+
var backing = 'this._' + prop;
171+
var dispatch = prop + '$dispatch';
160172

161-
}
173+
// `new Function(string)` is ugly but it avoids closures and by-string property lookups.
174+
// Since this is a [near] micro-optimization anyway, might as well go all the way.
175+
/*jslint evil: true */
162176

163-
};
177+
// The accessor creates a new Signal (and so it should only be used from user-code.)
178+
Object.defineProperty(Phaser.Events.prototype, prop, {
179+
get: new Function("return "+backing+" || ("+backing+" = new Phaser.Signal())")
180+
});
164181

165-
Phaser.Events.prototype.constructor = Phaser.Events;
182+
// The dispatcher will only broadcast on an already-defined signal.
183+
Phaser.Events.prototype[dispatch] =
184+
new Function("return "+backing+" ? "+backing+".dispatch.apply("+backing+", arguments) : null");
185+
186+
}

src/gameobjects/Image.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ Phaser.Image.prototype.revive = function() {
479479

480480
if (this.events)
481481
{
482-
this.events.onRevived.dispatch(this);
482+
this.events.onRevived$dispatch(this);
483483
}
484484

485485
return this;
@@ -504,7 +504,7 @@ Phaser.Image.prototype.kill = function() {
504504

505505
if (this.events)
506506
{
507-
this.events.onKilled.dispatch(this);
507+
this.events.onKilled$dispatch(this);
508508
}
509509

510510
return this;
@@ -529,7 +529,7 @@ Phaser.Image.prototype.destroy = function(destroyChildren) {
529529

530530
if (this.events)
531531
{
532-
this.events.onDestroy.dispatch(this);
532+
this.events.onDestroy$dispatch(this);
533533
}
534534

535535
if (this.parent)

0 commit comments

Comments
 (0)