Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"pointerout" interaction event triggers after disableInteractive() #5828

Closed
thewaver opened this issue Sep 8, 2021 · 3 comments · Fixed by #5839
Closed

"pointerout" interaction event triggers after disableInteractive() #5828

thewaver opened this issue Sep 8, 2021 · 3 comments · Fixed by #5839

Comments

@thewaver
Copy link

thewaver commented Sep 8, 2021

Version

  • Phaser Version:
    3.55.2
  • Operating system:
    Win 10
  • Browser:
    Opera 78.0.4093.184 (only tested here)

Description

I have a polygon GameObject with setInteractive() and a few on() events.
Events trigger fine, except that the "pointerout" event still triggers once after I call disableInteractive().
This is probably easier to understand by looking at the code.
If I am missing something obvious then I am truly sorry.
Problem goes away if I call removeAllListeners() after disableInteractive().

Example Test Code

  const polyPoints = [cell.topLeft, cell.topRight, cell.bottomRight, cell.bottomLeft];
  const poly = this.scene.add
    .polygon(0, 0, polyPoints)
    .setOrigin(0)
    .setInteractive(new Phaser.Geom.Polygon(polyPoints), Phaser.Geom.Polygon.Contains)
    .disableInteractive()
    .setStrokeStyle(
      boardStrokeConfigs.DEFAULT.width,
      boardStrokeConfigs.DEFAULT.color,
      boardStrokeConfigs.DEFAULT.alpha,
    ).on("pointerover", () => {
      this.applyStrokeConfigToCellPoly(
        ...getCellRanks(c),
        boardStrokeConfigs.OVER_TARGET,
        true,
      );
    })
    .on("pointerout", () => {
// still triggers once after call to disableCellInteraction()
// doesn't matter how long I wait before I move the mouse
      this.applyStrokeConfigToCellPoly(
        ...getCellRanks(c),
        boardStrokeConfigs.VALID_TARGET,
        true,
      );
    });
  disableCellInteraction = () => {
    this.forEachCell((c) => {
      this.cellPolys[c.row][c.col].disableInteractive();
    });
  };

  enableCellInteraction = (onclick: (cell: BoardCell) => void) => {
    this.disableCellInteraction();
    this._activePawnAction?.getValidTargetCells().forEach((c) => {
      this.cellPolys[c.row][c.col]
        .setInteractive()
        .on("pointerup", () => onclick(c));
    });
  };
@natureofcode
Copy link
Contributor

natureofcode commented Sep 15, 2021

Reproducible even with such a simple example:
CodeSandbox

This happens because disableInteractive() method sets input.enabled property of the GameObject to false, but internal processOverOutEvents() method of the InputPlugin class simply checks for existence of input property on the GameObject. This line

Although a GameObject with input.enabled property set to false is not in the currentlyOver array at all, it is still in the previouslyOver array, which makes it an ideal candidate for the "pointerout" event. This loop

@natureofcode
Copy link
Contributor

This issue also applies to at least POINTER_OUT, DRAG_END, DRAG_ENTER and DRAG_LEAVE events. I've updated CodeSandbox to reflect these events.

photonstorm added a commit that referenced this issue Dec 1, 2021
Fix #5828, improve GameObject#disableInteractive() and InputPlugin#disable()
@photonstorm
Copy link
Collaborator

Thank you for submitting this issue. We have fixed this and the fix has been pushed to the master branch. It will be part of the next release. If you get time to build and test it for yourself we would appreciate that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants