8个不稳定版本 (3个重大更改)
0.4.0 | 2024年7月4日 |
---|---|
0.4.0-rc.3 | 2024年6月17日 |
0.3.0 | 2024年2月18日 |
0.2.0 | 2023年11月6日 |
0.1.1 | 2023年8月19日 |
#13 in #bevy-ecs
每月 80 次下载
40KB
376 代码行
通过在泛型上实现Bevy的QueryData
,收集了一组用于简化查询中组件使用类型的类型。
使用示例
use bevy::prelude::*;
use std::ops::Deref;
use bevy_query_ext::AsDerefOrU32;
// Component which indicates ammo left in a weapon
// A weapon with an ammo component can't be used if ammo is 0
// A weapon with no ammo component, like a knife, can be used
#[derive(Component, Deref)]
struct Ammo(u32);
fn identify_usable_weapons_1(weapons: Query<(&Name, Option<&Ammo>)>) {
for (name, ammo_count) in weapons.iter() {
if ammo_count.map(|ammo_count|*ammo_count.deref()).unwrap_or(1) > 0 {
println!("{:?} can be used!", name)
}
}
}
// AsDerefOrU32<T, V> is a type alias for OrU32<AsDeref<T>, V>
fn identify_usable_weapons_2(weapons: Query<(&Name, AsDerefOrU32<Ammo, 1>)>) {
for (name, ammo_count) in weapons.iter() {
if ammo_count > 0 {
println!("{:?} can be used!", name)
}
}
}
// If you find yourself reusing a type in the same way across multiple systems, just use a type
// alias for it and you can use it like that in code.
type AmmoCount = AsDerefOrU32<Ammo, 1>;
基本类型
我们的crate由以下基本类型组成
AsDeref<T>
- 返回T的解引用(类似于Deref
特质)AsDerefMut<T>
- 返回T的解引用(类似于DerefMut
特质)Copied<T>
- 返回T的副本(类似于Copy
特质)Cloned<T>
- 返回T的克隆副本(类似于Clone
特质)OrDefault<T>
- 如果实体有此组件,则返回T,否则返回其默认值(类似于Default
特质)OrBool<T, const V: bool>
、OrChar<T, const V: bool>
、OrUsize<T, const V: usize>
等等 - 返回 T.borrow()(类似于Borrow
特性),如果没有这个组件,则返回提供的常量
您可以直接使用这些基本类型,但将它们组合使用时最为有用(除了 DerefMut
)。大多数这些类型的有效组合都有类型别名。例如,type AsDerefCopied<T> = Copied<AsDeref<T>>
。
有关析构函数和实体组件的说明
作者常见的一个用例是拥有引用实体组件。但在长元组查询中使用 AsDerefCopied
可能会导致实体混淆,因为它们不再有类型保护。在这些情况下,最好将这些引用字段设为公共的,并在可能的情况下使用解构赋值。例如,如果您的组件是 pub struct PointsTo(Entity)
,您可以使用类似 for (&PointsTo(points_to), <..>) = query.iter()
的方式来获取值。
这也不会影响具有命名字段的派生查询。
关于组合限制的说明
由于 QueryData 的工作方式,为了实现它,我们需要知道所有参数的生命周期是“协变的”,或者说如果 'a : 'b
,那么 T<'a> : T<'b>
。
有关变元的更多信息,请参阅这里。
然而,Rust 的关联类型被认为是不可变的,并且没有语言特性允许我们强制关联类型是协变类型,因此即使我们能够通过 unsafe 代码绕过它,也无法将其限制到正确的类型。这意味着我们无法简单地实现 <T: QueryData> Copied<T>
。然而,由于 Rust 的类型工作方式,我们可以手动实现组合类型,如 Copied<AsDeref<T>>
,即使 Copied<T>
已经实现。
这个软件包试图手动实现这里所有有用的类型组合,并使用专门的类型别名来表示。AsDerefCopiedOfClonedOrDefault
可能是这些中最引人注目的。
Bevy 兼容性
由于我们的 API 可能会有破坏性更改,因此我们的代码将不同于兼容的 bevy 库,但我们将在此处列出兼容性。
bevy | bevy_query_ext |
---|---|
0.14.0-rc.2 | 0.4.0-rc.2 |
0.13 | 0.3 |
0.12 | 0.2 |
0.11 | 0.1 |
反馈
文档是否可以更清晰?是否有遗漏的有用组合?是否有我没有考虑到的类型?对于任何这些问题,请在 Github 上打开一个问题或 PR!
依赖
~23MB
~413K SLoC