Overview
GPUI provides event system for component coordination:
Event Mechanisms:
Custom Events: Define and emit type-safe events Observations: React to entity state changes Subscriptions: Listen to events from other entities Global Events: App-wide event handling Quick Start Define and Emit Events
[derive(Clone)]
enum MyEvent { DataUpdated(String), ActionTriggered, }
impl MyComponent {
fn update_data(&mut self, data: String, cx: &mut Context
// Emit event
cx.emit(MyEvent::DataUpdated(data));
cx.notify();
}
}
Subscribe to Events
impl Listener {
fn new(source: Entity
Self { source }
})
}
}
Observe Entity Changes
impl Observer {
fn new(target: Entity
Self { target }
})
}
}
Common Patterns
1. Parent-Child Communication
// Parent emits events
impl Parent {
fn notify_children(&mut self, cx: &mut Context
// Children subscribe
impl Child {
fn new(parent: Entity
Self { parent }
})
}
}
- Global Event Broadcasting
struct EventBus {
listeners: Vec
>, }
impl EventBus {
fn broadcast(&mut self, event: GlobalEvent, cx: &mut Context
- Observer Pattern cx.observe(&entity, |this, observed, cx| { // React to any state change let state = observed.read(cx); this.sync_with_state(state, cx); }).detach();
Best Practices ✅ Detach Subscriptions // ✅ Detach to keep alive cx.subscribe(&entity, |this, source, event, cx| { // Handle event }).detach();
✅ Clean Event Types
[derive(Clone)]
enum AppEvent { DataChanged { id: usize, value: String }, ActionPerformed(ActionType), Error(String), }
❌ Avoid Event Loops // ❌ Don't create mutual subscriptions entity1.subscribe(entity2) → emits event entity2.subscribe(entity1) → emits event → infinite loop!
Reference Documentation
API Reference: See api-reference.md
Event definition, emission, subscriptions Observations, global events Subscription lifecycle
Patterns: See patterns.md
Event-driven architectures Communication patterns Best practices and pitfalls