|
1 | 1 | use crate::{
|
2 |
| - converter::{convert_axis, convert_button, convert_gamepad_id}, |
3 |
| - Gilrs, |
| 2 | + converter::{convert_axis, convert_button}, |
| 3 | + Gilrs, GilrsGamepads, |
4 | 4 | };
|
| 5 | +use bevy_ecs::event::EventWriter; |
| 6 | +use bevy_ecs::prelude::Commands; |
5 | 7 | #[cfg(target_arch = "wasm32")]
|
6 | 8 | use bevy_ecs::system::NonSendMut;
|
7 |
| -use bevy_ecs::{ |
8 |
| - event::EventWriter, |
9 |
| - system::{Res, ResMut}, |
10 |
| -}; |
11 |
| -use bevy_input::{ |
12 |
| - gamepad::{ |
13 |
| - GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadConnection, |
14 |
| - GamepadConnectionEvent, GamepadEvent, GamepadInfo, GamepadSettings, |
15 |
| - }, |
16 |
| - prelude::{GamepadAxis, GamepadButton}, |
17 |
| - Axis, |
| 9 | +use bevy_ecs::system::ResMut; |
| 10 | +use bevy_input::gamepad::{ |
| 11 | + GamepadConnection, GamepadConnectionEvent, GamepadInfo, RawGamepadAxisChangedEvent, |
| 12 | + RawGamepadButtonChangedEvent, RawGamepadEvent, |
18 | 13 | };
|
19 | 14 | use gilrs::{ev::filter::axis_dpad_to_button, EventType, Filter};
|
20 | 15 |
|
21 | 16 | pub fn gilrs_event_startup_system(
|
| 17 | + mut commands: Commands, |
22 | 18 | #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut<Gilrs>,
|
23 | 19 | #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut<Gilrs>,
|
24 |
| - mut events: EventWriter<GamepadEvent>, |
| 20 | + mut gamepads: ResMut<GilrsGamepads>, |
| 21 | + mut events: EventWriter<GamepadConnectionEvent>, |
25 | 22 | ) {
|
26 | 23 | for (id, gamepad) in gilrs.0.get().gamepads() {
|
| 24 | + // Create entity and add to mapping |
| 25 | + let entity = commands.spawn_empty().id(); |
| 26 | + gamepads.id_to_entity.insert(id, entity); |
| 27 | + gamepads.entity_to_id.insert(entity, id); |
| 28 | + |
27 | 29 | let info = GamepadInfo {
|
28 | 30 | name: gamepad.name().into(),
|
29 | 31 | };
|
30 | 32 |
|
31 |
| - events.send( |
32 |
| - GamepadConnectionEvent { |
33 |
| - gamepad: convert_gamepad_id(id), |
34 |
| - connection: GamepadConnection::Connected(info), |
35 |
| - } |
36 |
| - .into(), |
37 |
| - ); |
| 33 | + events.send(GamepadConnectionEvent { |
| 34 | + gamepad: entity, |
| 35 | + connection: GamepadConnection::Connected(info), |
| 36 | + }); |
38 | 37 | }
|
39 | 38 | }
|
40 | 39 |
|
41 | 40 | pub fn gilrs_event_system(
|
| 41 | + mut commands: Commands, |
42 | 42 | #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut<Gilrs>,
|
43 | 43 | #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut<Gilrs>,
|
44 |
| - mut events: EventWriter<GamepadEvent>, |
45 |
| - mut gamepad_buttons: ResMut<Axis<GamepadButton>>, |
46 |
| - gamepad_axis: Res<Axis<GamepadAxis>>, |
47 |
| - gamepad_settings: Res<GamepadSettings>, |
| 44 | + mut gamepads: ResMut<GilrsGamepads>, |
| 45 | + mut events: EventWriter<RawGamepadEvent>, |
| 46 | + mut connection_events: EventWriter<GamepadConnectionEvent>, |
| 47 | + mut button_events: EventWriter<RawGamepadButtonChangedEvent>, |
| 48 | + mut axis_event: EventWriter<RawGamepadAxisChangedEvent>, |
48 | 49 | ) {
|
49 | 50 | let gilrs = gilrs.0.get();
|
50 | 51 | while let Some(gilrs_event) = gilrs.next_event().filter_ev(&axis_dpad_to_button, gilrs) {
|
51 | 52 | gilrs.update(&gilrs_event);
|
52 |
| - |
53 |
| - let gamepad = convert_gamepad_id(gilrs_event.id); |
54 | 53 | match gilrs_event.event {
|
55 | 54 | EventType::Connected => {
|
56 | 55 | let pad = gilrs.gamepad(gilrs_event.id);
|
| 56 | + let entity = gamepads.get_entity(gilrs_event.id).unwrap_or_else(|| { |
| 57 | + let entity = commands.spawn_empty().id(); |
| 58 | + gamepads.id_to_entity.insert(gilrs_event.id, entity); |
| 59 | + gamepads.entity_to_id.insert(entity, gilrs_event.id); |
| 60 | + entity |
| 61 | + }); |
| 62 | + |
57 | 63 | let info = GamepadInfo {
|
58 | 64 | name: pad.name().into(),
|
59 | 65 | };
|
60 | 66 |
|
61 | 67 | events.send(
|
62 |
| - GamepadConnectionEvent::new(gamepad, GamepadConnection::Connected(info)).into(), |
| 68 | + GamepadConnectionEvent::new(entity, GamepadConnection::Connected(info.clone())) |
| 69 | + .into(), |
63 | 70 | );
|
| 71 | + connection_events.send(GamepadConnectionEvent::new( |
| 72 | + entity, |
| 73 | + GamepadConnection::Connected(info), |
| 74 | + )); |
64 | 75 | }
|
65 | 76 | EventType::Disconnected => {
|
66 |
| - events.send( |
67 |
| - GamepadConnectionEvent::new(gamepad, GamepadConnection::Disconnected).into(), |
68 |
| - ); |
| 77 | + let gamepad = gamepads |
| 78 | + .id_to_entity |
| 79 | + .get(&gilrs_event.id) |
| 80 | + .copied() |
| 81 | + .expect("mapping should exist from connection"); |
| 82 | + let event = GamepadConnectionEvent::new(gamepad, GamepadConnection::Disconnected); |
| 83 | + events.send(event.clone().into()); |
| 84 | + connection_events.send(event); |
69 | 85 | }
|
70 | 86 | EventType::ButtonChanged(gilrs_button, raw_value, _) => {
|
71 |
| - if let Some(button_type) = convert_button(gilrs_button) { |
72 |
| - let button = GamepadButton::new(gamepad, button_type); |
73 |
| - let old_value = gamepad_buttons.get(button); |
74 |
| - let button_settings = gamepad_settings.get_button_axis_settings(button); |
75 |
| - |
76 |
| - // Only send events that pass the user-defined change threshold |
77 |
| - if let Some(filtered_value) = button_settings.filter(raw_value, old_value) { |
78 |
| - events.send( |
79 |
| - GamepadButtonChangedEvent::new(gamepad, button_type, filtered_value) |
80 |
| - .into(), |
81 |
| - ); |
82 |
| - // Update the current value prematurely so that `old_value` is correct in |
83 |
| - // future iterations of the loop. |
84 |
| - gamepad_buttons.set(button, filtered_value); |
85 |
| - } |
86 |
| - } |
| 87 | + let Some(button) = convert_button(gilrs_button) else { |
| 88 | + continue; |
| 89 | + }; |
| 90 | + let gamepad = gamepads |
| 91 | + .id_to_entity |
| 92 | + .get(&gilrs_event.id) |
| 93 | + .copied() |
| 94 | + .expect("mapping should exist from connection"); |
| 95 | + events.send(RawGamepadButtonChangedEvent::new(gamepad, button, raw_value).into()); |
| 96 | + button_events.send(RawGamepadButtonChangedEvent::new( |
| 97 | + gamepad, button, raw_value, |
| 98 | + )); |
87 | 99 | }
|
88 | 100 | EventType::AxisChanged(gilrs_axis, raw_value, _) => {
|
89 |
| - if let Some(axis_type) = convert_axis(gilrs_axis) { |
90 |
| - let axis = GamepadAxis::new(gamepad, axis_type); |
91 |
| - let old_value = gamepad_axis.get(axis); |
92 |
| - let axis_settings = gamepad_settings.get_axis_settings(axis); |
93 |
| - |
94 |
| - // Only send events that pass the user-defined change threshold |
95 |
| - if let Some(filtered_value) = axis_settings.filter(raw_value, old_value) { |
96 |
| - events.send( |
97 |
| - GamepadAxisChangedEvent::new(gamepad, axis_type, filtered_value).into(), |
98 |
| - ); |
99 |
| - } |
100 |
| - } |
| 101 | + let Some(axis) = convert_axis(gilrs_axis) else { |
| 102 | + continue; |
| 103 | + }; |
| 104 | + let gamepad = gamepads |
| 105 | + .id_to_entity |
| 106 | + .get(&gilrs_event.id) |
| 107 | + .copied() |
| 108 | + .expect("mapping should exist from connection"); |
| 109 | + events.send(RawGamepadAxisChangedEvent::new(gamepad, axis, raw_value).into()); |
| 110 | + axis_event.send(RawGamepadAxisChangedEvent::new(gamepad, axis, raw_value)); |
101 | 111 | }
|
102 | 112 | _ => (),
|
103 | 113 | };
|
|
0 commit comments