Skip to content

Commit

Permalink
[#979] Prevent removal of actors that are killed and readded during t…
Browse files Browse the repository at this point in the history
…he same frame (#1016)

Closes #979

## Changes:

- Add check to ensure Actor is still killed before removing it from drawing tree.
  • Loading branch information
alanag13 authored and eonarheim committed Aug 4, 2018
1 parent fa3142f commit 175e725
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 6 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Added

- Add `Scene.isActorInDrawTree` method to determine if an actor is in the scene's draw tree.

### Changed

### Deprecated

### Fixed

- Fixed missing `exitviewport/enterviewport` events on Actors.on/once/off signatures. ([#978](https://github.com/excaliburjs/Excalibur/issues/978))
- Fixed missing `exitviewport/enterviewport` events on Actors.on/once/off signatures ([#978](https://github.com/excaliburjs/Excalibur/issues/978))
- Fix issue where Actors would not be properly added to a scene if they were removed from that scene during the same frame ([#979](https://github.com/excaliburjs/Excalibur/issues/979))

<!--------------------------------- DO NOT EDIT BELOW THIS LINE --------------------------------->

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 14 additions & 4 deletions src/engine/Scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,13 @@ export class Scene extends Class implements ICanInitialize, ICanActivate, ICanDe
// Remove actors from scene graph after being killed
var actorIndex: number;
for (let killed of killQueue) {
actorIndex = collection.indexOf(killed);
if (actorIndex > -1) {
this._sortedDrawingTree.removeByComparable(killed);
collection.splice(actorIndex, 1);
//don't remove actors that were readded during the same frame they were killed
if (killed.isKilled()) {
actorIndex = collection.indexOf(killed);
if (actorIndex > -1) {
this._sortedDrawingTree.removeByComparable(killed);
collection.splice(actorIndex, 1);
}
}
}
killQueue.length = 0;
Expand Down Expand Up @@ -737,6 +740,13 @@ export class Scene extends Class implements ICanInitialize, ICanActivate, ICanDe
this._sortedDrawingTree.add(actor);
}

/**
* Checks if an actor is in this scene's sorted draw tree
*/
public isActorInDrawTree(actor: Actor): boolean {
return this._sortedDrawingTree.find(actor);
}

public isCurrentScene(): boolean {
if (this.engine) {
return this.engine.currentScene === this;
Expand Down
13 changes: 13 additions & 0 deletions src/spec/SceneSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,19 @@ describe('A scene', () => {
expect(scene.actors.length).toBe(1);
});

it('will still be in the draw tree if it is killed and then added in the same frame', () => {
var actor = new ex.Actor();
scene.add(actor);
actor.kill();
scene.add(actor);

scene.update(engine, 10); //call _processKillQueue

expect(scene.actors.indexOf(actor)).toBe(0);
expect(scene.actors.length).toBe(1);
expect(scene.isActorInDrawTree(actor)).toBe(true);
});

it('will update Actors that were added in a Timer callback', () => {
var updated = false;
var initialized = false;
Expand Down

0 comments on commit 175e725

Please sign in to comment.