gpui-entity

安装量: 134
排名: #6460

安装

npx skills add https://github.com/longbridge/gpui-component --skill gpui-entity

Overview

An Entity is a handle to state of type T, providing safe access and updates.

Key Methods:

entity.read(cx) → &T - Read-only access entity.read_with(cx, |state, cx| ...) → R - Read with closure entity.update(cx, |state, cx| ...) → R - Mutable update entity.downgrade() → WeakEntity - Create weak reference entity.entity_id() → EntityId - Unique identifier

Entity Types:

Entity: Strong reference (increases ref count) WeakEntity: Weak reference (doesn't prevent cleanup, returns Result) 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, }

impl MyComponent { fn new(cx: &mut App) -> Entity { 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) { 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

返回排行榜