7 releases
0.2.6 | Nov 30, 2024 |
---|---|
0.2.5 | Jul 21, 2024 |
0.2.3 | May 4, 2024 |
0.2.0 | Mar 11, 2024 |
0.1.0 | Mar 9, 2024 |
#1696 in Game dev
314 downloads per month
Used in 11 crates
(6 directly)
31KB
491 lines
🛠️ Moonshine Utilities
Collection of utilities for Bevy.
Features
Expect<T>
A decorator for QueryData
which panics if it doesn't match.
This helps avoid silent failures in systems due to missing components:
use bevy::prelude::*;
use moonshine_util::expect::Expect;
#[derive(Component)]
struct A;
#[derive(Component)]
struct B;
#[derive(Bundle)]
struct AB {
a: A, // Every `A` is expected to have a `B`
b: B,
}
fn bad_system(mut commands: Commands) {
commands.spawn(A); // BUG: Spawn A witout B!
}
fn unsafe_system(mut query: Query<(&A, &B)>) {
for (a, b) in query.iter() {
// An instance of `A` does exist, but this system skips over it silently!
}
}
fn safe_system(mut query: Query<(&A, Expect<&B>)>) {
for (a, b) in query.iter() {
// This system will panic if an `A` instance is missing a `B`!
}
}
HierarchyQuery
A convenient SystemParam
for traversing and querying entity hierarchies:
use bevy::prelude::*;
use moonshine_util::hierarchy::HierarchyQuery;
#[derive(Component)]
struct Needle;
#[derive(Component)]
struct Haystack;
fn spawn_haystack(mut commands: Commands) {
// A complex hierarchy ...
commands.spawn(Haystack).with_children(|x| {
x.spawn_empty().with_children(|y| {
y.spawn_empty().with_children(|z| {
z.spawn(Needle);
});
});
});
}
fn find_needle(
haystack: Query<Entity, With<Haystack>>,
needle_query: Query<Entity, With<Needle>>,
hierarchy: HierarchyQuery
) {
let haystack = haystack.single();
for needle in hierarchy.descendants_deep(haystack) {
// ...
}
}
Some useful functions include:
fn parent(&self, Entity) -> Option<Entity>
fn has_parent(&self, Entity) -> bool
fn children(&self, Entity) -> Iterator<Item = Entity>
fn has_children(&self, Entity) -> bool
fn root(&self, Entity) -> Entity
fn is_root(&self, Entity) -> bool
fn ancestors(&self, Entity) -> Iterator<Item = Entity>
fn descendants(&self, Entity) -> Iterator<Item = Entity>
fn is_ancestor_of(&self, Entity, Entity) -> bool
fn is_descendant_of(&self, Entity, Entity) -> bool
fn find_ancestor<T, F>(&self, Entity, &Query<T, F>) -> Option<QueryItem<T>>
fn find_descendant<T, F>(&self, Entity, &Query<T, F>) -> Option<QueryItem<T>>
See code documentation for complete details.
RunSystemLoop
A trait similar to RunSystemOnce
which allows you to run a system loop for testing purposes:
use bevy::prelude::*;
use moonshine_util::diagnostics::RunSystemLoop;
let mut world = World::new();
let outputs = world.run_system_loop(2, |mut commands: Commands| {
commands.spawn_empty().id()
});
assert_eq!(outputs.len(), 2);
assert!(world.get_entity(outputs[0]).is_ok());
assert!(world.get_entity(outputs[1]).is_ok());
Utility Systems
A collection of simple and generic systems useful for constructing larger system pipelines:
has_event<T: Event>() -> bool
has_resource<T: Resource>() -> bool
remove_resource<T: Resource>(Commands)
remove_resource_immediate<T: Resource>(&mut World)
See code documentation for usage examples.
Support
Please post an issue for any bugs, questions, or suggestions.
You may also contact me on the official Bevy Discord server as @Zeenobit.
Dependencies
~10–19MB
~253K SLoC