mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 14:10:19 +00:00
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:
parent
7734b1ea6d
commit
fb2b19def5
5 changed files with 48 additions and 52 deletions
|
@ -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();
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue