refactor: safety first
This commit is contained in:
parent
5ff4eb2991
commit
091e19c7de
|
@ -44,13 +44,13 @@ export default class Ecs {
|
|||
|
||||
addDestructionDependency(id, promise) {
|
||||
if (!this.$$destructionDependencies.has(id)) {
|
||||
this.$$destructionDependencies.set(id, new Set())
|
||||
this.$$destructionDependencies.set(id, {promises: new Set()})
|
||||
}
|
||||
const dependencies = this.$$destructionDependencies.get(id);
|
||||
dependencies.add(promise);
|
||||
const {promises} = this.$$destructionDependencies.get(id);
|
||||
promises.add(promise);
|
||||
promise.then(() => {
|
||||
dependencies.delete(promise);
|
||||
if (0 === dependencies.size) {
|
||||
promises.delete(promise);
|
||||
if (!this.$$destructionDependencies.get(id)?.resolvers) {
|
||||
this.$$destructionDependencies.delete(id);
|
||||
}
|
||||
});
|
||||
|
@ -228,13 +228,13 @@ export default class Ecs {
|
|||
|
||||
destroy(entityId) {
|
||||
if (!this.$$destructionDependencies.has(entityId)) {
|
||||
this.$$destructionDependencies.set(entityId, new Set())
|
||||
this.$$destructionDependencies.set(entityId, {promises: new Set()});
|
||||
}
|
||||
this.$$destructionDependencies.get(entityId).add(0);
|
||||
}
|
||||
|
||||
destroyImmediately(entityId) {
|
||||
this.destroyMany([entityId]);
|
||||
const dependencies = this.$$destructionDependencies.get(entityId);
|
||||
if (!dependencies.resolvers) {
|
||||
dependencies.resolvers = withResolvers();
|
||||
}
|
||||
return dependencies.resolvers.promise;
|
||||
}
|
||||
|
||||
destroyAll() {
|
||||
|
@ -462,15 +462,16 @@ export default class Ecs {
|
|||
}
|
||||
}
|
||||
const destroying = new Set();
|
||||
for (const [id, dependencies] of this.$$destructionDependencies) {
|
||||
if (1 === dependencies.size && dependencies.has(0)) {
|
||||
destroying.add(id);
|
||||
for (const [entityId, {promises, resolvers}] of this.$$destructionDependencies) {
|
||||
if (0 === promises.size && resolvers) {
|
||||
destroying.add(entityId);
|
||||
}
|
||||
}
|
||||
if (destroying.size > 0) {
|
||||
this.destroyMany(destroying);
|
||||
for (const id of destroying) {
|
||||
this.$$destructionDependencies.delete(id);
|
||||
for (const entityId of destroying) {
|
||||
this.$$destructionDependencies.get(entityId).resolvers.resolve();
|
||||
this.$$destructionDependencies.delete(entityId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ test('destroys entities', async () => {
|
|||
expect(ecs.get(entity))
|
||||
.to.be.undefined;
|
||||
expect(() => {
|
||||
ecs.destroyImmediately(entity);
|
||||
ecs.destroyMany([entity]);
|
||||
})
|
||||
.to.throw();
|
||||
});
|
||||
|
@ -275,7 +275,8 @@ test('generates diffs for deletions', async () => {
|
|||
let entity;
|
||||
entity = await ecs.create();
|
||||
ecs.setClean();
|
||||
ecs.destroyImmediately(entity);
|
||||
ecs.destroy(entity);
|
||||
ecs.tick(0);
|
||||
expect(ecs.diff)
|
||||
.to.deep.equal({[entity]: false});
|
||||
});
|
||||
|
|
|
@ -89,15 +89,18 @@ export default class Engine {
|
|||
Ecs: {path},
|
||||
...updates,
|
||||
};
|
||||
// remove from old ECS
|
||||
this.destroyImmediately(entity.id);
|
||||
const promises = [];
|
||||
// load if necessary
|
||||
if (!engine.ecses[path]) {
|
||||
await engine.loadEcs(path);
|
||||
promises.push(engine.loadEcs(path));
|
||||
}
|
||||
// recreate the entity in the new ECS and again associate it with the connection
|
||||
connectedPlayer.entity = engine.ecses[path].get(await engine.ecses[path].create(dumped));
|
||||
connectedPlayer.entity.Player.id = id
|
||||
// remove from old ECS
|
||||
promises.push(this.destroy(entity.id));
|
||||
Promise.all(promises).then(async () => {
|
||||
// recreate the entity in the new ECS and again associate it with the connection
|
||||
connectedPlayer.entity = engine.ecses[path].get(await engine.ecses[path].create(dumped));
|
||||
connectedPlayer.entity.Player.id = id
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -255,12 +258,15 @@ export default class Engine {
|
|||
if (!connectedPlayer) {
|
||||
return;
|
||||
}
|
||||
const {entity, id} = connectedPlayer;
|
||||
const ecs = this.ecses[entity.Ecs.path];
|
||||
await this.savePlayer(id, entity);
|
||||
ecs.destroyImmediately(entity.id);
|
||||
this.connectedPlayers.delete(connection);
|
||||
this.incomingActions.delete(connection);
|
||||
const {entity, id} = connectedPlayer;
|
||||
const json = entity.toJSON();
|
||||
const ecs = this.ecses[entity.Ecs.path];
|
||||
return Promise.all([
|
||||
ecs.destroy(entity.id),
|
||||
this.savePlayer(id, json),
|
||||
]);
|
||||
}
|
||||
|
||||
async load() {
|
||||
|
|
|
@ -67,8 +67,8 @@ if (import.meta.hot) {
|
|||
const before = withResolvers();
|
||||
const promises = [before.promise];
|
||||
import.meta.hot.on('vite:beforeUpdate', async () => {
|
||||
engine.stop();
|
||||
await engine.disconnectPlayer(0);
|
||||
engine.stop();
|
||||
await engine.saveEcses();
|
||||
before.resolve();
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user