From fb2b19def5f4720250d128126a57d6ee9fc9af58 Mon Sep 17 00:00:00 2001 From: Utkarsh <37181756+simpuid@users.noreply.github.com> Date: Fri, 30 Oct 2020 02:25:35 +0530 Subject: [PATCH] Fix bug of connection event of gamepad at startup (#730) * Removed f32==f32 comparision in gamepad.rs * Trigger gamepad connection event at start up --- crates/bevy_gilrs/src/gilrs_system.rs | 11 ++++ crates/bevy_gilrs/src/lib.rs | 9 ++-- crates/bevy_input/src/gamepad.rs | 75 ++++++++++----------------- crates/bevy_input/src/lib.rs | 2 + examples/input/gamepad_input.rs | 3 +- 5 files changed, 48 insertions(+), 52 deletions(-) diff --git a/crates/bevy_gilrs/src/gilrs_system.rs b/crates/bevy_gilrs/src/gilrs_system.rs index ef03d7fc75..3a6164c050 100644 --- a/crates/bevy_gilrs/src/gilrs_system.rs +++ b/crates/bevy_gilrs/src/gilrs_system.rs @@ -4,6 +4,17 @@ use bevy_ecs::{Resources, World}; use bevy_input::{gamepad::GamepadEventRaw, prelude::*}; use gilrs::{EventType, Gilrs}; +pub fn gilrs_event_startup_system(_world: &mut World, resources: &mut Resources) { + let gilrs = resources.get_thread_local::().unwrap(); + let mut event = resources.get_mut::>().unwrap(); + for (id, _) in gilrs.gamepads() { + event.send(GamepadEventRaw( + convert_gamepad_id(id), + GamepadEventType::Connected, + )); + } +} + pub fn gilrs_event_system(_world: &mut World, resources: &mut Resources) { let mut gilrs = resources.get_thread_local_mut::().unwrap(); let mut event = resources.get_mut::>().unwrap(); diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index 350814f0d0..cc0113c09f 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -1,10 +1,10 @@ mod converter; mod gilrs_system; -use bevy_app::prelude::*; +use bevy_app::{prelude::*, startup_stage::PRE_STARTUP}; use bevy_ecs::prelude::*; use gilrs::GilrsBuilder; -use gilrs_system::gilrs_event_system; +use gilrs_system::{gilrs_event_startup_system, gilrs_event_system}; #[derive(Default)] pub struct GilrsPlugin; @@ -18,7 +18,10 @@ impl Plugin for GilrsPlugin { { Ok(gilrs) => { app.add_thread_local_resource(gilrs) - .add_startup_system(gilrs_event_system.thread_local_system()) + .add_startup_system_to_stage( + PRE_STARTUP, + gilrs_event_startup_system.thread_local_system(), + ) .add_system_to_stage( stage::PRE_EVENT, gilrs_event_system.thread_local_system(), diff --git a/crates/bevy_input/src/gamepad.rs b/crates/bevy_input/src/gamepad.rs index 59ac6b0f8d..c3707e6642 100644 --- a/crates/bevy_input/src/gamepad.rs +++ b/crates/bevy_input/src/gamepad.rs @@ -146,22 +146,22 @@ impl Default for AxisSettings { } impl AxisSettings { - fn filter(&self, new_value: f32, old_value: Option) -> f32 { + fn filter(&self, new_value: f32, old_value: Option) -> Option { if let Some(old_value) = old_value { if (new_value - old_value).abs() <= self.threshold { - return old_value; + return None; } } if new_value <= self.positive_low && new_value >= self.negative_low { - return 0.0; + return Some(0.0); } if new_value >= self.positive_high { - return 1.0; + return Some(1.0); } if new_value <= self.negative_high { - return -1.0; + return Some(-1.0); } - new_value + Some(new_value) } } @@ -183,23 +183,22 @@ impl Default for ButtonAxisSettings { } impl ButtonAxisSettings { - fn filter(&self, new_value: f32, old_value: Option) -> f32 { + fn filter(&self, new_value: f32, old_value: Option) -> Option { if let Some(old_value) = old_value { if (new_value - old_value).abs() <= self.threshold { - return old_value; + return None; } } if new_value <= self.low { - return 0.0; + return Some(0.0); } if new_value >= self.high { - return 1.0; + return Some(1.0); } - new_value + Some(new_value) } } -#[allow(clippy::float_cmp)] pub fn gamepad_event_system( mut event_reader: Local>, mut button_input: ResMut>, @@ -237,33 +236,29 @@ pub fn gamepad_event_system( } GamepadEventType::AxisChanged(axis_type, value) => { let gamepad_axis = GamepadAxis(gamepad, *axis_type); - let old_value = axis.get(gamepad_axis); - let filtered_value = settings + if let Some(filtered_value) = settings .get_axis_settings(gamepad_axis) - .filter(*value, old_value); - axis.set(gamepad_axis, filtered_value); - - // only send event if axis has changed after going through filters - if let Some(old_value) = old_value { - if old_value == filtered_value { - return; - } - } else if filtered_value == 0.0 { - return; + .filter(*value, axis.get(gamepad_axis)) + { + axis.set(gamepad_axis, filtered_value); + events.send(GamepadEvent( + gamepad, + GamepadEventType::AxisChanged(*axis_type, filtered_value), + )) } - - events.send(GamepadEvent( - gamepad, - GamepadEventType::AxisChanged(*axis_type, filtered_value), - )) } GamepadEventType::ButtonChanged(button_type, value) => { let gamepad_button = GamepadButton(gamepad, *button_type); - let old_value = button_axis.get(gamepad_button); - let filtered_value = settings + if let Some(filtered_value) = settings .get_button_axis_settings(gamepad_button) - .filter(*value, old_value); - button_axis.set(gamepad_button, filtered_value); + .filter(*value, button_axis.get(gamepad_button)) + { + button_axis.set(gamepad_button, filtered_value); + events.send(GamepadEvent( + gamepad, + GamepadEventType::ButtonChanged(*button_type, filtered_value), + )) + } let button_property = settings.get_button_settings(gamepad_button); if button_input.pressed(gamepad_button) { @@ -273,20 +268,6 @@ pub fn gamepad_event_system( } else if button_property.is_pressed(*value) { button_input.press(gamepad_button); } - - // only send event if axis has changed after going through filters - if let Some(old_value) = old_value { - if old_value == filtered_value { - return; - } - } else if filtered_value == 0.0 { - return; - } - - events.send(GamepadEvent( - gamepad, - GamepadEventType::ButtonChanged(*button_type, filtered_value), - )) } } } diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index d1ff1b75eb..ec8ec84498 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -26,6 +26,7 @@ use keyboard::{keyboard_input_system, KeyCode, KeyboardInput}; use mouse::{mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotion, MouseWheel}; use touch::{touch_screen_input_system, TouchInput, Touches}; +use bevy_app::startup_stage::STARTUP; use bevy_ecs::IntoQuerySystem; use gamepad::{ gamepad_event_system, GamepadAxis, GamepadButton, GamepadEvent, GamepadEventRaw, @@ -53,6 +54,7 @@ impl Plugin for InputPlugin { .init_resource::>() .init_resource::>() .add_system_to_stage(bevy_app::stage::EVENT, gamepad_event_system.system()) + .add_startup_system_to_stage(STARTUP, gamepad_event_system.system()) .add_event::() .init_resource::() .add_system_to_stage(bevy_app::stage::EVENT, touch_screen_input_system.system()); diff --git a/examples/input/gamepad_input.rs b/examples/input/gamepad_input.rs index 1b8279489d..bb0ec8be43 100644 --- a/examples/input/gamepad_input.rs +++ b/examples/input/gamepad_input.rs @@ -6,8 +6,7 @@ fn main() { App::build() .add_default_plugins() .init_resource::() - .add_startup_system(connection_system.system()) - .add_system(connection_system.system()) + .add_system_to_stage(stage::PRE_UPDATE, connection_system.system()) .add_system(gamepad_system.system()) .run(); }