refactor: lifetimes
This commit is contained in:
parent
8be6c23711
commit
1a7d55f6d3
|
@ -22,6 +22,8 @@ export default class Ecs {
|
|||
|
||||
deferredChanges = {}
|
||||
|
||||
destroying = new Set();
|
||||
|
||||
diff = {};
|
||||
|
||||
Systems = {};
|
||||
|
@ -206,6 +208,10 @@ export default class Ecs {
|
|||
}
|
||||
|
||||
destroy(entityId) {
|
||||
this.destroying.add(entityId);
|
||||
}
|
||||
|
||||
destroyImmediately(entityId) {
|
||||
this.destroyMany([entityId]);
|
||||
}
|
||||
|
||||
|
@ -427,31 +433,24 @@ export default class Ecs {
|
|||
}
|
||||
|
||||
tick(elapsed) {
|
||||
const destroying = new Set();
|
||||
for (const systemName in this.Systems) {
|
||||
const System = this.Systems[systemName];
|
||||
if (System.active) {
|
||||
if (System.frequency) {
|
||||
System.elapsed += elapsed;
|
||||
if (System.elapsed < System.frequency) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while (!System.frequency || System.elapsed >= System.frequency) {
|
||||
System.tick(System.frequency ? System.elapsed : elapsed);
|
||||
for (let j = 0; j < System.destroying.length; j++) {
|
||||
destroying.add(System.destroying[j]);
|
||||
}
|
||||
System.tickDestruction();
|
||||
if (!System.frequency) {
|
||||
break;
|
||||
}
|
||||
System.elapsed -= System.frequency;
|
||||
}
|
||||
if (!System.active) {
|
||||
continue;
|
||||
}
|
||||
if (!System.frequency) {
|
||||
System.tick(elapsed);
|
||||
continue;
|
||||
}
|
||||
System.elapsed += elapsed;
|
||||
while (System.elapsed >= System.frequency) {
|
||||
System.tick(System.frequency);
|
||||
System.elapsed -= System.frequency;
|
||||
}
|
||||
}
|
||||
if (destroying.size > 0) {
|
||||
this.destroyMany(destroying.values());
|
||||
if (this.destroying.size > 0) {
|
||||
this.destroyMany(this.destroying);
|
||||
this.destroying.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ test('destroys entities', async () => {
|
|||
expect(ecs.get(entity))
|
||||
.to.be.undefined;
|
||||
expect(() => {
|
||||
ecs.destroy(entity);
|
||||
ecs.destroyImmediately(entity);
|
||||
})
|
||||
.to.throw();
|
||||
});
|
||||
|
@ -170,50 +170,14 @@ test('ticks systems', async () => {
|
|||
.to.deep.equal(JSON.stringify({y: 128 + 30}));
|
||||
});
|
||||
|
||||
test('creates many entities when ticking systems', () => {
|
||||
const ecs = new Ecs({
|
||||
Systems: {
|
||||
Spawn: class extends System {
|
||||
tick() {
|
||||
this.createManyEntities(Array.from({length: 5}).map(() => []));
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
ecs.system('Spawn').active = true;
|
||||
ecs.create();
|
||||
expect(ecs.get(5))
|
||||
.to.be.undefined;
|
||||
ecs.tick(1);
|
||||
expect(ecs.get(5))
|
||||
.to.not.be.undefined;
|
||||
});
|
||||
|
||||
test('creates entities when ticking systems', () => {
|
||||
const ecs = new Ecs({
|
||||
Systems: {
|
||||
Spawn: class extends System {
|
||||
tick() {
|
||||
this.createEntity();
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
ecs.system('Spawn').active = true;
|
||||
ecs.create();
|
||||
expect(ecs.get(2))
|
||||
.to.be.undefined;
|
||||
ecs.tick(1);
|
||||
expect(ecs.get(2))
|
||||
.to.not.be.undefined;
|
||||
});
|
||||
|
||||
test('schedules entities to be deleted when ticking systems', () => {
|
||||
const ecs = new Ecs({
|
||||
Systems: {
|
||||
Despawn: class extends System {
|
||||
tick() {
|
||||
this.destroyEntity(1);
|
||||
this.ecs.destroy(1);
|
||||
expect(ecs.get(1))
|
||||
.to.not.be.undefined;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -225,50 +189,6 @@ test('schedules entities to be deleted when ticking systems', () => {
|
|||
.to.be.undefined;
|
||||
});
|
||||
|
||||
test('adds components to and remove components from entities when ticking systems', async () => {
|
||||
let promise;
|
||||
const ecs = new Ecs({
|
||||
Components: {Foo: wrapProperties('Foo', {bar: {type: 'uint8'}})},
|
||||
Systems: {
|
||||
AddComponent: class extends System {
|
||||
static queries() {
|
||||
return {
|
||||
default: ['Foo'],
|
||||
};
|
||||
}
|
||||
tick() {
|
||||
promise = this.insertComponents(1, {Foo: {}});
|
||||
}
|
||||
},
|
||||
RemoveComponent: class extends System {
|
||||
static queries() {
|
||||
return {
|
||||
default: ['Foo'],
|
||||
};
|
||||
}
|
||||
tick() {
|
||||
this.removeComponents(1, ['Foo']);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
ecs.system('AddComponent').active = true;
|
||||
ecs.create();
|
||||
ecs.tick(1);
|
||||
await promise;
|
||||
expect(Array.from(ecs.system('AddComponent').select('default')).length)
|
||||
.to.equal(1);
|
||||
expect(ecs.get(1).Foo)
|
||||
.to.not.be.undefined;
|
||||
ecs.system('AddComponent').active = false;
|
||||
ecs.system('RemoveComponent').active = true;
|
||||
ecs.tick(1);
|
||||
expect(Array.from(ecs.system('RemoveComponent').select('default')).length)
|
||||
.to.equal(0);
|
||||
expect(ecs.get(1).Foo)
|
||||
.to.be.undefined;
|
||||
});
|
||||
|
||||
test('generates diffs for entity creation', async () => {
|
||||
const ecs = new Ecs();
|
||||
let entity;
|
||||
|
@ -347,7 +267,7 @@ test('generates diffs for deletions', async () => {
|
|||
let entity;
|
||||
entity = await ecs.create();
|
||||
ecs.setClean();
|
||||
ecs.destroy(entity);
|
||||
ecs.destroyImmediately(entity);
|
||||
expect(ecs.diff)
|
||||
.to.deep.equal({[entity]: false});
|
||||
});
|
||||
|
|
|
@ -6,8 +6,6 @@ export default class System {
|
|||
|
||||
active = false;
|
||||
|
||||
destroying = [];
|
||||
|
||||
ecs;
|
||||
|
||||
elapsed = 0;
|
||||
|
@ -25,38 +23,12 @@ export default class System {
|
|||
this.reindex(ecs.entities);
|
||||
}
|
||||
|
||||
createEntity(components) {
|
||||
return this.ecs.create(components);
|
||||
}
|
||||
|
||||
createManyEntities(componentsList) {
|
||||
return this.ecs.createMany(componentsList);
|
||||
}
|
||||
|
||||
deindex(entityIds) {
|
||||
for (const i in this.queries) {
|
||||
this.queries[i].deindex(entityIds);
|
||||
}
|
||||
}
|
||||
|
||||
destroyEntity(entityId) {
|
||||
this.destroyManyEntities([entityId]);
|
||||
}
|
||||
|
||||
destroyManyEntities(entityIds) {
|
||||
for (let i = 0; i < entityIds.length; i++) {
|
||||
this.destroying.push(entityIds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
async insertComponents(entityId, components) {
|
||||
return this.ecs.insert(entityId, components);
|
||||
}
|
||||
|
||||
async insertManyComponents(components) {
|
||||
return this.ecs.insertMany(components);
|
||||
}
|
||||
|
||||
static get priority() {
|
||||
return {
|
||||
phase: 'normal',
|
||||
|
@ -73,14 +45,6 @@ export default class System {
|
|||
}
|
||||
}
|
||||
|
||||
removeComponents(entityId, components) {
|
||||
this.ecs.remove(entityId, components);
|
||||
}
|
||||
|
||||
removeManyComponents(entityIds) {
|
||||
this.ecs.removeMany(entityIds);
|
||||
}
|
||||
|
||||
select(query) {
|
||||
return this.queries[query].select();
|
||||
}
|
||||
|
@ -117,13 +81,6 @@ export default class System {
|
|||
);
|
||||
}
|
||||
|
||||
tickDestruction() {
|
||||
if (this.destroying.length > 0) {
|
||||
this.deindex(this.destroying);
|
||||
}
|
||||
this.destroying = [];
|
||||
}
|
||||
|
||||
tick() {}
|
||||
|
||||
}
|
||||
|
|
|
@ -322,6 +322,7 @@ export default class Engine {
|
|||
stop() {
|
||||
clearTimeout(this.handle);
|
||||
this.handle = undefined;
|
||||
this.tick(0);
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
|
|
|
@ -45,8 +45,8 @@ const engine = new Engine(WorkerServer);
|
|||
|
||||
onmessage = async (event) => {
|
||||
if (0 === event.data) {
|
||||
engine.stop();
|
||||
await engine.disconnectPlayer(0);
|
||||
engine.stop();
|
||||
await engine.saveEcses();
|
||||
postMessage(0);
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue
Block a user