Skip to content

Commit 6b23075

Browse files
committed
Scene plugin flow overhaul
Every Plugin has been updated to correctly follow the same flow through the Scene lifecycle. Instead of listening for the Scene 'boot' event, which is only dispatched once (when the Scene is first created), they will now listen for the Scene 'start' event, which occurs every time the Scene is started. All plugins now consistently follow the same Shutdown and Destroy patterns too, meaning they tidy-up after themselves on a shutdown, not just a destroy. Overall, this change means that there should be less issues when returning to previously closed Scenes, as the plugins will restart themselves properly.
1 parent 44aff65 commit 6b23075

25 files changed

Lines changed: 619 additions & 317 deletions

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99
* The Animation component didn't properly check for the animation state in its update, causing pause / resume to fail. Fix #3556 (thanks @Antriel @siolfyr)
1010
* The Scene Manager would never reach an `isBooted` state if you didn't add any Scenes into the Game Config. Fix #3553 (thanks @rgk)
1111
* Fixed issue in HTMLAudioSound where `mute` would get into a recursive loop.
12+
* Every RenderTexture would draw the same content due to a mis-use of the CanvasPool (this would also effect TileSprites). Fix #3555 (thanks @kuoruan)
1213

1314
### Updates
1415

1516
* Removed the following properties from BaseSound as they are no longer required. Each class that extends BaseSound implements them directly as getters: `mute`, `loop`, `seek` and `volume`.
17+
* The Device.OS test to see if Phaser is running under node.js has been strengthened to support node-like environments like Vue (thanks @Chumper)
18+
* Every Plugin has been updated to correctly follow the same flow through the Scene lifecycle. Instead of listening for the Scene 'boot' event, which is only dispatched once (when the Scene is first created), they will now listen for the Scene 'start' event, which occurs every time the Scene is started. All plugins now consistently follow the same Shutdown and Destroy patterns too, meaning they tidy-up after themselves on a shutdown, not just a destroy. Overall, this change means that there should be less issues when returning to previously closed Scenes, as the plugins will restart themselves properly.
19+
* When shutting down a Scene all Game Objects that belong to the scene will now automatically destroy themselves. They would previously be removed from the display and update lists, but the objects themselves didn't self-destruct.
1620

1721
### Examples, Documentation and TypeScript
1822

src/cameras/2d/CameraManager.js

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,6 @@ var CameraManager = new Class({
6666
*/
6767
this.systems = scene.sys;
6868

69-
if (!scene.sys.settings.isBooted)
70-
{
71-
scene.sys.events.once('boot', this.boot, this);
72-
}
73-
7469
/**
7570
* The current Camera ID.
7671
*
@@ -100,25 +95,14 @@ var CameraManager = new Class({
10095
*/
10196
this.cameraPool = [];
10297

103-
if (scene.sys.settings.cameras)
104-
{
105-
// We have cameras to create
106-
this.fromJSON(scene.sys.settings.cameras);
107-
}
108-
else
109-
{
110-
// Make one
111-
this.add();
112-
}
113-
11498
/**
11599
* The default Camera in the Camera Manager.
116100
*
117101
* @name Phaser.Cameras.Scene2D.CameraManager#main
118102
* @type {Phaser.Cameras.Scene2D.Camera}
119103
* @since 3.0.0
120104
*/
121-
this.main = this.cameras[0];
105+
this.main;
122106

123107
/**
124108
* This scale affects all cameras. It's used by Scale Manager.
@@ -127,23 +111,42 @@ var CameraManager = new Class({
127111
* @type {number}
128112
* @since 3.0.0
129113
*/
130-
this.baseScale = 1.0;
114+
this.baseScale = 1;
115+
116+
scene.sys.events.on('start', this.start, this);
131117
},
132118

133119
/**
134-
* Called when the Camera Manager boots.
135-
* Starts the event listeners running.
120+
* This method is called automatically by the Scene when it is starting up.
121+
* It is responsible for creating local systems, properties and listening for Scene events.
122+
* Do not invoke it directly.
136123
*
137-
* @method Phaser.Cameras.Scene2D.CameraManager#boot
138-
* @since 3.0.0
124+
* @method Phaser.Cameras.Scene2D.CameraManager#start
125+
* @private
126+
* @since 3.4.1
139127
*/
140-
boot: function ()
128+
start: function ()
141129
{
142-
var eventEmitter = this.systems.events;
130+
var sys = this.systems;
131+
132+
if (sys.settings.cameras)
133+
{
134+
// We have cameras to create
135+
this.fromJSON(sys.settings.cameras);
136+
}
137+
else
138+
{
139+
// Make one
140+
this.add();
141+
}
142+
143+
this.main = this.cameras[0];
144+
145+
var eventEmitter = sys.events;
143146

144147
eventEmitter.on('update', this.update, this);
145-
eventEmitter.on('shutdown', this.shutdown, this);
146-
eventEmitter.on('destroy', this.destroy, this);
148+
eventEmitter.once('shutdown', this.shutdown, this);
149+
eventEmitter.once('destroy', this.destroy, this);
147150
},
148151

149152
/**
@@ -444,23 +447,14 @@ var CameraManager = new Class({
444447
},
445448

446449
/**
447-
* [description]
450+
* The Scene that owns this plugin is shutting down.
451+
* We need to kill and reset all internal properties as well as stop listening to Scene events.
448452
*
449453
* @method Phaser.Cameras.Scene2D.CameraManager#shutdown
454+
* @private
450455
* @since 3.0.0
451456
*/
452457
shutdown: function ()
453-
{
454-
// TODO
455-
},
456-
457-
/**
458-
* [description]
459-
*
460-
* @method Phaser.Cameras.Scene2D.CameraManager#destroy
461-
* @since 3.0.0
462-
*/
463-
destroy: function ()
464458
{
465459
this.main = undefined;
466460

@@ -476,7 +470,29 @@ var CameraManager = new Class({
476470

477471
this.cameras = [];
478472
this.cameraPool = [];
479-
this.scene = undefined;
473+
474+
var eventEmitter = this.systems.events;
475+
476+
eventEmitter.off('update', this.update, this);
477+
eventEmitter.off('shutdown', this.shutdown, this);
478+
},
479+
480+
/**
481+
* The Scene that owns this plugin is being destroyed.
482+
* We need to shutdown and then kill off all external references.
483+
*
484+
* @method Phaser.Cameras.Scene2D.CameraManager#destroy
485+
* @private
486+
* @since 3.0.0
487+
*/
488+
destroy: function ()
489+
{
490+
this.shutdown();
491+
492+
this.scene.sys.events.off('start', this.start, this);
493+
494+
this.scene = null;
495+
this.systems = null;
480496
}
481497

482498
});

src/cameras/sprite3d/CameraManager.js

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,25 @@ var CameraManager = new Class({
5353
*/
5454
this.cameras = [];
5555

56-
if (!scene.sys.settings.isBooted)
57-
{
58-
scene.sys.events.once('boot', this.boot, this);
59-
}
56+
scene.sys.events.on('start', this.start, this);
6057
},
6158

6259
/**
63-
* [description]
60+
* This method is called automatically by the Scene when it is starting up.
61+
* It is responsible for creating local systems, properties and listening for Scene events.
62+
* Do not invoke it directly.
6463
*
65-
* @method Phaser.Cameras.Sprite3D.CameraManager#boot
66-
* @since 3.0.0
64+
* @method Phaser.Cameras.Sprite3D.CameraManager#start
65+
* @private
66+
* @since 3.4.1
6767
*/
68-
boot: function ()
68+
start: function ()
6969
{
7070
var eventEmitter = this.systems.events;
7171

7272
eventEmitter.on('update', this.update, this);
73-
eventEmitter.on('shutdown', this.shutdown, this);
74-
eventEmitter.on('destroy', this.destroy, this);
73+
eventEmitter.once('shutdown', this.shutdown, this);
74+
eventEmitter.once('destroy', this.destroy, this);
7575
},
7676

7777
/**
@@ -222,24 +222,39 @@ var CameraManager = new Class({
222222
},
223223

224224
/**
225-
* [description]
225+
* The Scene that owns this plugin is shutting down.
226+
* We need to kill and reset all internal properties as well as stop listening to Scene events.
226227
*
227228
* @method Phaser.Cameras.Sprite3D.CameraManager#shutdown
229+
* @private
228230
* @since 3.0.0
229231
*/
230232
shutdown: function ()
231233
{
234+
var eventEmitter = this.systems.events;
235+
236+
eventEmitter.off('update', this.update, this);
237+
eventEmitter.off('shutdown', this.shutdown, this);
238+
239+
this.removeAll();
232240
},
233241

234242
/**
235-
* [description]
243+
* The Scene that owns this plugin is being destroyed.
244+
* We need to shutdown and then kill off all external references.
236245
*
237246
* @method Phaser.Cameras.Sprite3D.CameraManager#destroy
247+
* @private
238248
* @since 3.0.0
239249
*/
240250
destroy: function ()
241251
{
242-
this.scene = undefined;
252+
this.shutdown();
253+
254+
this.scene.sys.events.off('start', this.start, this);
255+
256+
this.scene = null;
257+
this.systems = null;
243258
}
244259

245260
});

src/data/DataManagerPlugin.js

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ var DataManagerPlugin = new Class({
3030

3131
function DataManagerPlugin (scene)
3232
{
33+
DataManager.call(this, this.scene, scene.sys.events);
34+
3335
/**
3436
* [description]
3537
*
@@ -48,51 +50,58 @@ var DataManagerPlugin = new Class({
4850
*/
4951
this.systems = scene.sys;
5052

51-
if (!scene.sys.settings.isBooted)
52-
{
53-
scene.sys.events.once('boot', this.boot, this);
54-
}
55-
56-
DataManager.call(this, this.scene, scene.sys.events);
53+
scene.sys.events.on('start', this.start, this);
5754
},
5855

5956
/**
60-
* [description]
57+
* This method is called automatically by the Scene when it is starting up.
58+
* It is responsible for creating local systems, properties and listening for Scene events.
59+
* Do not invoke it directly.
6160
*
62-
* @method Phaser.Data.DataManagerPlugin#boot
63-
* @since 3.0.0
61+
* @method Phaser.Data.DataManagerPlugin#start
62+
* @private
63+
* @since 3.4.1
6464
*/
65-
boot: function ()
65+
start: function ()
6666
{
67+
this.events = this.scene.sys.events;
68+
6769
var eventEmitter = this.systems.events;
6870

69-
eventEmitter.on('shutdown', this.shutdownPlugin, this);
70-
eventEmitter.on('destroy', this.destroyPlugin, this);
71+
eventEmitter.once('shutdown', this.shutdown, this);
72+
eventEmitter.once('destroy', this.destroy, this);
7173
},
7274

7375
/**
74-
* [description]
76+
* The Scene that owns this plugin is shutting down.
77+
* We need to kill and reset all internal properties as well as stop listening to Scene events.
7578
*
76-
* @method Phaser.Data.DataManagerPlugin#shutdownPlugin
77-
* @since 3.0.0
79+
* @method Phaser.Data.DataManagerPlugin#shutdown
80+
* @private
81+
* @since 3.4.1
7882
*/
79-
shutdownPlugin: function ()
83+
shutdown: function ()
8084
{
81-
// Should we reset the events?
85+
var eventEmitter = this.systems.events;
86+
87+
eventEmitter.off('shutdown', this.shutdown, this);
8288
},
8389

8490
/**
85-
* [description]
91+
* The Scene that owns this plugin is being destroyed.
92+
* We need to shutdown and then kill off all external references.
8693
*
87-
* @method Phaser.Data.DataManagerPlugin#destroyPlugin
88-
* @since 3.0.0
94+
* @method Phaser.Data.DataManagerPlugin#destroy
95+
* @since 3.4.1
8996
*/
90-
destroyPlugin: function ()
97+
destroy: function ()
9198
{
92-
this.destroy();
99+
DataManager.prototype.destroy.call(this);
100+
101+
this.scene.sys.events.off('start', this.start, this);
93102

94-
this.scene = undefined;
95-
this.systems = undefined;
103+
this.scene = null;
104+
this.systems = null;
96105
}
97106

98107
});

0 commit comments

Comments
 (0)