Bevy UI 系统的演进提议
Bevy 社区最近就如何进一步完善其 UI 系统展开了热烈讨论。这主要是为了让 Bevy Editor 成为可能。@cart 作为讨论发起人,提出了以下一些改进方向:
- 统一 Bevy 的场景(Scene)系统和 UI 系统。UI 界面的定义应该通过场景系统来完成,而不是现有的命令式生成方式。
- 引入一种新的 Bevy 场景格式(BSN),同时适用于资源文件和 Rust 代码中场景的定义。比如: Div { width: 10 height: 100 } [ Img { handle: "branding/icon.png" } Div { width: 100 height: 200 } @("player.bsn") ]
- 增加场景的继承与嵌套支持。一个实体可以从另一个场景继承,也可以从多个场景继承。
- 支持属性的“级联”(cascading)。如果一个场景为一个实体定义了 Style::color,它会覆盖该实体继承的其他场景中的该属性,但保留其他 Style 属性。
- 引入 Schematics 概念,作为现有 Bundle 的扩展。Schematics 定义任意的输入数据,然后在插入到 ECS World 时转换为实际的组件。这填补了现有 Bundle 的功能缺口。 示例: #[derive(Component, Schematic, Reflect, Clone)] #[reflect(Schematic, Reflect)] struct Div { #[schematic] handle: Handle<Image>, } // 上面的宏展开之后大概是下面的样子 impl Props for AssetPath<'static> { fn apply_props(&mut self, other: &Self) { *self = other.clone() } } impl<T: Asset> Schematic for Handle<T> { type Props = AssetPath<'static>; fn from_props( asset_path: Self::Props, context: &mut SchematicContext, ) -> Result<Self, SchematicError> { Ok(context.assets.load(asset_path)) } }
- 加入对场景的“reactivity”支持,基于 ECS 数据自动重新构建场景。这可大大简化 UI 的更新。示例: #[derive(Component, Clone, Schematic, Reflect, Default, Debug)] #[schematic(example)] #[reflect(Schematic)] pub struct Example { score_multiplier: Prop<u32>, } fn example(In(props): In<Example>, score: Res<Score>) -> Bsn { let score = score.0 * props.score_multiplier.get(); bsn! { Div [ Label { val: {format!("Score: {score}")} } ] } } fn setup() -> Bsn { bsn! { Div [ Example { score_multiplier: 2 } ] } }
- 增加热重载能力,无缝应用对资源场景文件的更改。
这次讨论提出了许多具有前瞻性的想法,希望能打造一个原生的、高效的、声明式的 UI 框架。这对 Bevy 而言无疑是一次重要的进化与革新。由于目前还处于早期探讨阶段,很多细节都有待进一步探索,需要社区中的小伙伴们一起思考和贡献力量,让 Bevy UI 系统变得更加完善和强大。
详见:https://github.com/bevyengine/bevy/discussions/9538 ↗
wtx - 最快的 WebSocket 实现
wtx 是一个用 Rust 实现的高性能 WebSocket 库。最近的基准测试显示,在多个指标上 wtx 都优于其他实现,可以称得上是最快的 WebSocket 库。
测试分为三个指标:
- 连接数量:衡量服务端处理连接请求的能力
- 消息数量:反映处理消息编解码和网络往返时间的能力
- 传输内存:检查不同 Payload 大小的吞吐量
结果显示 wtx 的响应时间最短,其次是 tokio-tungstenite 和 uWebSockets。这说明 Rust 的网络库在性能上依然保持领先。
详见:https://c410-f3r.github.io/thoughts/the-fastest-websocket-implementation/ ↗
clown - 捕获 Rust 闭包中的变量
GRDigital 最近发布了一个名为 clown 的项目,它能够捕获 Rust 闭包中的变量,并将其转换为一个等价的闭包形式。
clown 通过自定义的 clown 属性宏来实现这一功能。例如:
代码语言:javascript复制#[clown] || do_call(honk!(foo.bar))
会被转换为:
代码语言:javascript复制{
let __honk_0 = foo.bar.clone();
move || do_call(__honk_0)
}
这样就可以在闭包中访问 foo.bar 了。clown 目前还处在早期开发阶段,感兴趣的同学可以前去 GitHub 上 star 一下。
项目地址:https://github.com/GRDigital/clown ↗