bevy_ergo_plugin 0.2.1

Macros to make building bevy plugins more ergonomic
Documentation
# bevy_ergo_plugin

Macros to make building bevy plugins more ergonomic (in my opinion).\
\
Bevy's API puts adding a system separate from its implementation. Separatng the system's run conditions and other system parameters from its definition adds an extra layer of indirection, harming readability and adding boilerplate (`.add_system`)\
This crate's purpose is to replace that API with a more ergonomic one, using attribute macros as markers for system parameters.\
\
Putting the `bevy_plugin` attribute on the `impl` block of a struct will turn that struct into a Bevy Plugin, which registers its associated functions as systems.\
If you want to add extra functionality to your plugin's `Plugin::build` (like adding an asset or registering a component), the contents of any associated function named `build` in a `bevy_plugin` attributed impl block will be inserted into the generated `Plugin::build` implementation.\
\
The other macros are the aforementioned parameter markers to be put on your system definitions.\
For any params not included by a specific marker, you can use the `sysparam` marker to define custom behavior.\
\
Multiple parameter markers on a system do stack onto a single `add_system` call, so you can add multiple run conditions and have it work as expected.
\
**This crate has not been thoroughly tested, so there will probably be weird bugs I don't know about.**
## Example
adapted from <https://github.com/bevyengine/bevy/blob/latest/examples/ecs/run_conditions.rs>\

    use bevy::prelude::*;
    use bevy_ergo_plugin::*;
 
    fn main() {
        println!();
        println!("For the first 2 seconds you will not be able to increment the counter");
        println!("Once that time has passed you can press space, enter, left mouse, right mouse or touch the screen to increment the counter");
        println!();
 
        App::new()
            .add_plugins(DefaultPlugins)
            .add_plugin(Game)
            .run();
    }
    #[derive(Resource, Default)]
    pub struct InputCounter(usize);
 
    pub struct Game;
    #[bevy_plugin]
    impl Game {
        #[run_if(resource_exists::<InputCounter>())]
        #[run_if(Game::has_user_input)]
        pub fn increment_input_counter(mut counter: ResMut<InputCounter>) {
            counter.0 += 1;
        }
 
        #[run_if(resource_exists::<InputCounter>().and_then(
            |counter: Res<InputCounter>| counter.is_changed() && !counter.is_added()
        ))]
        pub fn print_input_counter(counter: Res<InputCounter>) {
            println!("Input counter: {}", counter.0);
        }
 
        #[run_if(Game::time_passed(2.0))]
        #[run_if(not(Game::time_passed(2.5)))]
        pub fn print_time_message() {
            println!(
                "It has been more than 2 seconds since the program started and less than 2.5 seconds"
            );
        }
 
        #[do_not_add]
        pub fn has_user_input(
            keyboard_input: Res<Input<KeyCode>>,
            mouse_button_input: Res<Input<MouseButton>>,
            touch_input: Res<Touches>,
        ) -> bool {
            keyboard_input.just_pressed(KeyCode::Space)
                || keyboard_input.just_pressed(KeyCode::Return)
                || mouse_button_input.just_pressed(MouseButton::Left)
                || mouse_button_input.just_pressed(MouseButton::Right)
                || touch_input.any_just_pressed()
        }
 
        #[do_not_add]
        pub fn time_passed(t: f32) -> impl FnMut(Local<f32>, Res<Time>) -> bool {
            move |mut timer: Local<f32>, time: Res<Time>| {
                *timer += time.delta_seconds();
                *timer >= t
            }
        }
 
        pub fn build(&self, app: &mut App) {
            app.init_resource::<InputCounter>();
        }
    }