Agent SkillsfeigeCode/navop › gpui-event

gpui-event

GitHub

GPUI事件处理技能,支持自定义事件定义与发射、实体状态观察及组件间订阅。涵盖父子通信、全局广播和观察者模式,助力实现类型安全的事件驱动架构与组件协调。

.codex/skills/gpui-event/SKILL.md feigeCode/navop

Trigger Scenarios

需要实现组件间通信 监听实体状态变化 构建事件驱动系统 父向子传递消息

Install

npx skills add feigeCode/navop --skill gpui-event -g -y
More Options

Non-standard path

npx skills add https://github.com/feigeCode/navop/tree/dev/.codex/skills/gpui-event -g -y

Use without installing

npx skills use feigeCode/navop@gpui-event

指定 Agent (Claude Code)

npx skills add feigeCode/navop --skill gpui-event -a claude-code -g -y

安装 repo 全部 skill

npx skills add feigeCode/navop --all -g -y

预览 repo 内 skill

npx skills add feigeCode/navop --list

SKILL.md

Frontmatter
{
    "name": "gpui-event",
    "description": "Event handling and subscriptions in GPUI. Use when implementing events, observers, or event-driven patterns. Supports custom events, entity observations, and event subscriptions for coordinating between components."
}

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<Self>) {
        self.data = data.clone();

        // Emit event
        cx.emit(MyEvent::DataUpdated(data));
        cx.notify();
    }
}

Subscribe to Events

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

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

// 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

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

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

Version History

  • e768f09 Current 2026-07-19 08:48

Same Skill Collection

.codex/skills/gpui-action/SKILL.md
.codex/skills/gpui-async/SKILL.md
.codex/skills/gpui-context/SKILL.md
.codex/skills/gpui-element/SKILL.md
.codex/skills/gpui-entity/SKILL.md
.codex/skills/gpui-focus-handle/SKILL.md
.codex/skills/gpui-global/SKILL.md
.codex/skills/gpui-layout-and-style/SKILL.md
.codex/skills/gpui-style-guide/SKILL.md
.codex/skills/gpui-test/SKILL.md
.codex/skills/navop-release-notes/SKILL.md
.codex/skills/new-component/SKILL.md

Metadata

Files
0
Version
ba0720c
Hash
034e7fd2
Indexed
2026-07-19 08:48

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-20 15:27
浙ICP备14020137号-1 $Carte des visiteurs$