diff --git a/packages/ecs/src/ecs.js b/packages/ecs/src/ecs.js index fbe05d1..6eafc8e 100644 --- a/packages/ecs/src/ecs.js +++ b/packages/ecs/src/ecs.js @@ -59,6 +59,22 @@ export default class Ecs { return source; } + insertComponents(entity, components) { + this.ecs.insert(entity, components); + } + + insertManyComponents(components) { + this.ecs.insertMany(components); + } + + removeComponents(entity, components) { + this.ecs.remove(entity, components); + } + + removeManyComponents(entities) { + this.ecs.removeMany(entities); + } + } const wrappedSystem = new WrappedSystem(this.Components); wrappedSystem.reindex(Object.keys(this.$$entities)); @@ -192,6 +208,10 @@ export default class Ecs { } } + destroy(entity) { + this.destroyMany([entity]); + } + destroyAll() { this.destroyMany(Object.keys(this.$$entities).map((entity) => BigInt(entity))); } @@ -327,6 +347,27 @@ export default class Ecs { } } + remove(entity, components) { + this.removeMany([[entity, components]]); + } + + removeMany(entities) { + const removing = {}; + for (let i = 0; i < entities.length; i++) { + const [entity, components] = entities[i]; + for (let j = 0; j < components.length; j++) { + const component = components[j]; + if (!removing[component]) { + removing[component] = []; + } + removing[component].push(entity); + } + } + for (const component in removing) { + this.Components[component].destroyMany(removing[component]); + } + } + removeSystem(SystemLike) { const index = this.$$systems.findIndex((system) => SystemLike === system.source); if (-1 !== index) { diff --git a/packages/ecs/test/ecs.js b/packages/ecs/test/ecs.js index 5e37259..b46c6a5 100644 --- a/packages/ecs/test/ecs.js +++ b/packages/ecs/test/ecs.js @@ -48,6 +48,14 @@ it('can create entities with components', () => { .to.deep.equal(JSON.stringify({Empty: {}, Position: {x: 32, y: 420, z: 0}})); }); +it("can remove entities' components", () => { + const ecs = new Ecs({Empty, Position}); + const entity = ecs.create({Empty: {}, Position: {y: 420}}); + ecs.remove(entity, ['Position']); + expect(JSON.stringify(ecs.get(entity))) + .to.deep.equal(JSON.stringify({Empty: {}})); +}); + it('can get entities unsafely', () => { const ecs = new Ecs({Empty, Position}); const entity = ecs.create({Empty: {}, Position: {y: 420}}); @@ -142,6 +150,35 @@ it('can schedule entities to be deleted when ticking systems', () => { .to.be.undefined; }); +it('can add components to and remove components from entities when ticking systems', () => { + const Foo = {bar: 'uint8'}; + const ecs = new Ecs({Foo}); + class AddComponent extends System { + + tick() { + this.insertComponents(1n, {Foo: {}}); + } + + } + class RemoveComponent extends System { + + tick() { + this.removeComponents(1n, ['Foo']); + } + + } + ecs.addSystem(AddComponent); + ecs.createExact(1); + ecs.tick(1); + expect(ecs.get(1).Foo) + .to.not.be.undefined; + ecs.removeSystem(AddComponent); + ecs.addSystem(RemoveComponent); + ecs.tick(1); + expect(ecs.get(1).Foo) + .to.be.undefined; +}); + it('can encode and decode an ecs', () => { const ecs = new Ecs({Empty, Position}); const entity = ecs.create({Empty: {}, Position: {y: 420}});