Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug of connection event of gamepad at startup #730

Merged
merged 2 commits into from
Oct 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions crates/bevy_gilrs/src/gilrs_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
9 changes: 6 additions & 3 deletions crates/bevy_gilrs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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(),
Expand Down
75 changes: 28 additions & 47 deletions crates/bevy_input/src/gamepad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand All @@ -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>>,
Expand Down Expand Up @@ -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) {
Expand All @@ -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),
))
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_input/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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());
Expand Down
3 changes: 1 addition & 2 deletions examples/input/gamepad_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down