Crate bevy_query_ext
source ·Expand description
A collection of types used to simplify how components are used in queries, by implementing
bevy’s WorldQuery on generics.
Example of use
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>;Basic types
Our crate is composed of these basic types:
AsDeref<T>- Returns T dereferenced (a laDereftrait)AsDerefMut<T>- Returns T dereferenced (a laDerefMuttrait)Copied<T>- Returns T copied (a laCopytrait)Cloned<T>- Returns T cloned (a laClonetrait)OrDefault<T>- Returns T if the entity has this component, or its default (a laDefaulttrait)OrBool<T, const V: bool>,OrChar<T, const V: bool>,OrUsize<T, const V: usize>, etc. - Returns T.borrow() (a laBorrowtrait), or the constant provided if the entity does not have this component
You can use these basic types by themselves, but they are most useful composed with each other (except DerefMut).
There are type aliases for most valid compositions of these types. For example,
type AsDerefCopied<T> = Copied<AsDeref<T>>.
Note on limitations of composition
Because of the way WorldQuery works, in order to implement it, we need to know that the
lifetime for all parameters is “covariant,” or rather that if 'a : 'b then T<'a> : T<'b>.
For more information on variance, see here.
However, Rust’s associated types are assumed to be invariant, and there is no language feature
that allows us to enforce that the associated types are covariant types so even if we could get
around it with unsafe code we couldn’t restrict it to the proper types. This means we can’t
simply implement <T: WorldQuery> Copied<T>. However, thanks to the way Rust’s typing works,
we can manually implement composed types like Copied<AsDeref<T>> even with Copied<T> already implemented.
This crate attempts to manually implement all useful compositions of the types here, and to
indicate these with specialized type aliases. AsDerefCopiedOfClonedOrDefault is probably the
most egregious of these.
Bevy Compatibility
Since there can be breaking changes to our APIs we will have different versions for our code than the compatible bevy library, but we’ll list compatibility here.
| bevy | bevy_query_ext |
|---|---|
| 0.12 | 0.2 |
| 0.11 | 0.1 |
Feedback
Could the docs be clearer? Is a useful composition missing? Is there a type I haven’t considered? For any of these, please open an issue or PR on Github!
Modules
- Prelude module - Contains only the parts of the crate that are useful to consumers Everything in this module can also be imported from the crate directly, but you can import
bevy_query_ext::prelude::*overbevy_query_ext::*to avoid importing our internal modules.
Type Aliases
- Returns the dereferenced component
- Returns a clone of the dereferenced value (alias of
Cloned<AsDeref<T>>) - First either clones component T or gets the default value, then dereferences this value and clones it.
- Returns a copy of the dereferenced value (alias of
Copied<AsDeref<T>) - First either clones component T or gets the default value, then dereferences this value and copies it.
- First either copies component T or gets the default value, then dereferences this value and copies it.
- Returns the dereferenced component as a
Mut, or a reference if it is readonly. - When
TimplementsDereffor bool , this will return that value or the specified value if T has no result - When
TimplementsDereffor char , this will return that value or the specified value if T has no result - When
TimplementsDereffor i8 , this will return that value or the specified value if T has no result - When
TimplementsDereffor i16 , this will return that value or the specified value if T has no result - When
TimplementsDereffor i32 , this will return that value or the specified value if T has no result - When
TimplementsDereffor i64 , this will return that value or the specified value if T has no result - When
TimplementsDereffor i128 , this will return that value or the specified value if T has no result - When
TimplementsDereffor isize , this will return that value or the specified value if T has no result - When
TimplementsDereffor u8 , this will return that value or the specified value if T has no result - When
TimplementsDereffor u16 , this will return that value or the specified value if T has no result - When
TimplementsDereffor u32 , this will return that value or the specified value if T has no result - When
TimplementsDereffor u64 , this will return that value or the specified value if T has no result - When
TimplementsDereffor u128 , this will return that value or the specified value if T has no result - When
TimplementsDereffor usize , this will return that value or the specified value if T has no result - Clones a type when it is retrieved
- Copies a type when it is retrieved
- When
TimplementsBorrowforbool, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrBoolfor example of its use. - When
TimplementsBorrowforchar, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrCharfor example of its use. - If the query exists on the entity it is returned, or else the default for the query result
- When
TimplementsBorrowfori8, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrI8for example of its use. - When
TimplementsBorrowfori16, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrI16for example of its use. - When
TimplementsBorrowfori32, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrI32for example of its use. - When
TimplementsBorrowfori64, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrI64for example of its use. - When
TimplementsBorrowfori128, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrI128for example of its use. - When
TimplementsBorrowforisize, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrIsizefor example of its use. - When
TimplementsBorrowforu8, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrU8for example of its use. - When
TimplementsBorrowforu16, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrU16for example of its use. - When
TimplementsBorrowforu32, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrU32for example of its use. - When
TimplementsBorrowforu64, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrU64for example of its use. - When
TimplementsBorrowforu128, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrU128for example of its use. - When
TimplementsBorrowforusize, this will return that value or the specified value if T has no result. It’s unlikely you’ll use this by itself, seeAsDerefOrUsizefor example of its use.