Skip to content

Commit e94215c

Browse files
committed
Gamepad events refactor (#6965)
# Objective - Remove redundant gamepad events - Simplify consuming gamepad events. - Refactor: Separate handling of gamepad events into multiple systems. ## Solution - Removed `GamepadEventRaw`, and `GamepadEventType`. - Added bespoke `GamepadConnectionEvent`, `GamepadAxisChangedEvent`, and `GamepadButtonChangedEvent`. - Refactored `gamepad_event_system`. - Added `gamepad_button_event_system`, `gamepad_axis_event_system`, and `gamepad_connection_system`, which update the `Input` and `Axis` resources using their corresponding event type. Gamepad events are now handled in their own systems and have their own types. This allows for querying for gamepad events without having to match on `GamepadEventType` and makes creating handlers for specific gamepad event types, like a `GamepadConnectionEvent` or `GamepadButtonChangedEvent` possible. We remove `GamepadEventRaw` by filtering the gamepad events, using `GamepadSettings`, _at the source_, in `bevy_gilrs`. This way we can create `GamepadEvent`s directly and avoid creating `GamepadEventRaw` which do not pass the user defined filters. We expose ordered `GamepadEvent`s and we can respond to individual gamepad event types. ## Migration Guide - Replace `GamepadEvent` and `GamepadEventRaw` types with their specific gamepad event type.
1 parent fa15b31 commit e94215c

File tree

5 files changed

+414
-395
lines changed

5 files changed

+414
-395
lines changed

crates/bevy_gilrs/src/gilrs_system.rs

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,85 @@
11
use crate::converter::{convert_axis, convert_button, convert_gamepad_id};
22
use bevy_ecs::event::EventWriter;
3-
use bevy_ecs::system::{NonSend, NonSendMut};
4-
use bevy_input::gamepad::GamepadInfo;
5-
use bevy_input::{gamepad::GamepadEventRaw, prelude::*};
3+
use bevy_ecs::system::{NonSend, NonSendMut, Res};
4+
use bevy_input::gamepad::{
5+
GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadConnection, GamepadConnectionEvent,
6+
GamepadSettings,
7+
};
8+
use bevy_input::gamepad::{GamepadEvent, GamepadInfo};
9+
use bevy_input::prelude::{GamepadAxis, GamepadButton};
10+
use bevy_input::Axis;
611
use gilrs::{ev::filter::axis_dpad_to_button, EventType, Filter, Gilrs};
712

8-
pub fn gilrs_event_startup_system(gilrs: NonSend<Gilrs>, mut events: EventWriter<GamepadEventRaw>) {
13+
pub fn gilrs_event_startup_system(
14+
gilrs: NonSend<Gilrs>,
15+
mut connection_events: EventWriter<GamepadConnectionEvent>,
16+
) {
917
for (id, gamepad) in gilrs.gamepads() {
1018
let info = GamepadInfo {
1119
name: gamepad.name().into(),
1220
};
1321

14-
events.send(GamepadEventRaw::new(
15-
convert_gamepad_id(id),
16-
GamepadEventType::Connected(info),
17-
));
22+
connection_events.send(GamepadConnectionEvent {
23+
gamepad: convert_gamepad_id(id),
24+
connection: GamepadConnection::Connected(info),
25+
});
1826
}
1927
}
2028

21-
pub fn gilrs_event_system(mut gilrs: NonSendMut<Gilrs>, mut events: EventWriter<GamepadEventRaw>) {
29+
pub fn gilrs_event_system(
30+
mut gilrs: NonSendMut<Gilrs>,
31+
mut events: EventWriter<GamepadEvent>,
32+
gamepad_axis: Res<Axis<GamepadAxis>>,
33+
gamepad_buttons: Res<Axis<GamepadButton>>,
34+
gamepad_settings: Res<GamepadSettings>,
35+
) {
2236
while let Some(gilrs_event) = gilrs
2337
.next_event()
2438
.filter_ev(&axis_dpad_to_button, &mut gilrs)
2539
{
2640
gilrs.update(&gilrs_event);
2741

42+
let gamepad = convert_gamepad_id(gilrs_event.id);
2843
match gilrs_event.event {
2944
EventType::Connected => {
3045
let pad = gilrs.gamepad(gilrs_event.id);
3146
let info = GamepadInfo {
3247
name: pad.name().into(),
3348
};
3449

35-
events.send(GamepadEventRaw::new(
36-
convert_gamepad_id(gilrs_event.id),
37-
GamepadEventType::Connected(info),
38-
));
50+
events.send(
51+
GamepadConnectionEvent::new(gamepad, GamepadConnection::Connected(info)).into(),
52+
);
3953
}
40-
EventType::Disconnected => {
41-
events.send(GamepadEventRaw::new(
42-
convert_gamepad_id(gilrs_event.id),
43-
GamepadEventType::Disconnected,
44-
));
45-
}
46-
EventType::ButtonChanged(gilrs_button, value, _) => {
54+
EventType::Disconnected => events
55+
.send(GamepadConnectionEvent::new(gamepad, GamepadConnection::Disconnected).into()),
56+
EventType::ButtonChanged(gilrs_button, raw_value, _) => {
4757
if let Some(button_type) = convert_button(gilrs_button) {
48-
events.send(GamepadEventRaw::new(
49-
convert_gamepad_id(gilrs_event.id),
50-
GamepadEventType::ButtonChanged(button_type, value),
51-
));
58+
let button = GamepadButton::new(gamepad, button_type);
59+
let old_value = gamepad_buttons.get(button);
60+
let button_settings = gamepad_settings.get_button_axis_settings(button);
61+
62+
// Only send events that pass the user-defined change threshold
63+
if let Some(filtered_value) = button_settings.filter(raw_value, old_value) {
64+
events.send(
65+
GamepadButtonChangedEvent::new(gamepad, button_type, filtered_value)
66+
.into(),
67+
);
68+
}
5269
}
5370
}
54-
EventType::AxisChanged(gilrs_axis, value, _) => {
71+
EventType::AxisChanged(gilrs_axis, raw_value, _) => {
5572
if let Some(axis_type) = convert_axis(gilrs_axis) {
56-
events.send(GamepadEventRaw::new(
57-
convert_gamepad_id(gilrs_event.id),
58-
GamepadEventType::AxisChanged(axis_type, value),
59-
));
73+
let axis = GamepadAxis::new(gamepad, axis_type);
74+
let old_value = gamepad_axis.get(axis);
75+
let axis_settings = gamepad_settings.get_axis_settings(axis);
76+
77+
// Only send events that pass the user-defined change threshold
78+
if let Some(filtered_value) = axis_settings.filter(raw_value, old_value) {
79+
events.send(
80+
GamepadAxisChangedEvent::new(gamepad, axis_type, filtered_value).into(),
81+
);
82+
}
6083
}
6184
}
6285
_ => (),

0 commit comments

Comments
 (0)