import type ECSpresso from './ecspresso';
import type { RemoveEntityOptions } from './types';
import type { WorldConfig, EmptyConfig } from './type-utils';
/**
 * CommandBuffer queues structural changes to be executed later.
 * This prevents ordering issues when modifying entities during system execution.
 *
 * Commands are executed in FIFO order when playback() is called.
 *
 * @example
 * ```typescript
 * // In a system
 * ecs.commands.removeEntity(entityId);
 * ecs.commands.spawn({ position: { x: 0, y: 0 } });
 *
 * // Later (automatically at end of update())
 * ecs.commands.playback(ecs);
 * ```
 */
export default class CommandBuffer<Cfg extends WorldConfig = EmptyConfig> {
    private readonly parent?;
    private commands;
    /**
     * @param parent Owning ECS instance, used to read the active scope hint at
     *   queue time so screen-gated spawns get auto-scoped on playback. Optional
     *   so the buffer can be constructed standalone in tests.
     */
    constructor(parent?: ECSpresso<Cfg> | undefined);
    /**
     * Queue an entity removal command
     * @param entityId The entity ID to remove
     * @param options Optional removal options (cascade, etc.)
     */
    removeEntity(entityId: number, options?: RemoveEntityOptions): void;
    /**
     * Queue a component addition command
     * @param entityId The entity ID
     * @param componentName The name of the component to add
     * @param componentValue The component data
     */
    addComponent<K extends keyof Cfg['components']>(entityId: number, componentName: K, componentValue: Cfg['components'][K]): void;
    /**
     * Queue a component removal command
     * @param entityId The entity ID
     * @param componentName The name of the component to remove
     */
    removeComponent<K extends keyof Cfg['components']>(entityId: number, componentName: K): void;
    /**
     * Queue an entity spawn command
     * @param components The initial components for the new entity
     * @returns void (entity ID not available until playback)
     */
    spawn<T extends {
        [K in keyof Cfg['components']]?: Cfg['components'][K];
    }>(components: T & Record<Exclude<keyof T, keyof Cfg['components']>, never>, options?: {
        scope?: (keyof Cfg['screens'] & string) | null;
    }): void;
    /**
     * Queue a child entity spawn command
     * @param parentId The parent entity ID
     * @param components The initial components for the new child entity
     */
    spawnChild<T extends {
        [K in keyof Cfg['components']]?: Cfg['components'][K];
    }>(parentId: number, components: T & Record<Exclude<keyof T, keyof Cfg['components']>, never>, options?: {
        scope?: (keyof Cfg['screens'] & string) | null;
    }): void;
    /**
     * Snapshot the parent ECS's active scope hint at queue time when the
     * caller didn't pass an explicit scope. Without this, playback (after the
     * tick ends) would see a null hint and the gated system's screen intent
     * would be lost.
     */
    private _resolveScope;
    /**
     * Queue multiple component additions
     * @param entityId The entity ID
     * @param components Object with component names as keys and component data as values
     */
    addComponents<T extends {
        [K in keyof Cfg['components']]?: Cfg['components'][K];
    }>(entityId: number, components: T & Record<Exclude<keyof T, keyof Cfg['components']>, never>): void;
    /**
     * Queue a parent assignment command
     * @param childId The child entity ID
     * @param parentId The parent entity ID
     */
    setParent(childId: number, parentId: number): void;
    /**
     * Queue a component mutation command.
     * The mutator runs during playback, receiving the component for in-place mutation.
     * Automatically marks the component as changed.
     * @param entityId The entity ID
     * @param componentName The component to mutate
     * @param mutator A function that receives the component value for in-place mutation
     */
    mutateComponent<K extends keyof Cfg['components']>(entityId: number, componentName: K, mutator: (value: Cfg['components'][K]) => void): void;
    /** Queue a markChanged command for playback. */
    markChanged<K extends keyof Cfg['components']>(entityId: number, componentName: K): void;
    /**
     * Queue a parent removal command
     * @param childId The child entity ID
     */
    removeParent(childId: number): void;
    /**
     * Execute all queued commands in FIFO order.
     * Errors from individual commands are caught and logged, but do not stop playback.
     * @param ecs The ECSpresso instance to execute commands on
     */
    playback(ecs: ECSpresso<Cfg>): void;
    /**
     * Clear all queued commands without executing them
     */
    clear(): void;
    /**
     * Get the number of queued commands
     * @returns The number of commands waiting to be executed
     */
    get length(): number;
}
