11//! The gamepad input functionality.
22
33use crate :: { Axis , ButtonInput , ButtonState } ;
4+ use bevy_core:: Name ;
45use bevy_ecs:: {
56 change_detection:: DetectChangesMut ,
67 component:: Component ,
@@ -148,7 +149,7 @@ impl GamepadConnectionEvent {
148149
149150 /// Is the gamepad connected?
150151 pub fn connected ( & self ) -> bool {
151- matches ! ( self . connection, GamepadConnection :: Connected ( _ ) )
152+ matches ! ( self . connection, GamepadConnection :: Connected { .. } )
152153 }
153154
154155 /// Is the gamepad disconnected?
@@ -318,10 +319,10 @@ pub enum ButtonSettingsError {
318319/// ```
319320/// # use bevy_input::gamepad::{Gamepad, GamepadAxis, GamepadButton};
320321/// # use bevy_ecs::system::Query;
322+ /// # use bevy_core::Name;
321323/// #
322- /// fn gamepad_usage_system(gamepads: Query<&Gamepad>) {
323- /// for gamepad in &gamepads {
324- /// let name = &gamepad.info.name;
324+ /// fn gamepad_usage_system(gamepads: Query<(&Name, &Gamepad)>) {
325+ /// for (name, gamepad) in &gamepads {
325326/// println!("{name}");
326327///
327328/// if gamepad.digital.just_pressed(GamepadButton::North) {
@@ -338,31 +339,22 @@ pub enum ButtonSettingsError {
338339#[ cfg_attr( feature = "bevy_reflect" , derive( Reflect ) , reflect( Debug ) ) ]
339340#[ require( GamepadSettings ) ]
340341pub struct Gamepad {
341- /// Metadata.
342- pub info : GamepadInfo ,
342+ /// The USB vendor ID as assigned by the USB-IF, if available.
343+ pub vendor_id : Option < u16 > ,
344+
345+ /// The USB product ID as assigned by the [vendor], if available.
346+ ///
347+ /// [vendor]: Self::vendor_id
348+ pub product_id : Option < u16 > ,
349+
343350 /// [`ButtonInput`] of [`GamepadButton`] representing their digital state
344351 pub digital : ButtonInput < GamepadButton > ,
352+
345353 /// [`Axis`] of [`GamepadButton`] representing their analog state.
346354 pub analog : Axis < GamepadInput > ,
347355}
348356
349357impl Gamepad {
350- /// Creates a gamepad with the given metadata.
351- pub fn new ( info : GamepadInfo ) -> Self {
352- let mut analog = Axis :: default ( ) ;
353- for button in GamepadButton :: all ( ) . iter ( ) . copied ( ) {
354- analog. set ( button, 0.0 ) ;
355- }
356- for axis_type in GamepadAxis :: all ( ) . iter ( ) . copied ( ) {
357- analog. set ( axis_type, 0.0 ) ;
358- }
359- Self {
360- info,
361- analog,
362- digital : ButtonInput :: default ( ) ,
363- }
364- }
365-
366358 /// Returns the left stick as a [`Vec2`]
367359 pub fn left_stick ( & self ) -> Vec2 {
368360 Vec2 {
@@ -390,32 +382,23 @@ impl Gamepad {
390382 }
391383}
392384
393- // Note that we don't expose `gilrs::Gamepad::uuid` due to
394- // https://gitlab.com/gilrs-project/gilrs/-/issues/153.
395- //
396- /// Metadata associated with a [`Gamepad`].
397- #[ derive( Debug , Default , Clone , PartialEq , Eq ) ]
398- #[ cfg_attr( feature = "bevy_reflect" , derive( Reflect ) , reflect( Debug , PartialEq ) ) ]
399- #[ cfg_attr( feature = "serialize" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
400- #[ cfg_attr(
401- all( feature = "serialize" , feature = "bevy_reflect" ) ,
402- reflect( Serialize , Deserialize )
403- ) ]
404- pub struct GamepadInfo {
405- /// The name of the gamepad.
406- ///
407- /// This name is generally defined by the OS.
408- ///
409- /// For example on Windows the name may be "HID-compliant game controller".
410- pub name : String ,
411-
412- /// The USB vendor ID as assigned by the USB-IF, if available.
413- pub vendor_id : Option < u16 > ,
385+ impl Default for Gamepad {
386+ fn default ( ) -> Self {
387+ let mut analog = Axis :: default ( ) ;
388+ for button in GamepadButton :: all ( ) . iter ( ) . copied ( ) {
389+ analog. set ( button, 0.0 ) ;
390+ }
391+ for axis_type in GamepadAxis :: all ( ) . iter ( ) . copied ( ) {
392+ analog. set ( axis_type, 0.0 ) ;
393+ }
414394
415- /// The USB product ID as assigned by the [vendor], if available.
416- ///
417- /// [vendor]: Self::vendor_id
418- pub product_id : Option < u16 > ,
395+ Self {
396+ vendor_id : None ,
397+ product_id : None ,
398+ digital : Default :: default ( ) ,
399+ analog,
400+ }
401+ }
419402}
420403
421404/// Represents gamepad input types that are mapped in the range [0.0, 1.0].
@@ -1227,12 +1210,23 @@ pub fn gamepad_connection_system(
12271210 for connection_event in connection_events. read ( ) {
12281211 let id = connection_event. gamepad ;
12291212 match & connection_event. connection {
1230- GamepadConnection :: Connected ( info) => {
1213+ GamepadConnection :: Connected {
1214+ name,
1215+ vendor_id,
1216+ product_id,
1217+ } => {
12311218 let Some ( mut gamepad) = commands. get_entity ( id) else {
12321219 warn ! ( "Gamepad {:} removed before handling connection event." , id) ;
12331220 continue ;
12341221 } ;
1235- gamepad. insert ( Gamepad :: new ( info. clone ( ) ) ) ;
1222+ gamepad. insert ( (
1223+ Name :: new ( name. clone ( ) ) ,
1224+ Gamepad {
1225+ vendor_id : * vendor_id,
1226+ product_id : * product_id,
1227+ ..Default :: default ( )
1228+ } ,
1229+ ) ) ;
12361230 info ! ( "Gamepad {:?} connected." , id) ;
12371231 }
12381232 GamepadConnection :: Disconnected => {
@@ -1250,6 +1244,9 @@ pub fn gamepad_connection_system(
12501244 }
12511245}
12521246
1247+ // Note that we don't expose `gilrs::Gamepad::uuid` due to
1248+ // https://gitlab.com/gilrs-project/gilrs/-/issues/153.
1249+ //
12531250/// The connection status of a gamepad.
12541251#[ derive( Debug , Clone , PartialEq ) ]
12551252#[ cfg_attr( feature = "bevy_reflect" , derive( Reflect ) , reflect( Debug , PartialEq ) ) ]
@@ -1260,7 +1257,20 @@ pub fn gamepad_connection_system(
12601257) ]
12611258pub enum GamepadConnection {
12621259 /// The gamepad is connected.
1263- Connected ( GamepadInfo ) ,
1260+ Connected {
1261+ /// The name of the gamepad.
1262+ ///
1263+ /// This name is generally defined by the OS.
1264+ ///
1265+ /// For example on Windows the name may be "HID-compliant game controller".
1266+ name : String ,
1267+
1268+ /// The USB vendor ID as assigned by the USB-IF, if available.
1269+ vendor_id : Option < u16 > ,
1270+
1271+ /// The USB product ID as assigned by the vendor, if available.
1272+ product_id : Option < u16 > ,
1273+ } ,
12641274 /// The gamepad is disconnected.
12651275 Disconnected ,
12661276}
@@ -1497,8 +1507,8 @@ mod tests {
14971507 GamepadAxis , GamepadAxisChangedEvent , GamepadButton , GamepadButtonChangedEvent ,
14981508 GamepadButtonStateChangedEvent ,
14991509 GamepadConnection :: { Connected , Disconnected } ,
1500- GamepadConnectionEvent , GamepadEvent , GamepadInfo , GamepadSettings ,
1501- RawGamepadAxisChangedEvent , RawGamepadButtonChangedEvent , RawGamepadEvent ,
1510+ GamepadConnectionEvent , GamepadEvent , GamepadSettings , RawGamepadAxisChangedEvent ,
1511+ RawGamepadButtonChangedEvent , RawGamepadEvent ,
15021512 } ;
15031513 use crate :: ButtonState ;
15041514 use bevy_app:: { App , PreUpdate } ;
@@ -1871,7 +1881,11 @@ mod tests {
18711881 . resource_mut :: < Events < GamepadConnectionEvent > > ( )
18721882 . send ( GamepadConnectionEvent :: new (
18731883 gamepad,
1874- Connected ( GamepadInfo :: default ( ) ) ,
1884+ Connected {
1885+ name : "Test gamepad" . to_string ( ) ,
1886+ vendor_id : None ,
1887+ product_id : None ,
1888+ } ,
18751889 ) ) ;
18761890 gamepad
18771891 }
0 commit comments