import { GameEventBus } from "../classes/eventBus.d.ts"; import { Binding, BindingDefinition, CaptureInputOptions, Context, InputDefinition } from "../interfaces/binding.d.ts"; import { Disposable } from "../interfaces/lifecycle.d.ts"; import { DeviceType, InputDevice, InputState } from "../interfaces/input.d.ts"; import { Action } from "../interfaces/action.d.ts"; import { LoggingUtility } from "../utils/logger.d.ts"; /** * Configuration object structure for binding manager */ export interface BindingConfiguration { /** All registered actions */ actions: Action[]; /** All registered bindings */ bindings: BindingDefinition[]; /** All registered contexts */ contexts: { name: string; exclusive: boolean; active: boolean; }[]; } /** * Manages input bindings and actions for the game */ export declare class BindingManager implements Disposable { /** Map of device IDs to their bindings */ private _bindings; /** Map of action names to their action definitions */ private _actions; /** Map of all registered contexts by name for O(1) lookup */ private _contexts; /** * Set of all active contexts (both exclusive and non-exclusive) */ private _activeContexts; /** The most recent device type that produced intentional input */ private _lastActiveDeviceType; /** Last input state per device, used to prime edge state on context activation */ private _lastInputState; /** Active captureInput() state, or null when not capturing */ private _captureState; /** Event bus for handling game events */ private _eventBus; /** Unsubscribe function for input events */ private _inputUnsubscribe; /** Logger instance */ private _log; /** * Creates an instance of BindingManager. * Automatically subscribes to 'input:changed' events on the event bus. * * @param eventBus * @param logger */ constructor(eventBus: GameEventBus, logger?: LoggingUtility); /** * Checks if a binding's context is currently active. * Bindings with no context are always considered active. * * @param binding */ private _isBindingContextActive; /** * Get a context by name, creating it if it doesn't exist. * * @param contextName * @param exclusive - Only used when creating a new context */ private _getOrCreateContext; /** * Deactivate all exclusive contexts except the specified one. * Non-exclusive contexts are left untouched. * * @param exceptContextName */ private _deactivateExclusiveContexts; /** * Determines whether an input event represents intentional activity that should * update the last-active device type. Filters out noise like idle mousemove. * * @param state */ private _shouldUpdateActiveDevice; /** * Create a binding from a binding definition. * * @param definition * @returns Null if the action is not registered or the binding type is unsupported */ private _createBindingFromDefinition; /** * Create a device value reader from a definition object. * * @param definition * @throws Error if the reader type is not supported */ private _createInputSourceFromDefinition; /** * Evaluates an input event during capture mode. If the event matches the capture criteria, * resolves the capture promise and cleans up. Otherwise does nothing and waits for the next event. * * @param device * @param state */ private _processCaptureInput; /** * Tears down capture state, deactivates the temporary context, and restores the * snapshotted contexts. Does not resolve or reject — the caller handles that. */ private _cleanupCapture; /** * Handle input from a device and process all relevant bindings. * * **Internal API**: This method is prefixed with `$` to indicate it is intended for internal * engine use only. While it is public for testing purposes, external code should not call * this method directly. Input handling is triggered automatically via the event bus. * * @param device - The input device * @param state - Current input state * * @internal */ $handleInput(device: InputDevice, state: InputState): void; /** * Registers an action. * * @param action * @throws Error if action is already registered */ registerAction(action: Action): void; /** * Gets an action by name. * * @param actionName */ getAction(actionName: string): Action | null; /** * Returns the device type that most recently produced intentional input, * or `null` if no input has been received yet. */ get lastActiveDeviceType(): DeviceType | null; /** * Waits for the next intentional input event and returns a descriptor suitable for constructing * a binding. While capturing, all normal bindings are suppressed via a temporary exclusive context. * Previous context state is restored when the capture completes or is cancelled. * * @param options * @throws Error if a capture is already in progress */ captureInput(options: CaptureInputOptions): Promise; /** * Registers a context with specific options. * Updates exclusivity if the context already exists. * * @param contextName * @param exclusive */ registerContext(contextName: string, exclusive?: boolean): Context; /** * Activates a context, enabling all bindings associated with it. * If the context is exclusive, all other exclusive contexts will be deactivated. * * @param contextName */ activateContext(contextName: string): void; /** * Deactivates a context, disabling all bindings associated with it. * * @param contextName */ deactivateContext(contextName: string): void; /** * Returns a list of all active contexts. */ getActiveContexts(): string[]; /** * Returns whether a context is active. * * @param contextName */ isContextActive(contextName: string): boolean; /** * Gets a context by name. * * @param contextName */ getContext(contextName: string): Context | null; /** * Register a binding for an input device. * Auto-registers the binding's context if not already known. * * @param binding * @throws Error if binding type is invalid */ $registerBinding(binding: Binding): void; /** * Register a binding using a binding definition object. * Creates the appropriate Binding subclass and registers it. * * @param definition */ registerBinding(definition: BindingDefinition): void; /** * Unregister all bindings for an action within a context. * * @param actionName * @param context - Pass null (default) to target context-free bindings */ unregisterBindings(actionName: string, context?: string | null): void; /** * Gets all bindings for a specific action, optionally filtered by device type and/or context. * * @param actionName * @param deviceType - If provided, filters to only bindings for that device type * @param context - If provided, filters to only bindings in that context */ getBindingsForAction(actionName: string, deviceType?: DeviceType, context?: string | null): Binding[]; /** * Exports the current configuration to a serializable object. * Includes all actions, bindings, contexts, and their active states. */ exportConfiguration(): BindingConfiguration; /** * Imports a configuration, replacing all current actions, bindings, and contexts. * * @param config */ importConfiguration(config: BindingConfiguration): void; /** * Tears down the binding manager and cleans up any resources */ $teardown(): Promise; }