export type EntityManagerState = number;
export namespace EntityManagerState {
    let Initial: number;
    let Starting: number;
    let Running: number;
    let Failed: number;
    let Stopping: number;
    let Stopped: number;
}
/**
 * Brings together {@link System}s and an {@link EntityComponentDataset}
 * Main entry point into the simulation process.
 *
 * @example
 *      const em = new EntityManager()
 *
 *      em.addSystem(new MySystem())
 *      em.addSystem(new MyOtherSystem())
 *
 *      em.attachDataset(new EntityComponentDataset())
 *
 *      em.startup();
 *
 *      // ..
 *
 *      em.simulate(0.016); // advance simulation forward by 16ms
 *
 *      // ..
 *
 *      em.shutdown();
 *
 *      // ..
 *
 *      em.detachDataset();
 *
 * @author Alex Goldring
 * @copyright Company Named Limited (c) 2026
 */
export class EntityManager {
    /**
     * Registered systems
     * @readonly
     * @type {System[]}
     */
    readonly systems: System<any, any, any, any, any>[];
    /**
     * Current order of execution.
     * Note: this can be smaller that the number of registered systems, as systems are only added to the execution order once their startup finishes
     * @readonly
     * @private
     * @type {System[]}
     */
    private readonly systemsExecutionOrder;
    /**
     * Observers associated with individual systems, responsible for {@link System.link}/{@link System.unlink}
     * @readonly
     * @private
     * @type {Map<System,EntityObserver>}
     */
    private readonly systemObservers;
    /**
     * @readonly
     */
    readonly on: {
        systemStarted: Signal<any, any, any, any, any, any, any, any>;
        systemStopped: Signal<any, any, any, any, any, any, any, any>;
        /**
         * @type {Signal<System>}
         */
        systemAdded: Signal<System<any, any, any, any, any>>;
        systemRemoved: Signal<any, any, any, any, any, any, any, any>;
    };
    /**
     *
     * @type {EntityManagerState}
     */
    state: EntityManagerState;
    /**
     * Value used to execute {@link System.fixedUpdate}
     * In seconds.
     * The default is ~60 Hz, which should be sufficient for most use-cases.
     * Setting this value higher will reduce the total number of steps per second, and typically lead to better performance.
     * Setting this value lower will increase number of steps per second, increasing simulation accuracy at the cost of performance.
     * Make sure you understand the implications when modifying this.
     * A good safe range is [0.001 - 0.2]
     * @type {number}
     */
    fixedUpdateStepSize: number;
    /**
     * Wall-clock budget, in milliseconds, for the whole fixed-step catch-up loop
     * within a single {@link simulate} call. Once a cycle's accumulated
     * fixedUpdate work exceeds this, the loop stops early and the unconsumed time
     * stays in the accumulator to be caught up later — this avoids a runaway
     * freeze when {@link System.fixedUpdate} work outpaces its time step. (Now a
     * per-cycle budget across all systems' lock-step steps; previously per-system.)
     * @type {number}
     */
    fixedUpdatePerSystemExecutionTimeLimit: number;
    /**
     * Monotonic **simulation tick id** — the count of fixed steps the simulation
     * has executed. Advances once per {@link fixedUpdateStepSize} step inside
     * {@link simulate}. This is the hub-owned identity that producers (physics,
     * network) stamp per-tick state with, and that render-rate consumers
     * (interpolation) read as "the latest completed step". Pairs with
     * {@link getFixedStepAlpha}.
     * @type {number}
     */
    fixedStepTick: number;
    /**
     * Canonical fixed-step time accumulator backing {@link fixedStepTick} and
     * {@link getFixedStepAlpha}. Holds the sub-step remainder in `[0, step)`.
     * @private
     * @type {number}
     */
    private __fixedStepAccumulator;
    /**
     * Currently attached dataset.
     * Do not modify directly, instead use {@link attachDataset} and {@link detachDataset} respectively.
     * @type {EntityComponentDataset}
     */
    dataset: EntityComponentDataset;
    /**
     * Whenever a system is added or removed, optimal execution plan changes, this flag tells us to rebuild the current plan
     * see {@link #systemsExecutionOrder}
     * @type {boolean}
     * @private
     */
    private __execution_order_needs_update;
    /**
     * Rebuild execution order
     * @private
     */
    private updateExecutionOrder;
    /**
     * Get list of all components referenced by active systems
     * @returns {Class[]}
     */
    getComponentTypeMap(): Class[];
    /**
     * Link a given dataset, will cause associated systems to work with the new dataset as well
     * @param {EntityComponentDataset} dataset
     * @throws {Error} if another dataset is attached
     * @throws {Error} if dataset is incompatible with current system set
     */
    attachDataset(dataset: EntityComponentDataset): void;
    /**
     * Dissociate currently bound dataset, will cause attached systems to unlink entities held in the dataset.
     * Idempotent, if no dataset is attached - nothing will happen.
     */
    detachDataset(): void;
    /**
     * @template T
     * @param {Class<T>} systemClass
     * @returns {boolean}
     */
    hasSystem<T>(systemClass: Class<T>): boolean;
    /**
     * @template T
     * @param {Class<T>} systemClass
     * @returns {T|null}
     */
    getSystem<T_1>(systemClass: Class<T_1>): T_1;
    /**
     * @deprecated use {@link EntityComponentDataset.getComponentClassByName} instead
     * @template T
     * @param {string} className
     * @returns {null|Class<T>}
     */
    getComponentClassByName<T_2>(className: string): null | Class<T_2>;
    /**
     * Advance simulation forward by a specified amount of time
     * @param {number} time_delta_seconds in seconds
     */
    simulate(time_delta_seconds: number): void;
    /**
     * Fractional progress through the current fixed step, in `[0, 1)` — the
     * leftover sim time that hasn't yet formed a whole {@link fixedUpdateStepSize}
     * step, normalized by the step size. This is the blend parameter the
     * render-time interpolation system pairs with {@link fixedStepTick} to
     * interpolate between the last two completed steps: `alpha = 0` sits on the
     * previous tick, `alpha → 1` approaches the latest.
     *
     * @returns {number} alpha in `[0, 1)`
     */
    getFixedStepAlpha(): number;
    /**
     * If the {@link EntityManager} is already started, the system will be started automatically before being added
     * @param {System} system
     * @returns {Promise} resolution depends on {@link EntityManager}'s state, if running - promise resolves after system startup. Otherwise, the promise will be resolved immediately.
     * @throws {IllegalStateException}
     */
    addSystem(system: System<any, any, any, any, any>): Promise<any>;
    /**
     *
     * @param {System} system
     * @returns {Promise<boolean>}
     */
    removeSystem(system: System<any, any, any, any, any>): Promise<boolean>;
    /**
     * @private
     * @param {System} system
     * @param {function(system: System)} successCallback
     * @param {function(reason:*)} errorCallback
     */
    private stopSystem;
    /**
     * @private
     * @param {System} system
     * @param {function(system: System)} successCallback
     * @param {function(reason:*)} errorCallback
     */
    private startSystem;
    /**
     * This method is asynchronous by nature, it has to wait for each system to finish its own startup.
     * Make sure to register callback to be notified when the startup has finished
     * @param {function} [readyCallback] executed once entity manager successfully completes startup
     * @param {function} [errorCallback] executed if entity manager encounters an error during startup
     */
    startup(readyCallback?: Function, errorCallback?: Function): void;
    /**
     *
     * @param {Class} systemClass
     * @returns {Promise.<System>}
     */
    promiseSystem(systemClass: Class): Promise<System<any, any, any, any, any>>;
    /**
     * @param {Class} SystemClass
     * @param {SystemState} state
     * @returns {Promise.<System>}
     */
    promiseSystemInState(SystemClass: Class, state: SystemState): Promise<System<any, any, any, any, any>>;
    /**
     * This method is asynchronous by nature, it will not be done until each system has finished its shutdown
     * Make sure to use callback to be notified when the shutdown has completed
     * @param {function} [readyCallback] Called when shutdown finishes successfully. defaults to no-operation
     * @param {function} [errorCallback] Called when an error occurs during the shutdown process. defaults to console error output
     */
    shutdown(readyCallback?: Function, errorCallback?: Function): void;
    /**
     * @deprecated use lowercase spelling `attachDataset` instead
     */
    attachDataSet: (dataset: EntityComponentDataset) => void;
    /**
     * @deprecated use lowercase spelling `detachDataset` instead
     */
    detachDataSet: () => void;
}
import { System } from "./System.js";
import Signal from "../../core/events/signal/Signal.js";
import { EntityComponentDataset } from "./EntityComponentDataset.js";
//# sourceMappingURL=EntityManager.d.ts.map