import {Component, ComponentConstructor} from "./Component"; import { Entity } from "./Entity"; import { World } from "./World"; interface Attributes { priority?: number; [propName: string]: any; } export interface SystemQueries { [queryName: string]: { components: (ComponentConstructor | NotComponent)[], listen?: { added?: boolean, removed?: boolean, changed?: boolean | ComponentConstructor[], }, } } /** * A system that manipulates entities in the world. */ export abstract class System { /** * Defines what Components the System will query for. * This needs to be user defined. */ static queries: SystemQueries; static isSystem: true; constructor(world: World, attributes?: Attributes); /** * The results of the queries. * Should be used inside of execute. */ queries: { [queryName: string]: { results: EntityType[], added?: EntityType[], removed?: EntityType[], changed?: EntityType[], } } world: World; /** * Whether the system will execute during the world tick. */ enabled: boolean; /** * Execution priority (i.e: order) of the system. */ readonly priority: number; /** * Called when the system is added to the world. */ init(attributes?: Attributes): void /** * Resume execution of this system. */ play(): void; /** * Stop execution of this system. */ stop(): void; /** * This function is called for each run of world. * All of the `queries` defined on the class are available here. * @param delta * @param time */ abstract execute(delta: number, time: number): void; } export interface SystemConstructor { isSystem: true; queries: SystemQueries new (...args: any): T; } export interface NotComponent> { type: "not", Component: ComponentConstructor } /** * Use the Not class to negate a component query. */ export function Not>(Component: ComponentConstructor): NotComponent;