UNPKG

@valeera/x

Version:

ECS framework written in TS for web application.

107 lines (86 loc) 2.6 kB
import { Entity } from "./Entity"; import { IdGeneratorInstance } from "./Global"; import { World } from "./World"; export type TQueryRule = (entity: Entity) => boolean; export class System { public readonly id: number = IdGeneratorInstance.next(); public readonly isSystem = true; public name = ""; public loopTimes = 0; public entitySet: WeakMap<World, Set<Entity>> = new WeakMap(); public usedBy: World[] = []; public autoUpdate = true; public handler: (entity: Entity, time: number, delta: number, world: World) => any; protected currentDelta: number = 0; protected currentTime: number = 0; protected currentWorld: World | null = null; protected rule: TQueryRule; private _disabled = false; private _priority = 0; public get disabled(): boolean { return this._disabled; } public set disabled(value: boolean) { this._disabled = value; } public get priority(): number { return this._priority; } public set priority(v: number) { this._priority = v; for (let i = 0, len = this.usedBy.length; i < len; i++) { this.usedBy[i].updateOrder(); } } public constructor( fitRule: TQueryRule, handler?: (entity: Entity, time: number, delta: number, world: World) => any, name?: string, ) { this.name = name ?? this.constructor.name; this.disabled = false; this.handler = handler ?? (() => {}); this.rule = fitRule; } public checkEntityManager(world: World): this { let weakMapTmp = this.entitySet.get(world); if (!weakMapTmp) { weakMapTmp = new Set(); this.entitySet.set(world, weakMapTmp); } else { weakMapTmp.clear(); } world.entities.forEach((item: Entity) => { if (this.query(item)) { weakMapTmp.add(item); } else { weakMapTmp.delete(item); } }); return this; } public query(entity: Entity): boolean { return this.rule(entity); } public run(world: World, time: number, delta: number): this { if (this.disabled) { return this; } this.entitySet.get(world)?.forEach((item: Entity) => { // 此处不应该校验disabled。这个交给各自系统自行判断 this.handle(item, time, delta, world); }); return this; } public destroy(): this { for (let i = this.usedBy.length - 1; i > -1; i--) { this.usedBy[i].remove(this); } return this; } public handle(entity: Entity, time: number, delta: number, world: World): this { this.handler(entity, time, delta, world); return this; } } export type SystemConstructor = new (...a: any[]) => System;