This crate implements three extension traits that allow for conditional component, bundle and child insertion without the need for an intermediate EntityCommands
or EntityMut
binding.
ConditionalInsertBundleExt
forEntityCommands
andEntityMut
Methods:insert_if
insert_if_else
insert_some
insert_some_or
ConditionalChildBuilderExt
forEntityCommands
Methods:with_children_if
ConditionalWorldChildBuilderExt
forEntityMut
Methods:with_children_if
Supports Bevy 0.9
To add to a project either use:
cargo add conditional_commands
or manually add to your Cargo.toml:
[dependencies]
conditional_commands = "0.9.0"
use bevy::prelude::*;
use conditional_commands::*;
#[derive(Component)]
struct FizzBuzzer;
#[derive(Component)]
struct Number(usize);
#[derive(Component)]
struct Fizz;
#[derive(Component)]
struct Buzz;
fn fizz_buzz<const N: usize>(
mut commands: Commands
) {
for n in 1 ..= N {
let mut entity_commands = commands.spawn(FizzBuzzer);
match (n % 3, n % 5) {
(0, 0) => { entity_commands.insert((Fizz, Buzz)); },
(0, _) => { entity_commands.insert(Fizz); },
(_, 0) => { entity_commands.insert(Buzz); },
_ => { entity_commands.insert(Number(n)); }
}
}
}
With Conditional Commands the intermediate EntityCommands binding in no longer required.
fn fizz_buzz<const N: usize>(
mut commands: Commands
) {
for n in 1 ..= N {
commands
.spawn(FizzBuzzer)
.insert_if(0 < n % 3 && 0 < n % 5, || Number(n))
.insert_if(n % 3 == 0, || Fizz)
.insert_if(n % 5 == 0, || Buzz);
}
}
ConditionalInsertBundleExt
is also implemented for EntityMut
:
#[derive(Component)]
struct Even;
#[derive(Component)]
struct Odd;
fn exclusive_system(world: &mut World) {
for n in 0..10 {
world.spawn_empty().insert_if_else(n % 2 == 0, || Even, || Odd);
}
}
Bundles passed to the _else
/_or
methods don't need to be the same type,
as seen in the above example with the Even
and Odd
components.
Use insert_some
to insert the inner value of an optional bundle, if present.
commands.spawn(MyBundle)
.insert_some(Some(OtherBundle::default()))
.insert_some_or(None::<MyThing>, AlternativeThing::default);
cargo run --example exclusive
cargo run --example fizz_buzz
cargo run --example insert_if
cargo run --example insert_if_2
cargo run --example with_children_if
-
I haven't done any benchmarking. For performance critical systems it should be better to spawn entire bundles at once.
-
Earlier versions of this crate have both eager and lazy versions of each insertion method. I'm not sure the eager versions had any advantages (beyond no
||
), so they are gone. -
I wasn't able to quite finesse the lifetimes to get a single generic child builder trait for both
EntityCommands
andEntityMut
.