Fix bug of connection event of gamepad at startup (#730)

* Removed f32==f32 comparision in gamepad.rs

* Trigger gamepad connection event at start up
This commit is contained in:
Utkarsh 2020-10-30 02:25:35 +05:30 committed by GitHub
parent 7734b1ea6d
commit fb2b19def5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 52 deletions

View file

@ -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::<Gilrs>().unwrap();
let mut event = resources.get_mut::<Events<GamepadEventRaw>>().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::<Gilrs>().unwrap();
let mut event = resources.get_mut::<Events<GamepadEventRaw>>().unwrap();

View file

@ -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(),

View file

@ -146,22 +146,22 @@ impl Default for AxisSettings {
}
impl AxisSettings {
fn filter(&self, new_value: f32, old_value: Option<f32>) -> f32 {
fn filter(&self, new_value: f32, old_value: Option<f32>) -> Option<f32> {
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>) -> f32 {
fn filter(&self, new_value: f32, old_value: Option<f32>) -> Option<f32> {
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<EventReader<GamepadEventRaw>>,
mut button_input: ResMut<Input<GamepadButton>>,
@ -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),
))
}
}
}

View file

@ -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::<Axis<GamepadAxis>>()
.init_resource::<Axis<GamepadButton>>()
.add_system_to_stage(bevy_app::stage::EVENT, gamepad_event_system.system())
.add_startup_system_to_stage(STARTUP, gamepad_event_system.system())
.add_event::<TouchInput>()
.init_resource::<Touches>()
.add_system_to_stage(bevy_app::stage::EVENT, touch_screen_input_system.system());

View file

@ -6,8 +6,7 @@ fn main() {
App::build()
.add_default_plugins()
.init_resource::<GamepadLobby>()
.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();
}