Input Manager

Centralized input handling for mouse and keyboard

Overview

The InputManager captures all mouse and keyboard input from the browser and emits standardized events to the EventBus. This provides a single point of input handling, similar to how OSes handle input at the kernel level.

Features

  • Mouse State Tracking: Tracks position, button states, and target element
  • Keyboard State Tracking: Tracks pressed keys and modifier keys (Ctrl, Alt, Shift, Meta)
  • Event Normalization: Converts browser events to standardized format
  • EventBus Integration: Emits all input to EventBus for component consumption

Emitted Events

Mouse Events

  • input.mousedown - Button pressed
    • data.x, data.y - Mouse position
    • data.button - 'left', 'right', or 'middle'
    • data.buttons - Object with all button states
    • data.target - Element under cursor
  • input.mouseup - Button released (same data structure)
  • input.mousemove - Mouse moved (same data structure)
  • input.click - Click detected
  • input.dblclick - Double-click detected
  • input.contextmenu - Right-click menu requested

Keyboard Events

  • input.keydown - Key pressed
    • data.key - Key name (e.g., 'a', 'Enter', 'ArrowLeft')
    • data.code - Physical key code
    • data.modifiers - Object with Ctrl, Alt, Shift, Meta states
  • input.keyup - Key released (same data structure)

Usage

Initialization

const eventBus = new EventBus();
const inputManager = new InputManager(eventBus);
window.freeworldInputManager = inputManager;

Subscribing to Input Events

// Listen for mouse clicks
eventBus.on('input.click', (event) => {
    console.log('Clicked at:', event.data.x, event.data.y);
    console.log('Target:', event.data.target);
});

// Listen for keyboard input
eventBus.on('input.keydown', (event) => {
    if (event.data.key === 'Enter' && event.data.modifiers.ctrl) {
        console.log('Ctrl+Enter pressed');
    }
});

Getting Current State

// Get current mouse state
const mouseState = inputManager.getMouseState();
console.log('Mouse at:', mouseState.x, mouseState.y);
console.log('Left button:', mouseState.buttons.left);

// Get current keyboard state
const keyboardState = inputManager.getKeyboardState();
console.log('Pressed keys:', Array.from(keyboardState.keys));
console.log('Ctrl pressed:', keyboardState.modifiers.ctrl);

Integration

The InputManager is the foundation of the input system. All other components that need input (DragDropSystem, window managers, etc.) subscribe to InputManager events via the EventBus rather than attaching their own DOM listeners.

This ensures:

  • No duplicate event listeners
  • Consistent event format across all components
  • Easy debugging (all input flows through one place)
  • Components can be added/removed without affecting input handling