diff --git a/app/ecs/ecs.js b/app/ecs/ecs.js index 2f8eb28..948655c 100644 --- a/app/ecs/ecs.js +++ b/app/ecs/ecs.js @@ -23,7 +23,7 @@ export default class Ecs { deferredChanges = {} - destroying = new Set(); + $$destructionDependencies = new Map(); diff = {}; @@ -42,6 +42,20 @@ export default class Ecs { } } + addDestructionDependency(id, promise) { + if (!this.$$destructionDependencies.has(id)) { + this.$$destructionDependencies.set(id, new Set()) + } + const dependencies = this.$$destructionDependencies.get(id); + dependencies.add(promise); + promise.then(() => { + dependencies.delete(promise); + if (0 === dependencies.size) { + this.$$destructionDependencies.delete(id); + } + }); + } + async apply(patch) { const creating = []; const destroying = []; @@ -213,7 +227,10 @@ export default class Ecs { } destroy(entityId) { - this.destroying.add(entityId); + if (!this.$$destructionDependencies.has(entityId)) { + this.$$destructionDependencies.set(entityId, new Set()) + } + this.$$destructionDependencies.get(entityId).add(0); } destroyImmediately(entityId) { @@ -444,9 +461,17 @@ export default class Ecs { System.elapsed -= System.frequency; } } - if (this.destroying.size > 0) { - this.destroyMany(this.destroying); - this.destroying.clear(); + const destroying = new Set(); + for (const [id, dependencies] of this.$$destructionDependencies) { + if (1 === dependencies.size && dependencies.has(0)) { + destroying.add(id); + } + } + if (destroying.size > 0) { + this.destroyMany(destroying); + for (const id of destroying) { + this.$$destructionDependencies.delete(id); + } } }