1
1
use crate :: { Axis , Input } ;
2
2
use bevy_ecs:: event:: { EventReader , EventWriter } ;
3
3
use bevy_ecs:: system:: { Res , ResMut , Resource } ;
4
- use bevy_utils:: { tracing:: info, HashMap , HashSet } ;
4
+ use bevy_utils:: { tracing:: info, HashMap } ;
5
5
use thiserror:: Error ;
6
6
7
7
/// Errors that occur when setting axis settings for gamepad input.
@@ -78,6 +78,13 @@ impl Gamepad {
78
78
}
79
79
}
80
80
81
+ /// Metadata associated with a `Gamepad`.
82
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
83
+ #[ cfg_attr( feature = "serialize" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
84
+ pub struct GamepadInfo {
85
+ pub name : String ,
86
+ }
87
+
81
88
/// A collection of connected [`Gamepad`]s.
82
89
///
83
90
/// ## Usage
@@ -92,23 +99,27 @@ impl Gamepad {
92
99
#[ derive( Resource , Default , Debug ) ]
93
100
pub struct Gamepads {
94
101
/// The collection of the connected [`Gamepad`]s.
95
- gamepads : HashSet < Gamepad > ,
102
+ gamepads : HashMap < Gamepad , GamepadInfo > ,
96
103
}
97
104
98
105
impl Gamepads {
99
106
/// Returns `true` if the `gamepad` is connected.
100
107
pub fn contains ( & self , gamepad : Gamepad ) -> bool {
101
- self . gamepads . contains ( & gamepad)
108
+ self . gamepads . contains_key ( & gamepad)
102
109
}
103
110
104
111
/// Returns an iterator over registered [`Gamepad`]s in an arbitrary order.
105
112
pub fn iter ( & self ) -> impl Iterator < Item = Gamepad > + ' _ {
106
- self . gamepads . iter ( ) . copied ( )
113
+ self . gamepads . keys ( ) . copied ( )
114
+ }
115
+
116
+ pub fn name ( & self , gamepad : Gamepad ) -> Option < & str > {
117
+ self . gamepads . get ( & gamepad) . map ( |g| g. name . as_str ( ) )
107
118
}
108
119
109
120
/// Registers the `gamepad`, marking it as connected.
110
- fn register ( & mut self , gamepad : Gamepad ) {
111
- self . gamepads . insert ( gamepad) ;
121
+ fn register ( & mut self , gamepad : Gamepad , info : GamepadInfo ) {
122
+ self . gamepads . insert ( gamepad, info ) ;
112
123
}
113
124
114
125
/// Deregisters the `gamepad`, marking it as disconnected.
@@ -118,11 +129,11 @@ impl Gamepads {
118
129
}
119
130
120
131
/// The data contained in a [`GamepadEvent`] or [`GamepadEventRaw`].
121
- #[ derive( Debug , Clone , Copy , PartialEq ) ]
132
+ #[ derive( Debug , Clone , PartialEq ) ]
122
133
#[ cfg_attr( feature = "serialize" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
123
134
pub enum GamepadEventType {
124
135
/// A [`Gamepad`] has been connected.
125
- Connected ,
136
+ Connected ( GamepadInfo ) ,
126
137
/// A [`Gamepad`] has been disconnected.
127
138
Disconnected ,
128
139
@@ -151,7 +162,7 @@ pub enum GamepadEventType {
151
162
/// [`Axis<GamepadAxis>`], and [`Axis<GamepadButton>`] resources won't be updated correctly.
152
163
///
153
164
/// An example for gamepad input mocking can be seen in the documentation of the [`GamepadEventRaw`].
154
- #[ derive( Debug , Clone , Copy , PartialEq ) ]
165
+ #[ derive( Debug , Clone , PartialEq ) ]
155
166
#[ cfg_attr( feature = "serialize" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
156
167
pub struct GamepadEvent {
157
168
/// The gamepad this event corresponds to.
@@ -191,7 +202,7 @@ impl GamepadEvent {
191
202
/// ```
192
203
/// # use bevy_input::prelude::*;
193
204
/// # use bevy_input::InputPlugin;
194
- /// # use bevy_input::gamepad::GamepadEventRaw;
205
+ /// # use bevy_input::gamepad::{ GamepadEventRaw, GamepadInfo} ;
195
206
/// # use bevy_app::prelude::*;
196
207
/// # use bevy_ecs::prelude::*;
197
208
/// #[derive(Resource)]
@@ -223,7 +234,8 @@ impl GamepadEvent {
223
234
///
224
235
/// // Send the gamepad connected event to mark our gamepad as connected.
225
236
/// // This updates the `Gamepads` resource accordingly.
226
- /// app.world.send_event(GamepadEventRaw::new(gamepad, GamepadEventType::Connected));
237
+ /// let info = GamepadInfo { name: "Mock Gamepad".into() };
238
+ /// app.world.send_event(GamepadEventRaw::new(gamepad, GamepadEventType::Connected(info)));
227
239
///
228
240
/// // Send the gamepad input event to mark the `South` gamepad button as pressed.
229
241
/// // This updates the `Input<GamepadButton>` resource accordingly.
@@ -254,7 +266,7 @@ impl GamepadEvent {
254
266
/// #
255
267
/// # bevy_ecs::system::assert_is_system(change_resource_on_gamepad_button_press);
256
268
/// ```
257
- #[ derive( Debug , Clone , Copy , PartialEq ) ]
269
+ #[ derive( Debug , Clone , PartialEq ) ]
258
270
#[ cfg_attr( feature = "serialize" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
259
271
pub struct GamepadEventRaw {
260
272
/// The gamepad this event corresponds to.
@@ -1062,11 +1074,12 @@ pub fn gamepad_connection_system(
1062
1074
mut gamepad_event : EventReader < GamepadEvent > ,
1063
1075
) {
1064
1076
for event in gamepad_event. iter ( ) {
1065
- match event. event_type {
1066
- GamepadEventType :: Connected => {
1067
- gamepads. register ( event. gamepad ) ;
1077
+ match & event. event_type {
1078
+ GamepadEventType :: Connected ( info ) => {
1079
+ gamepads. register ( event. gamepad , info . clone ( ) ) ;
1068
1080
info ! ( "{:?} Connected" , event. gamepad) ;
1069
1081
}
1082
+
1070
1083
GamepadEventType :: Disconnected => {
1071
1084
gamepads. deregister ( event. gamepad ) ;
1072
1085
info ! ( "{:?} Disconnected" , event. gamepad) ;
@@ -1096,9 +1109,9 @@ pub fn gamepad_event_system(
1096
1109
) {
1097
1110
button_input. clear ( ) ;
1098
1111
for event in raw_events. iter ( ) {
1099
- match event. event_type {
1100
- GamepadEventType :: Connected => {
1101
- events. send ( GamepadEvent :: new ( event. gamepad , event. event_type ) ) ;
1112
+ match & event. event_type {
1113
+ GamepadEventType :: Connected ( _ ) => {
1114
+ events. send ( GamepadEvent :: new ( event. gamepad , event. event_type . clone ( ) ) ) ;
1102
1115
for button_type in & ALL_BUTTON_TYPES {
1103
1116
let gamepad_button = GamepadButton :: new ( event. gamepad , * button_type) ;
1104
1117
button_input. reset ( gamepad_button) ;
@@ -1109,7 +1122,7 @@ pub fn gamepad_event_system(
1109
1122
}
1110
1123
}
1111
1124
GamepadEventType :: Disconnected => {
1112
- events. send ( GamepadEvent :: new ( event. gamepad , event. event_type ) ) ;
1125
+ events. send ( GamepadEvent :: new ( event. gamepad , event. event_type . clone ( ) ) ) ;
1113
1126
for button_type in & ALL_BUTTON_TYPES {
1114
1127
let gamepad_button = GamepadButton :: new ( event. gamepad , * button_type) ;
1115
1128
button_input. reset ( gamepad_button) ;
@@ -1120,37 +1133,37 @@ pub fn gamepad_event_system(
1120
1133
}
1121
1134
}
1122
1135
GamepadEventType :: AxisChanged ( axis_type, value) => {
1123
- let gamepad_axis = GamepadAxis :: new ( event. gamepad , axis_type) ;
1136
+ let gamepad_axis = GamepadAxis :: new ( event. gamepad , * axis_type) ;
1124
1137
if let Some ( filtered_value) = settings
1125
1138
. get_axis_settings ( gamepad_axis)
1126
- . filter ( value, axis. get ( gamepad_axis) )
1139
+ . filter ( * value, axis. get ( gamepad_axis) )
1127
1140
{
1128
1141
axis. set ( gamepad_axis, filtered_value) ;
1129
1142
events. send ( GamepadEvent :: new (
1130
1143
event. gamepad ,
1131
- GamepadEventType :: AxisChanged ( axis_type, filtered_value) ,
1144
+ GamepadEventType :: AxisChanged ( * axis_type, filtered_value) ,
1132
1145
) ) ;
1133
1146
}
1134
1147
}
1135
1148
GamepadEventType :: ButtonChanged ( button_type, value) => {
1136
- let gamepad_button = GamepadButton :: new ( event. gamepad , button_type) ;
1149
+ let gamepad_button = GamepadButton :: new ( event. gamepad , * button_type) ;
1137
1150
if let Some ( filtered_value) = settings
1138
1151
. get_button_axis_settings ( gamepad_button)
1139
- . filter ( value, button_axis. get ( gamepad_button) )
1152
+ . filter ( * value, button_axis. get ( gamepad_button) )
1140
1153
{
1141
1154
button_axis. set ( gamepad_button, filtered_value) ;
1142
1155
events. send ( GamepadEvent :: new (
1143
1156
event. gamepad ,
1144
- GamepadEventType :: ButtonChanged ( button_type, filtered_value) ,
1157
+ GamepadEventType :: ButtonChanged ( * button_type, filtered_value) ,
1145
1158
) ) ;
1146
1159
}
1147
1160
1148
1161
let button_property = settings. get_button_settings ( gamepad_button) ;
1149
1162
if button_input. pressed ( gamepad_button) {
1150
- if button_property. is_released ( value) {
1163
+ if button_property. is_released ( * value) {
1151
1164
button_input. release ( gamepad_button) ;
1152
1165
}
1153
- } else if button_property. is_pressed ( value) {
1166
+ } else if button_property. is_pressed ( * value) {
1154
1167
button_input. press ( gamepad_button) ;
1155
1168
}
1156
1169
}
0 commit comments