vertecs
Version:
A typescript entity-component-system framework
171 lines (139 loc) • 4.54 kB
text/typescript
import type { ComponentClass } from "./Component";
import Component from "./Component";
import Entity from "./Entity";
import EcsManager from "./EcsManager";
type SystemConstructor<T extends Component[]> = new (
...args: any[]
) => System<T>;
/**
* A system loops over all entities and uses the components of the entities to perform logic.
*/
export default abstract class System<T extends Component[] = []> {
protected ecsManager?: EcsManager;
public readonly filter: ComponentClass<T[number]>[];
$dependencies: SystemConstructor<Component[]>[];
/**
* Create a new system with the given component group filter and the given tps
*/
protected constructor(
filter: ComponentClass<T[number]>[],
tps?: number,
dependencies?: SystemConstructor<Component[]>[]
) {
this.filter = filter;
this.
this.
this.
this.
this.$dependencies = dependencies ?? [];
this.
}
/**
* Called every frame, you should not call this method directly but instead use the {@see onLoop} method
*/
public loop(components: T[], entities: Entity[]): void {
this.
if (this.
return;
}
const startLoopTime = performance.now();
this.onLoop(components, entities, this.getDeltaTime());
this.
this.
}
public async start(ecsManager: EcsManager): Promise<void> {
this.ecsManager = ecsManager;
this.
await this.onStart();
}
public async stop(): Promise<void> {
this.
await this.onStop();
}
public sleep(milliseconds: number): void {
this.
}
/**
* Called when the system is added to an ecs manager
* @param ecsManager
*/
public onAddedToEcsManager(ecsManager: EcsManager): void {}
/**
* Called when the system is added to an ecs manager
*/
public async initialize(): Promise<void> {}
/**
* Called when the system is ready to start
*/
public async onStart(): Promise<void> {}
/**
* Called when the system is stopped
*/
public async onStop(): Promise<void> {}
/**
* Called whenever an entity becomes eligible to a system
* An entity becomes eligible when a component is added to an entity making it eligible to a group,
* or when a new system is added and an entity was already eligible to the new system's group
*/
public onEntityEligible(entity: Entity, components: T): void {}
/**
* Called when an entity becomes ineligible to a system, and before it is removed from the system
*/
public onEntityNoLongerEligible(entity: Entity, components: T): void {}
/**
* Called every frame
* @param components
* @param entities
* @param deltaTime The time since the last loop
*/
protected abstract onLoop(
components: T[],
entities: Entity[],
deltaTime: number
): void;
/**
* Return the time since the last update
* @private
*/
private getDeltaTime() {
return performance.now() - this.
}
/**
* Return true if enough time has passed since the last update, false otherwise
*/
public hasEnoughTimePassed(): boolean {
return (
this.
performance.now() - this.
);
}
public get dependencies(): SystemConstructor<Component[]>[] {
return this.$dependencies;
}
public get lastUpdateTime(): number {
return this.
}
public set lastUpdateTime(value: number) {
this.
}
public get loopTime(): number {
return this.
}
public get tps(): number {
return this.
}
public set tps(value: number) {
this.
}
public get hasStarted(): boolean {
return this.
}
public set hasStarted(value: boolean) {
this.
}
}