From a0cc7c8bd9bdf66792bdc4a458b1235e82784e97 Mon Sep 17 00:00:00 2001 From: Eric Hebert Date: Mon, 12 Apr 2021 01:54:12 -0400 Subject: [PATCH] Inject world into systems automatically --- src/system_storage.js | 14 ++++---- src/world.js | 2 +- test/world.test.js | 80 ++++++++++++++++++++++++------------------- 3 files changed, 51 insertions(+), 45 deletions(-) diff --git a/src/system_storage.js b/src/system_storage.js index 7478dbd..8057eb9 100644 --- a/src/system_storage.js +++ b/src/system_storage.js @@ -2,9 +2,10 @@ import { invoke } from './utilities.js' /** @ignore */ export class SystemStorage { - constructor() { + constructor(world) { + this.world = world this.systems = [] - this.context = undefined + this.context = { world } } register(systemClass, ...args) { @@ -36,7 +37,7 @@ export class SystemStorage { // Update existing systems' context setContext(data) { - this.context = data + this.context = { ...data, world: this.world } for (const system of this.systems) { this._injectContext(system) } @@ -44,11 +45,8 @@ export class SystemStorage { // Injects context into a system based on current context state _injectContext(system) { - if (this.context) { - // Inject as keys of context - for (const key in this.context) { - system[key] = this.context[key] - } + for (const key in this.context) { + system[key] = this.context[key] } } } diff --git a/src/world.js b/src/world.js index 95bc14b..a9e0b99 100644 --- a/src/world.js +++ b/src/world.js @@ -23,7 +23,7 @@ export class World { */ constructor(options) { /** @ignore */ - this.systems = new SystemStorage() + this.systems = new SystemStorage(this) /** @ignore */ this.entities = new EntityStorage(this) diff --git a/test/world.test.js b/test/world.test.js index d244b8f..50b7ba8 100644 --- a/test/world.test.js +++ b/test/world.test.js @@ -23,7 +23,7 @@ test('world: create a world with options', () => { expect(world1).toBeInstanceOf(World) expect(world1.systems.systems).toHaveLength(0) expect(getSize(world1.entities.componentClasses)).toBe(0) - expect(getSize(world1.systems.context)).toBe(0) + expect(getSize(world1.systems.context)).toBe(1) const world2 = new World({ components: {}, systems: [], @@ -32,7 +32,7 @@ test('world: create a world with options', () => { expect(world2).toBeInstanceOf(World) expect(world2.systems.systems).toHaveLength(0) expect(getSize(world2.entities.componentClasses)).toBe(0) - expect(getSize(world2.systems.context)).toBe(0) + expect(getSize(world2.systems.context)).toBe(1) const world3 = new World({ components: { position, velocity }, systems: [input, physics, render], @@ -41,7 +41,8 @@ test('world: create a world with options', () => { expect(world3).toBeInstanceOf(World) expect(world3.systems.systems).toHaveLength(3) expect(getSize(world3.entities.componentClasses)).toBe(2) - expect(getSize(world3.systems.context)).toBe(1) + expect(getSize(world3.systems.context)).toBe(2) + expect(Object.keys(world3.systems.context)).toEqual(['state', 'world']) }) test('component: define a component', () => { @@ -438,17 +439,21 @@ test('system: system iteration', () => { run(dt, total) { expect(dt > 0).toBeTruthy() expect(total > 0).toBeTruthy() - world.each('position', 'velocity', ({ position, velocity }, ent) => { - expect(position).toBeTruthy() - expect(velocity).toBeTruthy() - position.x += velocity.x - position.y += velocity.y - expect(ent).toBeTruthy() - expect(ent.has('position')).toBeTruthy() - expect(ent.has('velocity')).toBeTruthy() - expect(dt > 0).toBeTruthy() - expect(total > 0).toBeTruthy() - }) + this.world.each( + 'position', + 'velocity', + ({ position, velocity }, ent) => { + expect(position).toBeTruthy() + expect(velocity).toBeTruthy() + position.x += velocity.x + position.y += velocity.y + expect(ent).toBeTruthy() + expect(ent.has('position')).toBeTruthy() + expect(ent.has('velocity')).toBeTruthy() + expect(dt > 0).toBeTruthy() + expect(total > 0).toBeTruthy() + } + ) } } ) @@ -507,7 +512,7 @@ test('system: system methods', () => { run() { ++methodsCalled expect(this.val === 10).toBeTruthy() - world.each('position', ({ position }) => { + this.world.each('position', ({ position }) => { position.x = 1 ++methodsCalled expect(this.val === 10).toBeTruthy() @@ -548,27 +553,30 @@ test('system: system edge cases', () => { world.system( class { run() { - world.each(['position', 'velocity'], ({ position, velocity }, ent) => { - ++count - if (count == 1) { - testEnt1.remove('position', 'velocity') - testEnt2.remove('position') - testEnt0.remove('velocity') - return + this.world.each( + ['position', 'velocity'], + ({ position, velocity }, ent) => { + ++count + if (count == 1) { + testEnt1.remove('position', 'velocity') + testEnt2.remove('position') + testEnt0.remove('velocity') + return + } + expect(position).toBeTruthy() + expect(velocity).toBeTruthy() + position.x += velocity.x + position.y += velocity.y + expect(ent).toBeTruthy() + expect(ent.has('position')).toBeTruthy() + expect(ent.has('velocity')).toBeTruthy() + + // Make sure the test entities do not show up here + expect(ent.id !== testEnt0.id).toBeTruthy() + expect(ent.id !== testEnt1.id).toBeTruthy() + expect(ent.id !== testEnt2.id).toBeTruthy() } - expect(position).toBeTruthy() - expect(velocity).toBeTruthy() - position.x += velocity.x - position.y += velocity.y - expect(ent).toBeTruthy() - expect(ent.has('position')).toBeTruthy() - expect(ent.has('velocity')).toBeTruthy() - - // Make sure the test entities do not show up here - expect(ent.id !== testEnt0.id).toBeTruthy() - expect(ent.id !== testEnt1.id).toBeTruthy() - expect(ent.id !== testEnt2.id).toBeTruthy() - }) + ) } } ) @@ -953,7 +961,7 @@ test('system: test indexing with each()', () => { world.system( class { run() { - world.each(() => { + this.world.each(() => { ++count }) }