gpui-event
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOverview
概述
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
GPUI 为组件协调提供事件系统:
事件机制:
- 自定义事件:定义并发射类型安全的事件
- 观察机制:响应实体状态变化
- 订阅机制:监听来自其他实体的事件
- 全局事件:应用级别的事件处理
Quick Start
快速开始
Define and Emit Events
定义并发射事件
rust
#[derive(Clone)]
enum MyEvent {
DataUpdated(String),
ActionTriggered,
}
impl MyComponent {
fn update_data(&mut self, data: String, cx: &mut Context<Self>) {
self.data = data.clone();
// Emit event
cx.emit(MyEvent::DataUpdated(data));
cx.notify();
}
}rust
#[derive(Clone)]
enum MyEvent {
DataUpdated(String),
ActionTriggered,
}
impl MyComponent {
fn update_data(&mut self, data: String, cx: &mut Context<Self>) {
self.data = data.clone();
// Emit event
cx.emit(MyEvent::DataUpdated(data));
cx.notify();
}
}Subscribe to Events
订阅事件
rust
impl Listener {
fn new(source: Entity<MyComponent>, cx: &mut App) -> Entity<Self> {
cx.new(|cx| {
// Subscribe to events
cx.subscribe(&source, |this, emitter, event: &MyEvent, cx| {
match event {
MyEvent::DataUpdated(data) => {
this.handle_update(data.clone(), cx);
}
MyEvent::ActionTriggered => {
this.handle_action(cx);
}
}
}).detach();
Self { source }
})
}
}rust
impl Listener {
fn new(source: Entity<MyComponent>, cx: &mut App) -> Entity<Self> {
cx.new(|cx| {
// Subscribe to events
cx.subscribe(&source, |this, emitter, event: &MyEvent, cx| {
match event {
MyEvent::DataUpdated(data) => {
this.handle_update(data.clone(), cx);
}
MyEvent::ActionTriggered => {
this.handle_action(cx);
}
}
}).detach();
Self { source }
})
}
}Observe Entity Changes
观察实体变化
rust
impl Observer {
fn new(target: Entity<Target>, cx: &mut App) -> Entity<Self> {
cx.new(|cx| {
// Observe entity for any changes
cx.observe(&target, |this, observed, cx| {
// Called when observed.update() calls cx.notify()
println!("Target changed");
cx.notify();
}).detach();
Self { target }
})
}
}rust
impl Observer {
fn new(target: Entity<Target>, cx: &mut App) -> Entity<Self> {
cx.new(|cx| {
// Observe entity for any changes
cx.observe(&target, |this, observed, cx| {
// Called when observed.update() calls cx.notify()
println!("Target changed");
cx.notify();
}).detach();
Self { target }
})
}
}Common Patterns
常见模式
1. Parent-Child Communication
1. 父子组件通信
rust
// Parent emits events
impl Parent {
fn notify_children(&mut self, cx: &mut Context<Self>) {
cx.emit(ParentEvent::Updated);
cx.notify();
}
}
// Children subscribe
impl Child {
fn new(parent: Entity<Parent>, cx: &mut App) -> Entity<Self> {
cx.new(|cx| {
cx.subscribe(&parent, |this, parent, event, cx| {
this.handle_parent_event(event, cx);
}).detach();
Self { parent }
})
}
}rust
// Parent emits events
impl Parent {
fn notify_children(&mut self, cx: &mut Context<Self>) {
cx.emit(ParentEvent::Updated);
cx.notify();
}
}
// Children subscribe
impl Child {
fn new(parent: Entity<Parent>, cx: &mut App) -> Entity<Self> {
cx.new(|cx| {
cx.subscribe(&parent, |this, parent, event, cx| {
this.handle_parent_event(event, cx);
}).detach();
Self { parent }
})
}
}2. Global Event Broadcasting
2. 全局事件广播
rust
struct EventBus {
listeners: Vec<WeakEntity<dyn Listener>>,
}
impl EventBus {
fn broadcast(&mut self, event: GlobalEvent, cx: &mut Context<Self>) {
self.listeners.retain(|weak| {
weak.update(cx, |listener, cx| {
listener.on_event(&event, cx);
}).is_ok()
});
}
}rust
struct EventBus {
listeners: Vec<WeakEntity<dyn Listener>>,
}
impl EventBus {
fn broadcast(&mut self, event: GlobalEvent, cx: &mut Context<Self>) {
self.listeners.retain(|weak| {
weak.update(cx, |listener, cx| {
listener.on_event(&event, cx);
}).is_ok()
});
}
}3. Observer Pattern
3. 观察者模式
rust
cx.observe(&entity, |this, observed, cx| {
// React to any state change
let state = observed.read(cx);
this.sync_with_state(state, cx);
}).detach();rust
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
✅ 分离订阅
rust
// ✅ Detach to keep alive
cx.subscribe(&entity, |this, source, event, cx| {
// Handle event
}).detach();rust
// ✅ Detach to keep alive
cx.subscribe(&entity, |this, source, event, cx| {
// Handle event
}).detach();✅ Clean Event Types
✅ 清晰的事件类型
rust
#[derive(Clone)]
enum AppEvent {
DataChanged { id: usize, value: String },
ActionPerformed(ActionType),
Error(String),
}rust
#[derive(Clone)]
enum AppEvent {
DataChanged { id: usize, value: String },
ActionPerformed(ActionType),
Error(String),
}❌ Avoid Event Loops
❌ 避免事件循环
rust
// ❌ Don't create mutual subscriptions
entity1.subscribe(entity2) → emits event
entity2.subscribe(entity1) → emits event → infinite loop!rust
// ❌ 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
-
API 参考:查看 api-reference.md
- 事件定义、发射、订阅
- 观察机制、全局事件
- 订阅生命周期
-
模式参考:查看 patterns.md
- 事件驱动架构
- 通信模式
- 最佳实践与常见陷阱