diff --git a/packages/entity/traits/spawner.trait.js b/packages/entity/traits/spawner.trait.js index 92101aa..b35812e 100644 --- a/packages/entity/traits/spawner.trait.js +++ b/packages/entity/traits/spawner.trait.js @@ -31,12 +31,15 @@ export class Spawner extends decorate(Trait) { } destroy() { - this.children = []; + while (this.children.length > 0) { + this.removeChild(this.children.pop()); + } } constructor(entity, params, state) { super(entity, params, state); this.children = []; + this.childrenListeners = new Map(); this.spawnJSONs = this.params.spawns; } @@ -63,6 +66,16 @@ export class Spawner extends decorate(Trait) { return true; } + removeChild(child) { + const index = this.children.indexOf(child); + if (-1 !== index) { + this.children.splice(index, 1); + const listener = this.childrenListeners.get(child); + child.off('destroy', listener); + this.childrenListeners.delete(child); + } + } + listeners() { return { @@ -100,14 +113,13 @@ export class Spawner extends decorate(Trait) { // Add null to children to prevent race. const childIndex = this.children.length; this.children.push(null); - return Entity.loadOrInstance(mergedJSON).then((spawn) => { - this.children[childIndex] = spawn; - spawn.once('destroy', () => { - const index = this.children.indexOf(spawn); - this.children.splice(index, 1); - }) - list.addEntity(spawn); - return spawn; + return Entity.loadOrInstance(mergedJSON).then((child) => { + this.children[childIndex] = child; + const listener = this.removeChild.bind(this, child); + this.childrenListeners.set(child, listener); + child.once('destroy', listener); + list.addEntity(child); + return child; }); },