# Conditional Commands 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``` for ```EntityCommands``` and ```EntityMut```\ Methods: - ```insert_if``` - ```insert_if_else``` - ```insert_some``` - ```insert_some_or``` * ```ConditionalChildBuilderExt``` for ```EntityCommands```\ Methods: - ```with_children_if``` * ```ConditionalWorldChildBuilderExt``` for ```EntityMut```\ Methods: - ```with_children_if``` Supports Bevy 0.9 # ## Usage To add to a project either use: ``` cargo add conditional_commands ``` or manually add to your Cargo.toml: ```toml [dependencies] conditional_commands = "0.9.0" ``` ## A Motivating But Contrived ECS Fizz-Buzz Example ```rust 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( 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. ```rust fn fizz_buzz( 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`: ```rust #[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. ```rust commands.spawn(MyBundle) .insert_some(Some(OtherBundle::default())) .insert_some_or(None::, AlternativeThing::default); ``` ## Examples ``` 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 ``` # ## Notes * 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``` and ```EntityMut```.