Skip to content

Commit

Permalink
added createSystem to engine
Browse files Browse the repository at this point in the history
theres now some lifecycle to the engine and systems.

engine.createSystem
will trigger a register of the system and the systems onCreate funktion

unregister now alsow flags systems for destruction
and on the nex tick triggers the systems onDestroy function

engine.tick handels engine.update and engine.cleanUp
  • Loading branch information
Yoieh committed Nov 28, 2021
1 parent af01f2c commit 2ff83b0
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 28 deletions.
4 changes: 0 additions & 4 deletions src/ecs/BaseSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ export abstract class BaseSystem {

public enabled = true;

constructor() {
Engine.instance.registerSystem(this);
}

public onCreate(deltaTime: number) {}

public onUpdate(deltaTime: number) {}
Expand Down
31 changes: 27 additions & 4 deletions src/engine/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,52 @@ export class Engine implements IUpdate {

public systems: BaseSystem[] = [];

public systemsToDestroy: BaseSystem[] = [];

public entityManager: EntityManager = EntityManager.instance;

public tick(deltaTime: number): void {
this._lastDeltaTime = deltaTime;

this.update(deltaTime);

this.cleanUp();
}

public update(deltaTime: number): void {
// eslint-disable-next-line no-restricted-syntax
for (const system of this.systems) {
if (system.enabled) {
system.onUpdate(deltaTime);
}
}
}

this._lastDeltaTime = deltaTime;
public cleanUp(): void {
// eslint-disable-next-line no-restricted-syntax
for (const system of this.systemsToDestroy) {
system.onDestroy(this._lastDeltaTime);
this.systems = this.systems.filter((s) => s !== system);
}

this.systemsToDestroy = [];
}

public createSystem(system: new (...args: any[]) => BaseSystem) {
const newSystem = new system();
newSystem.onCreate(this._lastDeltaTime);
this.registerSystem(newSystem);
return newSystem;
}

public registerSystem(system: BaseSystem): void {
system.onCreate(this._lastDeltaTime);
this.systems.push(system);
this.onSystemAdded.dispatch(system);
}

public unregisterSystem(system: BaseSystem): void {
this.systems = this.systems.filter((s) => s !== system);
this.systemsToDestroy.push(system);
this.onSystemRemoved.dispatch(system);
system.onDestroy(this._lastDeltaTime);
}
}

Expand Down
4 changes: 3 additions & 1 deletion tests/_test_classes/SimpelSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { Query } from '../../src/ecs/Query';
import { CValue } from './CValue';

export class SimpelSystem extends BaseSystem {
public q: Query;
public q!: Query;

public constructor() {
super();
}

public onCreate(delta: number): void {
this.q = new Query((entity: IEntity) => entity.has(CValue));
}

Expand Down
17 changes: 13 additions & 4 deletions tests/ecs/SimpelSystem.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ describe('>>> SimpelSystem', () => {

beforeEach(() => {
engine = Engine.instance;
});

afterEach(() => {
for (const system of engine.systems) {
engine.unregisterSystem(system);
}
Expand All @@ -22,29 +25,35 @@ describe('>>> SimpelSystem', () => {
for (const entity of engine.entityManager.entities) {
engine.entityManager.removeEntity(entity.id);
}

engine.tick(1);

jest.clearAllMocks();
});

it('should be able to create a system', () => {
const system = new SimpelSystem();
const system = engine.createSystem(SimpelSystem);
expect(system).toBeInstanceOf(SimpelSystem);
});

it('should have been registerd', () => {
const system = new SimpelSystem();
engine.createSystem(SimpelSystem);
expect(engine.systems.length).toBe(1);
});

it('should be abel to be unregisterd', () => {
const system = new SimpelSystem();
const system = engine.createSystem(SimpelSystem);
engine.unregisterSystem(system);
engine.tick(1);
expect(engine.systems.length).toBe(0);
});

it('should be able to update', () => {
const expectedValue = 10;
const initialValue = 0;

new SimpelSystem();
engine.createSystem(SimpelSystem);

const query = new Query((e: IEntity) => e.has(CValue));

const valueEntity = EntityManager.instance.createEntity();
Expand Down
60 changes: 45 additions & 15 deletions tests/engine/Engine.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('>>> Engine', () => {
const dt = now - lastUpdate;
lastUpdate = now;

engine.update(dt);
engine.tick(dt);
// render(dt);
};

Expand All @@ -35,25 +35,31 @@ describe('>>> Engine', () => {

beforeEach(() => {
engine = Engine.instance;

// window.requestAnimationFrame = jest.fn().mockImplementationOnce((cb) => cb()); // <-- ADD
});

afterEach(() => {
jest.clearAllMocks();

for (const system of engine.systems) {
engine.unregisterSystem(system);
}

window.requestAnimationFrame = jest.fn().mockImplementationOnce((cb) => cb()); // <-- ADD
loop(5);
});

it('should register a new system', () => {
const s1 = new S1();

it('should register a new system with out a engine tick', () => {
engine.createSystem(S1);
expect(engine.systems.length).toBe(1);
});

it('should update registerd systems', () => {
engine = Engine.instance;
engine.update(1);
const s1 = new S1();
const s2 = new S2();
const s3 = new S3();
const s1 = engine.createSystem(S1);
const s2 = engine.createSystem(S2);
const s3 = engine.createSystem(S3);

const spyOnUpdate1 = jest.spyOn(s1, 'onUpdate');
const spyOnUpdate2 = jest.spyOn(s2, 'onUpdate');
Expand All @@ -75,9 +81,9 @@ describe('>>> Engine', () => {

new SignalListener(engine.onSystemAdded, spy2);

const s1 = new S1();
const s2 = new S2();
const s3 = new S3();
engine.createSystem(S1);
engine.createSystem(S2);
engine.createSystem(S3);

expect(spy1).toHaveBeenCalledTimes(3);
expect(spy2).toHaveBeenCalledTimes(3);
Expand All @@ -93,15 +99,39 @@ describe('>>> Engine', () => {

new SignalListener(engine.onSystemRemoved, spy2);

const s1 = new S1();
const s2 = new S2();
const s3 = new S3();
const s1 = engine.createSystem(S1);
engine.createSystem(S2);
engine.createSystem(S3);

const systemsCount = engine.systems.length;

expect(systemsCount).toBe(3);

engine.unregisterSystem(s1);

loop(1);

expect(spy1).toHaveBeenCalledTimes(1);
expect(spy2).toHaveBeenCalledTimes(1);

expect(engine.systems.length).toBe(2);
expect(engine.systems.length).toBe(systemsCount - 1);
});

it('should create systems', () => {
engine = Engine.instance;

const spy1 = jest.spyOn(engine, 'createSystem');
const spy2 = jest.fn();

new SignalListener(engine.onSystemAdded, spy2);

engine.createSystem(S1);
engine.createSystem(S2);
engine.createSystem(S3);

expect(spy1).toHaveBeenCalledTimes(3);
expect(spy2).toHaveBeenCalledTimes(3);

expect(engine.systems.length).toBe(3);
});
});

0 comments on commit 2ff83b0

Please sign in to comment.