ansiq-runtime
ansiq-runtime 是 Ansiq 的运行时入口。它主要负责:
App生命周期RuntimeHandle提供的消息、任务、history 和 focus 控制接口- 主循环、dirty scope 收集、局部 rerender
- focus 与 input routing
如果你还没先理解这些类型的职责,先读:
App trait
pub trait App {
type Message: Send + 'static;
fn mount(&mut self, _handle: &RuntimeHandle<Self::Message>) {}
fn render(&mut self, cx: &mut ViewCtx<'_, Self::Message>) -> Element<Self::Message>;
fn update(&mut self, message: Self::Message, handle: &RuntimeHandle<Self::Message>);
fn on_unhandled_key(&mut self, _key: Key, _handle: &RuntimeHandle<Self::Message>) -> bool {
false
}
}mount(...)
调用时机:
- terminal session 建立之后
- 第一次
render(...)之前
典型用途:
- 启动后台任务
- 发送初始消息
- 建立需要长期存在的连接或采样器
不适合的事情:
- 直接修改渲染树
- 在这里手动做布局或 patch
render(...)
render(...) 负责:
- 描述当前 UI 树
- 建立本轮响应式读取
- 暴露组件边界和 continuity key
它不负责:
- 直接写 terminal
- 决定 relayout / damage model
update(...)
update(...) 负责:
- 消费
Message - 修改 app state
- 决定是否继续启动异步工作
最常见的边界是:
async task -> handle.emit(Message) -> update(...) -> state
on_unhandled_key(...)
如果某个按键:
- 没有被当前 widget 消费
- 也没有被 runtime 的焦点导航消费
那么它会回到 app 的 on_unhandled_key(...)。
适合这里处理的事情:
- 全局快捷键
Escape取消- 模式切换
- 命令入口
fn on_unhandled_key(
&mut self,
key: Key,
handle: &RuntimeHandle<Self::Message>,
) -> bool {
if key == Key::Esc {
let _ = handle.emit(Message::Cancel);
return true;
}
false
}RuntimeHandle
RuntimeHandle 是 app 和 runtime 之间最重要的控制面。
消息与任务
handle.emit(Message::Refresh)?;
let task_handle = handle.clone();
handle.spawn(async move {
let _ = task_handle.emit(Message::Loaded(data));
});最常用的方法:
emit(message):把消息送回 appspawn(future):启动后台任务quit():请求退出主循环
注意:
- 不要在
spawn(...)的任务里直接改 UI signal - 正确模式始终是
emit -> update -> state
history / scrollback
handle.commit_history("completed turn".to_string())?;
handle.commit_history_block(block)?;这组方法适合:
- 把已完成 turn 提交到 scrollback
- 把 live viewport 留给当前活动内容
focus scope
handle.trap_focus_in("composer-panel")?;
handle.clear_focus_scope()?;这组方法适合:
- modal
- 弹出层
- 需要把
Tab限制在某个子树里的面板
它们依赖的是 continuity key,而不是临时 node id。
最小运行入口
use ansiq_runtime::run_app;
#[tokio::main]
async fn main() -> std::io::Result<()> {
run_app(MyApp::default()).await
}如果你还需要控制 viewport 策略,用 run_app_with_policy(...),见下一页:
Last updated on