gpui

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GPUI Best Practices

GPUI 最佳实践

Comprehensive guide for building desktop applications with GPUI, the UI framework powering Zed editor. Contains 40+ rules across 8 categories, prioritized by impact.
这是一份使用GPUI构建桌面应用的综合指南,GPUI是为Zed编辑器提供支持的UI框架。指南包含8个分类下的40+条规则,按影响优先级排序。

When to Apply

适用场景

Reference these guidelines when:
  • Writing new GPUI views or components
  • Implementing state management with Entity
  • Handling events and keyboard shortcuts
  • Working with async tasks and background work
  • Building forms, lists, or dialogs
  • Styling components with Tailwind-like API
  • Testing GPUI applications
在以下场景中可参考本指南:
  • 编写新的GPUI视图或组件
  • 使用Entity实现状态管理
  • 处理事件和键盘快捷键
  • 处理异步任务和后台工作
  • 构建表单、列表或对话框
  • 使用类Tailwind API为组件设置样式
  • 测试GPUI应用

Rule Categories by Priority

按优先级划分的规则分类

PriorityCategoryImpactPrefix
1Core ConceptsCRITICAL
core-
2RenderingCRITICAL
render-
3State ManagementHIGH
state-
4Event HandlingHIGH
event-
5Async & ConcurrencyMEDIUM-HIGH
async-
6StylingMEDIUM
style-
7ComponentsMEDIUM
comp-
8Anti-patternsCRITICAL
anti-
优先级分类影响程度前缀
1核心概念关键
core-
2渲染关键
render-
3状态管理
state-
4事件处理
event-
5异步与并发中高
async-
6样式设计
style-
7组件
comp-
8反模式关键
anti-

Quick Reference

快速参考

1. Core Concepts (CRITICAL)

1. 核心概念(关键)

  • core-ownership-model
    - Understand GPUI's single ownership model
  • core-entity-operations
    - Use read/update/observe/subscribe correctly
  • core-weak-entity
    - Use WeakEntity to break circular references
  • core-context-types
    - Know when to use App, Context<T>, AsyncApp
  • core-ownership-model
    - 理解GPUI的单一所有权模型
  • core-entity-operations
    - 正确使用read/update/observe/subscribe方法
  • core-weak-entity
    - 使用WeakEntity打破循环引用
  • core-context-types
    - 了解何时使用App、Context<T>、AsyncApp

2. Rendering (CRITICAL)

2. 渲染(关键)

  • render-render-vs-renderonce
    - Choose Render for stateful, RenderOnce for components
  • render-element-composition
    - Build element trees with div() and method chaining
  • render-conditional
    - Use .when() and .when_some() for conditional styling
  • render-shared-string
    - Use SharedString to avoid string copying
  • render-builder-pattern
    - Design components with builder pattern
  • render-render-vs-renderonce
    - 为有状态组件选择Render,为无状态组件选择RenderOnce
  • render-element-composition
    - 使用div()和方法链构建元素树
  • render-conditional
    - 使用.when()和.when_some()实现条件样式
  • render-shared-string
    - 使用SharedString避免字符串复制
  • render-builder-pattern
    - 采用构建者模式设计组件

3. State Management (HIGH)

3. 状态管理(高)

  • state-notify
    - Always call cx.notify() after state changes
  • state-observe
    - Use cx.observe() to react to Entity changes
  • state-subscribe
    - Use cx.subscribe() for typed events
  • state-global
    - Use Global trait for app-wide state
  • state-keyed-state
    - Use window.use_keyed_state() for persistent state
  • state-notify
    - 状态变更后务必调用cx.notify()
  • state-observe
    - 使用cx.observe()响应Entity变更
  • state-subscribe
    - 使用cx.subscribe()处理类型化事件
  • state-global
    - 为全局应用状态使用Global trait
  • state-keyed-state
    - 使用window.use_keyed_state()实现持久化状态

4. Event Handling (HIGH)

4. 事件处理(高)

  • event-actions
    - Define and register actions for keyboard shortcuts
  • event-listener
    - Use cx.listener() for view-bound event handlers
  • event-focus
    - Manage focus with FocusHandle and key_context
  • event-propagation
    - Understand event bubbling and stop_propagation
  • event-actions
    - 定义并注册键盘快捷键对应的动作
  • event-listener
    - 使用cx.listener()实现视图绑定的事件处理器
  • event-focus
    - 使用FocusHandle和key_context管理焦点
  • event-propagation
    - 理解事件冒泡与stop_propagation的使用

5. Async & Concurrency (MEDIUM-HIGH)

5. 异步与并发(中高)

  • async-task-lifecycle
    - Store or detach tasks to prevent cancellation
  • async-debounce
    - Implement debounce with timer + task replacement
  • async-background-spawn
    - Use background_spawn for CPU-intensive work
  • async-weak-entity
    - Use WeakEntity for safe cross-await access
  • async-error-handling
    - Use .log_err() and .detach_and_log_err()
  • async-task-lifecycle
    - 存储或分离Task以避免被取消
  • async-debounce
    - 结合定时器与任务替换实现防抖
  • async-background-spawn
    - 使用background_spawn处理CPU密集型工作
  • async-weak-entity
    - 使用WeakEntity实现跨await的安全访问
  • async-error-handling
    - 使用.log_err()和.detach_and_log_err()处理错误

6. Styling (MEDIUM)

6. 样式设计(中)

  • style-flexbox
    - Use h_flex() and v_flex() for layouts
  • style-theme-colors
    - Always use cx.theme() for colors
  • style-spacing
    - Use DynamicSpacing for responsive spacing
  • style-elevation
    - Use elevation system for layered surfaces
  • style-flexbox
    - 使用h_flex()和v_flex()实现布局
  • style-theme-colors
    - 始终使用cx.theme()获取颜色
  • style-spacing
    - 使用DynamicSpacing实现响应式间距
  • style-elevation
    - 使用层级系统实现分层界面

7. Components (MEDIUM)

7. 组件(中)

  • comp-stateless
    - Prefer RenderOnce with #[derive(IntoElement)]
  • comp-traits
    - Implement Disableable, Selectable, Sizable traits
  • comp-focus-ring
    - Add focus ring for accessibility
  • comp-dialog
    - Use WindowExt for dialog management
  • comp-variant
    - Use variant enums for component styles
  • comp-stateless
    - 优先使用带有#[derive(IntoElement)]的RenderOnce
  • comp-traits
    - 实现Disableable、Selectable、Sizable trait
  • comp-focus-ring
    - 添加焦点环以提升可访问性
  • comp-dialog
    - 使用WindowExt管理对话框
  • comp-variant
    - 使用变体枚举实现组件样式

8. Anti-patterns (CRITICAL)

8. 反模式(关键)

  • anti-silent-error
    - Never silently discard errors with let _ =
  • anti-drop-task
    - Never drop Task without storing or detaching
  • anti-drop-subscription
    - Always detach or store subscriptions
  • anti-circular-reference
    - Avoid Entity cycles, use WeakEntity
  • anti-missing-notify
    - Never forget cx.notify() after state changes
  • anti-unwrap
    - Avoid unwrap(), use ? or explicit handling
  • anti-silent-error
    - 绝不要用let _ = 静默丢弃错误
  • anti-drop-task
    - 绝不要在未存储或分离的情况下丢弃Task
  • anti-drop-subscription
    - 务必分离或存储订阅
  • anti-circular-reference
    - 避免Entity循环引用,使用WeakEntity替代
  • anti-missing-notify
    - 状态变更后绝不要忘记调用cx.notify()
  • anti-unwrap
    - 避免使用unwrap(),改用?或显式处理

Architecture Overview

架构概述

┌─────────────────────────────────────────────────────────┐
│                    Application (App)                     │
│              (Single owner of all Entities)              │
└─────────────────────────────────────────────────────────┘
        ┌───────────────────┼───────────────────┐
        │                   │                   │
    ┌───────────┐       ┌───────────┐       ┌──────────┐
    │ Entity<A> │       │ Entity<B> │       │ Global<C>│
    └───────────┘       └───────────┘       └──────────┘
        │                   │                   │
        │ read/update       │ read/update       │ via App
        │ via Context<A>    │ via Context<B>    │
    ┌─────────────────────────────────────────────────┐
    │           UI Rendering (Render trait)           │
    │      Each frame: fn render(&mut self, ...)      │
    │      Returns: impl IntoElement (Element tree)   │
    └─────────────────────────────────────────────────┘
        ├─ observe() → changes trigger render
        ├─ subscribe() → events trigger reactions
        ├─ notify() → signal changes
        └─ emit() → send typed events
┌─────────────────────────────────────────────────────────┐
│                    Application (App)                     │
│              (Single owner of all Entities)              │
└─────────────────────────────────────────────────────────┘
        ┌───────────────────┼───────────────────┐
        │                   │                   │
    ┌───────────┐       ┌───────────┐       ┌──────────┐
    │ Entity<A> │       │ Entity<B> │       │ Global<C>│
    └───────────┘       └───────────┘       └──────────┘
        │                   │                   │
        │ read/update       │ read/update       │ via App
        │ via Context<A>    │ via Context<B>    │
    ┌─────────────────────────────────────────────────┐
    │           UI Rendering (Render trait)           │
    │      Each frame: fn render(&mut self, ...)      │
    │      Returns: impl IntoElement (Element tree)   │
    └─────────────────────────────────────────────────┘
        ├─ observe() → changes trigger render
        ├─ subscribe() → events trigger reactions
        ├─ notify() → signal changes
        └─ emit() → send typed events

How to Use

使用方法

Read individual rule files for detailed explanations and code examples:
rules/core-ownership-model.md
rules/render-render-vs-renderonce.md
rules/anti-silent-error.md
Each rule file contains:
  • Brief explanation of why it matters
  • Incorrect code example with explanation
  • Correct code example with explanation
  • Additional context and references
阅读单个规则文件以获取详细说明和代码示例:
rules/core-ownership-model.md
rules/render-render-vs-renderonce.md
rules/anti-silent-error.md
每个规则文件包含:
  • 规则重要性的简要说明
  • 错误代码示例及解释
  • 正确代码示例及解释
  • 额外背景信息与参考资料