From 42e1a3d0e788ebd9c31a5eda7e75925d5bcbb17b Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 24 Feb 2023 13:27:21 +0100 Subject: [PATCH] add common run conditions to bevy_input --- crates/bevy_input/Cargo.toml | 3 + crates/bevy_input/src/common_conditions.rs | 97 ++++++++++++++++++++++ crates/bevy_input/src/lib.rs | 2 + 3 files changed, 102 insertions(+) create mode 100644 crates/bevy_input/src/common_conditions.rs diff --git a/crates/bevy_input/Cargo.toml b/crates/bevy_input/Cargo.toml index 4dcb1ea340e72..28e741fe61477 100644 --- a/crates/bevy_input/Cargo.toml +++ b/crates/bevy_input/Cargo.toml @@ -23,3 +23,6 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.9.0", features = ["glam" # other serde = { version = "1", features = ["derive"], optional = true } thiserror = "1.0" + +[dev-dependencies] +bevy = { path = "../../", version = "0.9.0" } diff --git a/crates/bevy_input/src/common_conditions.rs b/crates/bevy_input/src/common_conditions.rs new file mode 100644 index 0000000000000..efae7a5837636 --- /dev/null +++ b/crates/bevy_input/src/common_conditions.rs @@ -0,0 +1,97 @@ +use crate::Input; +use bevy_ecs::system::Res; +use std::hash::Hash; + +/// Stateful run condition that can be toggled via a input press using [`Input::just_pressed`]. +/// +/// ```rust,no_run +/// use bevy::prelude::*; +/// use bevy::input::common_conditions::input_toggle_active; +/// +/// fn main() { +/// App::new() +/// .add_plugins(DefaultPlugins) +/// .add_system(pause_menu.run_if(input_toggle_active(false, KeyCode::Escape))) +/// .run(); +/// } +/// +/// fn pause_menu() { +/// println!("in pause menu"); +/// } +/// ``` +/// +/// If you want other system to be able to access whether the toggled state is active, +/// you should use a custom resource or a state for that: +/// ```rust,no_run +/// use bevy::prelude::*; +/// use bevy::input::common_conditions::input_toggle_active; +/// +/// #[derive(Resource, Default)] +/// struct Paused(bool); +/// +/// fn main() { +/// App::new() +/// .add_plugins(DefaultPlugins) +/// .init_resource::() +/// .add_system(pause_menu.run_if(|paused: Res| paused.0)) +/// .run(); +/// } +/// +/// fn update_pause_state(mut paused: ResMut, input: Input) { +/// if input.just_pressed(KeyCode::Escape) { +/// paused.0 = !paused.0; +/// } +/// } +/// +/// fn pause_menu() { +/// println!("in pause menu"); +/// } +/// +/// ``` +pub fn input_toggle_active(default: bool, input: T) -> impl FnMut(Res>) -> bool +where + T: Copy + Eq + Hash + Send + Sync + 'static, +{ + let mut active = default; + move |inputs: Res>| { + active ^= inputs.just_pressed(input); + active + } +} + +/// Run condition that is active if [`Input::pressed`] is true for the given input. +pub fn input_pressed(input: T) -> impl FnMut(Res>) -> bool +where + T: Copy + Eq + Hash + Send + Sync + 'static, +{ + move |inputs: Res>| inputs.pressed(input) +} + +/// Run condition that is active if [`Input::just_pressed`] is true for the given input. +/// +/// ```rust,no_run +/// use bevy::prelude::*; +/// use bevy::input::common_conditions::input_just_pressed; +/// fn main() { +/// App::new() +/// .add_plugins(DefaultPlugins) +/// .add_system(jump.run_if(input_just_pressed(KeyCode::Space))) +/// .run(); +/// } +/// +/// # fn jump() {} +/// ``` +pub fn input_just_pressed(input: T) -> impl FnMut(Res>) -> bool +where + T: Copy + Eq + Hash + Send + Sync + 'static, +{ + move |inputs: Res>| inputs.just_pressed(input) +} + +/// Run condition that is active if [`Input::just_released`] is true for the given input. +pub fn input_just_released(input: T) -> impl FnMut(Res>) -> bool +where + T: Copy + Eq + Hash + Send + Sync + 'static, +{ + move |inputs: Res>| inputs.just_released(input) +} diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index cbf4bf0e7c660..7fc988171cf56 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -1,4 +1,6 @@ mod axis; +/// Common run conditions +pub mod common_conditions; pub mod gamepad; mod input; pub mod keyboard;