Skip to content

Commit 961e858

Browse files
committed
Working through making the Input system DOM responsive and not reliant on the game step
1 parent 9a2b8b9 commit 961e858

2 files changed

Lines changed: 140 additions & 46 deletions

File tree

src/input/InputManager.js

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ var InputManager = new Class({
246246
* @type {boolean}
247247
* @default false
248248
* @since 3.0.0
249+
this.ignoreEvents = -1;
249250
*/
250-
this.ignoreEvents = false;
251251

252252
/**
253253
* The time this Input Manager was last updated.
@@ -260,16 +260,6 @@ var InputManager = new Class({
260260
*/
261261
this.time = 0;
262262

263-
/**
264-
* Internal property that tracks frame event state.
265-
*
266-
* @name Phaser.Input.InputManager#_updatedThisFrame
267-
* @type {boolean}
268-
* @private
269-
* @since 3.16.0
270-
*/
271-
this._updatedThisFrame = false;
272-
273263
/**
274264
* A re-cycled point-like object to store hit test values in.
275265
*
@@ -331,7 +321,9 @@ var InputManager = new Class({
331321

332322
this.events.emit(Events.MANAGER_BOOT);
333323

334-
this.game.events.on(GameEvents.PRE_STEP, this.preStep, this);
324+
this.game.events.on(GameEvents.PRE_RENDER, this.preStep, this);
325+
326+
this.game.events.on(GameEvents.POST_RENDER, this.postRender, this);
335327

336328
this.game.events.once(GameEvents.DESTROY, this.destroy, this);
337329
},
@@ -371,7 +363,7 @@ var InputManager = new Class({
371363
},
372364

373365
/**
374-
* Internal update, called automatically by the Game Step.
366+
* Internal update, called automatically by the Game Step right at the start.
375367
*
376368
* @method Phaser.Input.InputManager#preStep
377369
* @private
@@ -383,16 +375,33 @@ var InputManager = new Class({
383375
{
384376
this.time = time;
385377

386-
this.ignoreEvents = false;
378+
this.events.emit(Events.MANAGER_UPDATE);
379+
380+
// this.ignoreEvents = false;
381+
},
382+
383+
/**
384+
* Internal update, called automatically by the Game Step right after everything has finished rendering.
385+
*
386+
* We do this because, in the life of a frame, rAF comes _after_ the input events. So, we need to clear down
387+
* the input settings, ready incase the new input events potentially change them prior to the next game step.
388+
*
389+
* https://medium.com/@paul_irish/requestanimationframe-scheduling-for-nerds-9c57f7438ef4
390+
*
391+
* @method Phaser.Input.InputManager#postRender
392+
* @private
393+
* @since 3.18.0
394+
*/
395+
postRender: function ()
396+
{
397+
// this.ignoreEvents = false;
387398

388399
var pointers = this.pointers;
389400

390401
for (var i = 0; i < this.pointersTotal; i++)
391402
{
392-
pointers[i].reset(time);
403+
pointers[i].reset(this.game.getTime());
393404
}
394-
395-
this.events.emit(Events.MANAGER_UPDATE);
396405
},
397406

398407
/**
@@ -704,9 +713,10 @@ var InputManager = new Class({
704713
{
705714
var scene = scenes[i];
706715

707-
if (scene.sys.input)
716+
if (scene.sys.input && scene.sys.input.update(time, delta) && this.globalTopOnly)
708717
{
709-
scene.sys.input.update(time, delta);
718+
// If the Scene returns true, it means it captured some input that no other Scene should get, so we bail out
719+
return;
710720
}
711721
}
712722
},
@@ -806,6 +816,8 @@ var InputManager = new Class({
806816
*/
807817
onMouseDown: function (event)
808818
{
819+
console.log(this.game.getFrame(), 'md', event.pageX, event.pageY);
820+
809821
this.mousePointer.down(event);
810822

811823
this.mousePointer.updateMotion();

src/input/InputPlugin.js

Lines changed: 109 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,16 @@ var InputPlugin = new Class({
356356
*/
357357
this._validTypes = [ 'onDown', 'onUp', 'onOver', 'onOut', 'onMove', 'onDragStart', 'onDrag', 'onDragEnd', 'onDragEnter', 'onDragLeave', 'onDragOver', 'onDrop' ];
358358

359+
/**
360+
* Internal property that tracks frame event state.
361+
*
362+
* @name Phaser.Input.InputPlugin#_updatedThisFrame
363+
* @type {boolean}
364+
* @private
365+
* @since 3.18.0
366+
*/
367+
this._updatedThisFrame = false;
368+
359369
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
360370
scene.sys.events.on(SceneEvents.START, this.start, this);
361371
},
@@ -525,10 +535,9 @@ var InputPlugin = new Class({
525535
{
526536
this.pluginEvents.emit(Events.UPDATE, time, delta);
527537

528-
/*
529-
if (this.pollRate > -1)
538+
if (this.pollRate > -1 && !this._updatedThisFrame)
530539
{
531-
this.update(time, delta);
540+
this.updatePoll(time, delta);
532541
}
533542
else
534543
{
@@ -539,7 +548,92 @@ var InputPlugin = new Class({
539548

540549
this.pluginEvents.emit(Events.UPDATE, time, delta);
541550
}
542-
*/
551+
552+
this._updatedThisFrame = false;
553+
},
554+
555+
updatePoll: function (time, delta)
556+
{
557+
console.log('poll');
558+
559+
if (!this.isActive())
560+
{
561+
return false;
562+
}
563+
564+
if (this.pollRate > 0)
565+
{
566+
this._pollTimer -= delta;
567+
568+
if (this._pollTimer < 0)
569+
{
570+
// Discard timer diff, we're ready to poll again
571+
this._pollTimer = this.pollRate;
572+
}
573+
else
574+
{
575+
// Not enough time has elapsed since the last poll, so abort now
576+
return;
577+
}
578+
}
579+
580+
// We got this far? Then we should poll for movement
581+
var manager = this.manager;
582+
var pointers = manager.pointers;
583+
var pointersTotal = manager.pointersTotal;
584+
var captured = false;
585+
586+
for (var i = 0; i < pointersTotal; i++)
587+
{
588+
var pointer = pointers[i];
589+
590+
// Always reset this array
591+
this._tempZones = [];
592+
593+
// _temp contains a hit tested and camera culled list of IO objects
594+
this._temp = this.hitTestPointer(pointer);
595+
596+
this.sortGameObjects(this._temp);
597+
this.sortGameObjects(this._tempZones);
598+
599+
if (this.topOnly)
600+
{
601+
// Only the top-most one counts now, so safely ignore the rest
602+
if (this._temp.length)
603+
{
604+
this._temp.splice(1);
605+
}
606+
607+
if (this._tempZones.length)
608+
{
609+
this._tempZones.splice(1);
610+
}
611+
}
612+
613+
var total = 0;
614+
615+
// TODO: Enable for touch - the method needs recoding to take ALL pointers at once
616+
// and process them all together, in the same batch, otherwise the justOut and stillOver
617+
// arrays will get corrupted in multi-touch enabled games. For now, we'll enable it for
618+
// single touch games (which is probably the majority anyway).
619+
if (pointersTotal < 3 || !pointer.wasTouch)
620+
{
621+
total += this.processOverOutEvents(pointer);
622+
}
623+
624+
if (pointer.justMoved)
625+
{
626+
total += this.processMoveEvents(pointer);
627+
}
628+
629+
if (total > 0 && manager.globalTopOnly)
630+
{
631+
// We interacted with an event in this Scene, so block any Scenes below us from doing the same this frame
632+
captured = true;
633+
}
634+
}
635+
636+
return captured;
543637
},
544638

545639
/**
@@ -553,37 +647,21 @@ var InputPlugin = new Class({
553647
*
554648
* @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now().
555649
* @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class.
650+
*
651+
* @return {boolean} `true` if this Scene has captured the input events from all other Scenes, otherwise `false`.
556652
*/
557653
update: function (time, delta)
558654
{
559655
if (!this.isActive())
560656
{
561-
return;
657+
return false;
562658
}
563659

564660
var manager = this.manager;
565661

566-
// this.pluginEvents.emit(Events.UPDATE, time, delta);
567-
568-
// Another Scene above this one has already consumed the input events, or we're in transition
569-
if (manager.globalTopOnly && manager.ignoreEvents)
570-
{
571-
return;
572-
}
573-
574-
if (this.pollRate > 0)
575-
{
576-
this._pollTimer -= delta;
577-
578-
if (this._pollTimer < 0)
579-
{
580-
// Discard timer diff
581-
this._pollTimer = this.pollRate;
582-
}
583-
}
584-
585-
var pointers = this.manager.pointers;
586-
var pointersTotal = this.manager.pointersTotal;
662+
var pointers = manager.pointers;
663+
var pointersTotal = manager.pointersTotal;
664+
var captured = false;
587665

588666
for (var i = 0; i < pointersTotal; i++)
589667
{
@@ -641,9 +719,13 @@ var InputPlugin = new Class({
641719
if (total > 0 && manager.globalTopOnly)
642720
{
643721
// We interacted with an event in this Scene, so block any Scenes below us from doing the same this frame
644-
manager.ignoreEvents = true;
722+
captured = true;
645723
}
646724
}
725+
726+
this._updatedThisFrame = true;
727+
728+
return captured;
647729
},
648730

649731
/**

0 commit comments

Comments
 (0)