Skip to main content

Overview

The Pascal Editor SDK uses a typed event bus based on mitt for inter-component communication. This enables decoupled, event-driven architecture for handling user interactions, camera controls, and tool coordination.

Event Bus

The event emitter is exported from @pascal-app/core:
Location: packages/core/src/events/bus.ts:91

Event Types

Node Events

Node events are fired when users interact with 3D objects:
Location: packages/core/src/events/bus.ts:12-19

Type-Specific Events

Each node type has its own event variant:
Location: packages/core/src/events/bus.ts:21-31

Event Suffixes

All node and grid events support these interaction types:
Location: packages/core/src/events/bus.ts:34-43 This generates events like:
  • wall:click
  • item:enter
  • zone:context-menu
  • slab:double-click

Grid Events

Grid events fire when interacting with empty space (background):
Location: packages/core/src/events/bus.ts:7-10 Grid events:
  • grid:click
  • grid:move
  • grid:pointerdown
  • etc.

Camera Control Events

Events for controlling camera behavior:
Location: packages/core/src/events/bus.ts:55-70

Tool Events

Events for tool coordination:
Location: packages/core/src/events/bus.ts:72-74

Subscribing to Events

Basic Subscription

React Hook Pattern

Wildcard Events

Emitting Events

From Renderers

Node renderers emit events on user interactions:

From Tools

Camera Controls

Event Flow Example

Here’s how events flow through the system when a user clicks a wall:
  1. User clicks on a wall mesh
  2. WallRenderer handles the Three.js click event
  3. Renderer emits wall:click event with node data
  4. SelectTool (subscribed to wall clicks) receives event
  5. Tool updates selection state in store
  6. Store triggers re-render with new selection

Use Cases

Selection Management

Context Menus

Hover Highlighting

Tool Coordination

Event Propagation

Events support propagation control:
The stopPropagation function calls the native Three.js event’s stopPropagation, preventing the event from bubbling up the scene hierarchy.

Best Practices

Always Cleanup

Remove event listeners in cleanup functions to prevent memory leaks

Type Safety

Use typed event interfaces (WallEvent, ItemEvent) for type safety

Stop Propagation

Call event.stopPropagation() to prevent unintended parent interactions

Minimal Emitters

Only emit events from renderers and core systems, not from UI components
Memory Leaks: Always clean up event listeners in React useEffect return functions or component unmount handlers.