Guide · 04 State & Navigation
响应式状态与多端路由 (Store & Router)
使用线程安全的 Store
响应式状态容器:`Store<T>`
gpux::Store<T> 基于 Arc<RwLock<T>> 封装,支持在多个 GPUI 视图、后台异步遥测任务与强类型 ServiceRegistry 服务闭包之间零拷贝共享(Clone 仅增加原子引用计数)并执行原子读写更新:
rust
use gpux::prelude::*;
#[derive(Clone, Debug, Default)]
pub struct TelemetryState {
pub active_workers: u32,
pub p99_ms: f32,
}
let store = Store::new(TelemetryState {
active_workers: 4,
p99_ms: 0.24,
});
// 原子修改状态并返回计算结果
let workers = store.update(|s| {
s.active_workers += 2;
s.p99_ms = 0.19;
s.active_workers
});
assert_eq!(workers, 6);
assert_eq!(store.get().active_workers, 6);
多端历史路由栈:`Router<R>`
Router<R> 允许你使用强类型 Rust 枚举定义应用的所有页面,自动维护去重的前进/后退历史栈,并直接对接桌面快捷键、iOS 侧滑返回、Android / HarmonyOS 系统级 Back 手势以及 Web History 状态:
rust
use gpux::prelude::*;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AppRoute {
Overview,
NodeDetail(u64),
Inspector,
}
let mut router = Router::new(AppRoute::Overview);
router.push(AppRoute::NodeDetail(42));
router.push(AppRoute::Inspector);
assert!(router.can_go_back());
assert_eq!(router.current(), &AppRoute::Inspector);
// 弹出栈顶路由,返回是否成功回退(栈底根路由不会被弹出)
assert!(router.pop());
assert_eq!(router.current(), &AppRoute::NodeDetail(42));
在 GPUI 视图中联动 `Store`、`Router` 与 `cx.notify()`
在 GPUI 的响应式实体模型中,修改 Store<T> 或 Router<R> 后只需调用 cx.notify(),GPUI 即可在下一帧以增量场景图重绘受影响的区域:
rust
impl Render for ClusterShell {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let state = self.store.get();
let current_route = self.router.current().clone();
let can_back = self.router.can_go_back();
v_flex()
.size_full()
.gap_4()
.p_5()
.bg(cx.theme().background)
.child(
h_flex()
.justify_between()
.child(format!("Route: {:?} · Workers: {}", current_route, state.active_workers))
.child(
Button::new("btn-back")
.outline()
.label(if can_back { "← 返回上级" } else { "进入 Inspector →" })
.on_click(cx.listener(|this, _ev, _win, cx| {
if !this.router.pop() {
this.router.push(AppRoute::Inspector);
}
cx.notify();
})),
),
)
}
}