gpui-entity
50
总安装量
50
周安装量
#4296
全站排名
安装命令
npx skills add https://github.com/longbridge/gpui-component --skill gpui-entity
Agent 安装分布
opencode
35
claude-code
34
gemini-cli
29
codex
29
cursor
24
antigravity
22
Skill 文档
Overview
An Entity<T> is a handle to state of type T, providing safe access and updates.
Key Methods:
entity.read(cx)â&T– Read-only accessentity.read_with(cx, |state, cx| ...)âR– Read with closureentity.update(cx, |state, cx| ...)âR– Mutable updateentity.downgrade()âWeakEntity<T>– Create weak referenceentity.entity_id()âEntityId– Unique identifier
Entity Types:
Entity<T>: Strong reference (increases ref count)WeakEntity<T>: Weak reference (doesn’t prevent cleanup, returnsResult)
Quick Start
Creating and Using Entities
// Create entity
let counter = cx.new(|cx| Counter { count: 0 });
// Read state
let count = counter.read(cx).count;
// Update state
counter.update(cx, |state, cx| {
state.count += 1;
cx.notify(); // Trigger re-render
});
// Weak reference (for closures/callbacks)
let weak = counter.downgrade();
let _ = weak.update(cx, |state, cx| {
state.count += 1;
cx.notify();
});
In Components
struct MyComponent {
shared_state: Entity<SharedData>,
}
impl MyComponent {
fn new(cx: &mut App) -> Entity<Self> {
let shared = cx.new(|_| SharedData::default());
cx.new(|cx| Self {
shared_state: shared,
})
}
fn update_shared(&mut self, cx: &mut Context<Self>) {
self.shared_state.update(cx, |state, cx| {
state.value = 42;
cx.notify();
});
}
}
Async Operations
impl MyComponent {
fn fetch_data(&mut self, cx: &mut Context<Self>) {
let weak_self = cx.entity().downgrade();
cx.spawn(async move |cx| {
let data = fetch_from_api().await;
// Update entity safely
let _ = weak_self.update(cx, |state, cx| {
state.data = Some(data);
cx.notify();
});
}).detach();
}
}
Core Principles
Always Use Weak References in Closures
// â
Good: Weak reference prevents retain cycles
let weak = cx.entity().downgrade();
callback(move || {
let _ = weak.update(cx, |state, cx| cx.notify());
});
// â Bad: Strong reference may cause memory leak
let strong = cx.entity();
callback(move || {
strong.update(cx, |state, cx| cx.notify());
});
Use Inner Context
// â
Good: Use inner cx from closure
entity.update(cx, |state, inner_cx| {
inner_cx.notify(); // Correct
});
// â Bad: Use outer cx (multiple borrow error)
entity.update(cx, |state, inner_cx| {
cx.notify(); // Wrong!
});
Avoid Nested Updates
// â
Good: Sequential updates
entity1.update(cx, |state, cx| { /* ... */ });
entity2.update(cx, |state, cx| { /* ... */ });
// â Bad: Nested updates (may panic)
entity1.update(cx, |_, cx| {
entity2.update(cx, |_, cx| { /* ... */ });
});
Common Use Cases
- Component State: Internal state that needs reactivity
- Shared State: State shared between multiple components
- Parent-Child: Coordinating between related components (use weak refs)
- Async State: Managing state that changes from async operations
- Observations: Reacting to changes in other entities
Reference Documentation
Complete API Documentation
- Entity API: See api-reference.md
- Entity types, methods, lifecycle
- Context methods, async operations
- Error handling, type conversions
Implementation Guides
-
Patterns: See patterns.md
- Model-view separation, state management
- Cross-entity communication, async operations
- Observer pattern, event subscription
- Pattern selection guide
-
Best Practices: See best-practices.md
- Avoiding common pitfalls, memory leaks
- Performance optimization, batching updates
- Lifecycle management, cleanup
- Async best practices, testing
-
Advanced Patterns: See advanced.md
- Entity collections, registry pattern
- Debounced/throttled updates, state machines
- Entity snapshots, transactions, pools