From 853af821e04920ad36fc787a2735dc9c36ef2992 Mon Sep 17 00:00:00 2001 From: Utkarsh Date: Wed, 21 Oct 2020 07:06:09 +0530 Subject: [PATCH] Simplify gamepad_input example and refactor bevy_input::gamepad --- crates/bevy_gilrs/src/lib.rs | 5 +- crates/bevy_input/src/gamepad.rs | 88 ++++++++++++------------- crates/bevy_input/src/lib.rs | 5 +- examples/input/gamepad_input.rs | 110 ++++++++----------------------- 4 files changed, 76 insertions(+), 132 deletions(-) diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index 475b156908a58..99f803f50fa3f 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -18,10 +18,7 @@ impl Plugin for GilrsPlugin { { Ok(gilrs) => { app.add_thread_local_resource(gilrs) - .add_startup_system_to_stage( - bevy_app::startup_stage::STARTUP, - gilrs_event_startup_system.thread_local_system(), - ) + .add_startup_system(gilrs_event_startup_system.thread_local_system()) .add_system_to_stage(stage::FIRST, girls_event_system.thread_local_system()); } Err(err) => log::error!("Failed to start Gilrs. {}", err), diff --git a/crates/bevy_input/src/gamepad.rs b/crates/bevy_input/src/gamepad.rs index 8bfa00a973509..bd416935987c5 100644 --- a/crates/bevy_input/src/gamepad.rs +++ b/crates/bevy_input/src/gamepad.rs @@ -66,51 +66,51 @@ pub enum GamepadAxisType { pub struct GamepadAxis(pub Gamepad, pub GamepadAxisType); #[derive(Default, Debug)] -pub struct GamepadProperty { - pub default_button_property: ButtonProperty, - pub default_axis_property: AxisProperty, - pub default_button_axis_property: ButtonAxisProperty, - pub button_properties: HashMap, - pub axis_properties: HashMap, - pub button_axis_properties: HashMap, +pub struct GamepadSetting { + pub default_button_setting: ButtonSetting, + pub default_axis_setting: AxisSetting, + pub default_button_axis_setting: ButtonAxisSetting, + pub button_settings: HashMap, + pub axis_settings: HashMap, + pub button_axis_settings: HashMap, } -impl GamepadProperty { - pub fn get_button_properties(&self, button: GamepadButton) -> &ButtonProperty { - self.button_properties +impl GamepadSetting { + pub fn get_button_setting(&self, button: GamepadButton) -> &ButtonSetting { + self.button_settings .get(&button) - .unwrap_or(&self.default_button_property) + .unwrap_or(&self.default_button_setting) } - pub fn get_axis_properties(&self, axis: GamepadAxis) -> &AxisProperty { - self.axis_properties + pub fn get_axis_setting(&self, axis: GamepadAxis) -> &AxisSetting { + self.axis_settings .get(&axis) - .unwrap_or(&self.default_axis_property) + .unwrap_or(&self.default_axis_setting) } - pub fn get_button_axis_properties(&self, button: GamepadButton) -> &ButtonAxisProperty { - self.button_axis_properties + pub fn get_button_axis_setting(&self, button: GamepadButton) -> &ButtonAxisSetting { + self.button_axis_settings .get(&button) - .unwrap_or(&self.default_button_axis_property) + .unwrap_or(&self.default_button_axis_setting) } } #[derive(Debug, Clone)] -pub struct ButtonProperty { +pub struct ButtonSetting { pub press: f32, pub release: f32, } -impl Default for ButtonProperty { +impl Default for ButtonSetting { fn default() -> Self { - ButtonProperty { + ButtonSetting { press: 0.75, release: 0.65, } } } -impl ButtonProperty { +impl ButtonSetting { fn is_pressed(&self, value: f32) -> bool { value >= self.press } @@ -121,7 +121,7 @@ impl ButtonProperty { } #[derive(Debug, Clone)] -pub struct AxisProperty { +pub struct AxisSetting { pub positive_high: f32, pub positive_low: f32, pub negative_high: f32, @@ -129,9 +129,9 @@ pub struct AxisProperty { pub threshold: f32, } -impl Default for AxisProperty { +impl Default for AxisSetting { fn default() -> Self { - AxisProperty { + AxisSetting { positive_high: 0.95, positive_low: 0.05, negative_high: -0.95, @@ -141,7 +141,7 @@ impl Default for AxisProperty { } } -impl AxisProperty { +impl AxisSetting { fn filter(&self, new_value: f32, old_value: Option) -> f32 { if let Some(old_value) = old_value { if (new_value - old_value).abs() <= self.threshold { @@ -162,15 +162,15 @@ impl AxisProperty { } #[derive(Debug, Clone)] -pub struct ButtonAxisProperty { +pub struct ButtonAxisSetting { pub high: f32, pub low: f32, pub threshold: f32, } -impl Default for ButtonAxisProperty { +impl Default for ButtonAxisSetting { fn default() -> Self { - ButtonAxisProperty { + ButtonAxisSetting { high: 0.95, low: 0.05, threshold: 0.01, @@ -178,7 +178,7 @@ impl Default for ButtonAxisProperty { } } -impl ButtonAxisProperty { +impl ButtonAxisSetting { fn filter(&self, new_value: f32, old_value: Option) -> f32 { if let Some(old_value) = old_value { if (new_value - old_value).abs() <= self.threshold { @@ -202,20 +202,20 @@ pub struct GamepadEventState { pub fn gamepad_event_system( mut state: Local, - mut button: ResMut>, + mut button_input: ResMut>, mut axis: ResMut>, mut button_axis: ResMut>, - event: Res>, - properties: Res, + events: Res>, + settings: Res, ) { - button.update(); - for event in state.gamepad_event_reader.iter(&event) { + button_input.update(); + for event in state.gamepad_event_reader.iter(&events) { let (gamepad, event) = (&event.0, &event.1); match event { GamepadEventType::Connected => { for button_type in ALL_BUTTON_TYPES.iter() { let gamepad_button = GamepadButton(*gamepad, *button_type); - button.reset(gamepad_button); + button_input.reset(gamepad_button); button_axis.set(gamepad_button, 0.0); } for axis_type in ALL_AXIS_TYPES.iter() { @@ -225,7 +225,7 @@ pub fn gamepad_event_system( GamepadEventType::Disconnected => { for button_type in ALL_BUTTON_TYPES.iter() { let gamepad_button = GamepadButton(*gamepad, *button_type); - button.reset(gamepad_button); + button_input.reset(gamepad_button); button_axis.remove(gamepad_button); } for axis_type in ALL_AXIS_TYPES.iter() { @@ -234,25 +234,25 @@ pub fn gamepad_event_system( } GamepadEventType::AxisChanged(axis_type, value) => { let gamepad_axis = GamepadAxis(*gamepad, *axis_type); - let value = properties - .get_axis_properties(gamepad_axis) + let value = settings + .get_axis_setting(gamepad_axis) .filter(*value, axis.get(gamepad_axis)); axis.set(gamepad_axis, value); } GamepadEventType::ButtonChanged(button_type, value) => { let gamepad_button = GamepadButton(*gamepad, *button_type); - let filtered_value = properties - .get_button_axis_properties(gamepad_button) + let filtered_value = settings + .get_button_axis_setting(gamepad_button) .filter(*value, button_axis.get(gamepad_button)); button_axis.set(gamepad_button, filtered_value); - let button_property = properties.get_button_properties(gamepad_button); - if button.pressed(gamepad_button) { + let button_property = settings.get_button_setting(gamepad_button); + if button_input.pressed(gamepad_button) { if button_property.is_released(*value) { - button.release(gamepad_button); + button_input.release(gamepad_button); } } else if button_property.is_pressed(*value) { - button.press(gamepad_button); + button_input.press(gamepad_button); } } } diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index cd215ac8fc737..6c528c2dda28c 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -27,7 +27,7 @@ use mouse::{mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotio use touch::{touch_screen_input_system, TouchInput, Touches}; use bevy_ecs::IntoQuerySystem; -use gamepad::{gamepad_event_system, GamepadAxis, GamepadButton, GamepadEvent, GamepadProperty}; +use gamepad::{gamepad_event_system, GamepadAxis, GamepadButton, GamepadEvent, GamepadSetting}; /// Adds keyboard and mouse input to an App #[derive(Default)] @@ -50,7 +50,7 @@ impl Plugin for InputPlugin { mouse_button_input_system.system(), ) .add_event::() - .init_resource::() + .init_resource::() .init_resource::>() .init_resource::>() .init_resource::>() @@ -59,7 +59,6 @@ impl Plugin for InputPlugin { gamepad_event_system.system(), ) .add_system_to_stage(bevy_app::stage::EVENT_UPDATE, gamepad_event_system.system()) - .init_resource::>() .add_event::() .init_resource::() .add_system_to_stage( diff --git a/examples/input/gamepad_input.rs b/examples/input/gamepad_input.rs index c1fd62c378503..768f90b358211 100644 --- a/examples/input/gamepad_input.rs +++ b/examples/input/gamepad_input.rs @@ -1,16 +1,14 @@ use bevy::prelude::*; use bevy_input::gamepad::{Gamepad, GamepadButton, GamepadEvent, GamepadEventType}; -use bevy_utils::{HashMap, HashSet}; +use bevy_utils::HashSet; fn main() { App::build() .add_default_plugins() .init_resource::() - .init_resource::() .add_startup_system(connection_system.system()) .add_system(connection_system.system()) - .add_system(button_system.system()) - .add_system(axis_system.system()) + .add_system(gamepad_system.system()) .run(); } @@ -20,12 +18,6 @@ struct GamepadLobby { gamepad_event_reader: EventReader, } -#[derive(Default)] -struct GamepadData { - axis: HashMap, - button: HashMap, -} - fn connection_system(mut lobby: ResMut, gamepad_event: Res>) { for event in lobby.gamepad_event_reader.iter(&gamepad_event) { match &event { @@ -42,82 +34,38 @@ fn connection_system(mut lobby: ResMut, gamepad_event: Res, - inputs: Res>, + button_inputs: Res>, button_axes: Res>, - mut data: ResMut, -) { - let button_types = [ - GamepadButtonType::South, - GamepadButtonType::East, - GamepadButtonType::North, - GamepadButtonType::West, - GamepadButtonType::C, - GamepadButtonType::Z, - GamepadButtonType::LeftTrigger, - GamepadButtonType::LeftTrigger2, - GamepadButtonType::RightTrigger, - GamepadButtonType::RightTrigger2, - GamepadButtonType::Select, - GamepadButtonType::Start, - GamepadButtonType::Mode, - GamepadButtonType::LeftThumb, - GamepadButtonType::RightThumb, - GamepadButtonType::DPadUp, - GamepadButtonType::DPadDown, - GamepadButtonType::DPadLeft, - GamepadButtonType::DPadRight, - ]; - for gamepad in lobby.gamepads.iter() { - for button_type in button_types.iter() { - let gamepad_button = GamepadButton(*gamepad, *button_type); - if inputs.just_pressed(gamepad_button) { - println!("{:?} Pressed", gamepad_button); - } else if inputs.just_released(GamepadButton(*gamepad, *button_type)) { - println!("{:?} Released", gamepad_button); - } - if let Some(value) = button_axes.get(gamepad_button) { - if !approx_eq( - data.button.get(&gamepad_button).copied().unwrap_or(0.0), - value, - ) { - data.button.insert(gamepad_button, value); - println!("{:?} is {}", gamepad_button, value); - } - } - } - } -} - -fn axis_system( - lobby: Res, axes: Res>, - mut data: ResMut, ) { - let axis_types = [ - GamepadAxisType::LeftStickX, - GamepadAxisType::LeftStickY, - GamepadAxisType::LeftZ, - GamepadAxisType::RightStickX, - GamepadAxisType::RightStickY, - GamepadAxisType::RightZ, - GamepadAxisType::DPadX, - GamepadAxisType::DPadY, - ]; for gamepad in lobby.gamepads.iter() { - for axis_type in axis_types.iter() { - let gamepad_axis = GamepadAxis(*gamepad, *axis_type); - if let Some(value) = axes.get(gamepad_axis) { - if !approx_eq(data.axis.get(&gamepad_axis).copied().unwrap_or(0.0), value) { - data.axis.insert(gamepad_axis, value); - println!("{:?} is {}", gamepad_axis, value); - } - } + let south_button = GamepadButton(*gamepad, GamepadButtonType::South); + if button_inputs.just_pressed(south_button) { + println!( + "{:?} of {:?} is just pressed", + GamepadButtonType::South, + gamepad + ); + } else if button_inputs.just_released(south_button) { + println!( + "{:?} of {:?} is just released", + GamepadButtonType::South, + gamepad + ); } - } -} -fn approx_eq(a: f32, b: f32) -> bool { - (a - b).abs() < f32::EPSILON + println!( + "For {:?}: {:?} is {:.4}, {:?} is {:.4}", + gamepad, + GamepadButtonType::RightTrigger2, + button_axes + .get(GamepadButton(*gamepad, GamepadButtonType::RightTrigger2)) + .unwrap_or(0.0), + GamepadAxisType::LeftStickX, + axes.get(GamepadAxis(*gamepad, GamepadAxisType::LeftStickX)) + .unwrap_or(0.0) + ) + } }