Skip to content

Commit f33ba5d

Browse files
committed
Timer has removed all use of local temporary vars in the core update loop.
Timer.clearPendingEvents will purge any events marked for deletion, this is run automatically at the start of the update loop. The main Timer loop could incorrectly remove TimeEvent if a new one was added specifically during an event callback (thanks @garyyeap, fix phaserjs#710)
1 parent 286882b commit f33ba5d

3 files changed

Lines changed: 61 additions & 37 deletions

File tree

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,22 @@ There is also an [un-official Getting Started Guide](http://www.antonoffplus.com
5656

5757
Version 2.0.4 - "Mos Shirare" - in development
5858

59+
5960
### Updates
6061

62+
* TypeScript definitions fixes and updates (thanks @clark-stevenson)
63+
* Timer has removed all use of local temporary vars in the core update loop.
64+
6165

6266
### New Features
6367

68+
* Loader now has an onFileStart event you can listen for (thanks @codevinsky, #705)
69+
* Timer.clearPendingEvents will purge any events marked for deletion, this is run automatically at the start of the update loop.
70+
6471

6572
### Bug Fixes
6673

74+
* The main Timer loop could incorrectly remove TimeEvent if a new one was added specifically during an event callback (thanks @garyyeap, fix #710)
6775

6876

6977
There is an extensive [Migration Guide](https://github.com/photonstorm/phaser/blob/master/resources/Migration%20Guide.md) available for those converting from Phaser 1.x to 2.x. In the guide we detail the API breaking changes and approach to our new physics system.

src/loader/Loader.js

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,29 +94,28 @@ Phaser.Loader = function (game) {
9494
*/
9595
this.baseURL = '';
9696

97+
/**
98+
* @property {Phaser.Signal} onLoadStart - This event is dispatched when the loading process starts, before the first file has been requested.
99+
*/
100+
this.onLoadStart = new Phaser.Signal();
97101

98102
/**
99-
* @property {Phaser.Signal} onFileStart - Event signal.
103+
* @property {Phaser.Signal} onFileStart - This event is dispatched immediately before a file starts loading. It's possible the file may still error (404, etc) after this event is sent.
100104
*/
101105
this.onFileStart = new Phaser.Signal();
102106

103107
/**
104-
* @property {Phaser.Signal} onFileComplete - Event signal.
108+
* @property {Phaser.Signal} onFileComplete - This event is dispatched when a file completes loading successfully.
105109
*/
106110
this.onFileComplete = new Phaser.Signal();
107111

108112
/**
109-
* @property {Phaser.Signal} onFileError - Event signal.
113+
* @property {Phaser.Signal} onFileError - This event is dispatched when a file errors as a result of the load request.
110114
*/
111115
this.onFileError = new Phaser.Signal();
112116

113117
/**
114-
* @property {Phaser.Signal} onLoadStart - Event signal.
115-
*/
116-
this.onLoadStart = new Phaser.Signal();
117-
118-
/**
119-
* @property {Phaser.Signal} onLoadComplete - Event signal.
118+
* @property {Phaser.Signal} onLoadComplete - This event is dispatched when the final file in the load queue has either loaded or failed.
120119
*/
121120
this.onLoadComplete = new Phaser.Signal();
122121

@@ -886,11 +885,11 @@ Phaser.Loader.prototype = {
886885
return;
887886
}
888887

889-
this.onFileStart.dispatch(this.progress, this._fileList[this._fileIndex]);
890-
891888
var file = this._fileList[this._fileIndex];
892889
var _this = this;
893890

891+
this.onFileStart.dispatch(this.progress, file.key);
892+
894893
// Image or Data?
895894
switch (file.type)
896895
{

src/time/Timer.js

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@ Phaser.Timer = function (game, autoDestroy) {
109109
*/
110110
this._i = 0;
111111

112+
/**
113+
* @property {number} _diff - Internal cache var.
114+
* @private
115+
*/
116+
this._diff = 0;
117+
118+
/**
119+
* @property {number} _newTick - Internal cache var.
120+
* @private
121+
*/
122+
this._newTick = 0;
123+
112124
};
113125

114126
/**
@@ -325,6 +337,28 @@ Phaser.Timer.prototype = {
325337

326338
},
327339

340+
/**
341+
* Clears any events from the Timer which have pendingDelete set to true and then resets the private _len and _i values.
342+
*
343+
* @method Phaser.Timer#clearPendingEvents
344+
*/
345+
clearPendingEvents: function () {
346+
347+
this._i = this.events.length;
348+
349+
while (this._i--)
350+
{
351+
if (this.events[this._i].pendingDelete)
352+
{
353+
this.events.splice(this._i, 1);
354+
}
355+
}
356+
357+
this._len = this.events.length;
358+
this._i = 0;
359+
360+
},
361+
328362
/**
329363
* The main Timer update event, called automatically by the Game clock.
330364
* @method Phaser.Timer#update
@@ -341,55 +375,38 @@ Phaser.Timer.prototype = {
341375

342376
this._now = time;
343377

344-
this._len = this.events.length;
345-
346-
this._i = 0;
347-
348-
while (this._i < this._len)
349-
{
350-
if (this.events[this._i].pendingDelete)
351-
{
352-
this.events.splice(this._i, 1);
353-
this._len--;
354-
}
355-
356-
this._i++;
357-
}
358-
359-
this._len = this.events.length;
378+
// Clears events marked for deletion and resets _len and _i to 0.
379+
this.clearPendingEvents();
360380

361381
if (this.running && this._now >= this.nextTick && this._len > 0)
362382
{
363-
this._i = 0;
364-
365383
while (this._i < this._len && this.running)
366384
{
367385
if (this._now >= this.events[this._i].tick)
368386
{
369-
var diff = this._now - this.events[this._i].tick;
370-
var newTick = (this._now + this.events[this._i].delay) - diff;
387+
// (now + delay) - (time difference from last tick to now)
388+
this._newTick = (this._now + this.events[this._i].delay) - (this._now - this.events[this._i].tick);
371389

372-
if (newTick < 0)
390+
if (this._newTick < 0)
373391
{
374-
newTick = this._now + this.events[this._i].delay;
392+
this._newTick = this._now + this.events[this._i].delay;
375393
}
376394

377395
if (this.events[this._i].loop === true)
378396
{
379-
this.events[this._i].tick = newTick;
397+
this.events[this._i].tick = this._newTick;
380398
this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args);
381399
}
382400
else if (this.events[this._i].repeatCount > 0)
383401
{
384402
this.events[this._i].repeatCount--;
385-
this.events[this._i].tick = newTick;
403+
this.events[this._i].tick = this._newTick;
386404
this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args);
387405
}
388406
else
389407
{
390408
this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args);
391-
this.events.splice(this._i, 1);
392-
this._len--;
409+
this.events[this._i].pendingDelete = true;
393410
}
394411

395412
this._i++;

0 commit comments

Comments
 (0)