Change gamepad.rs tuples to normal structs (#4519)

# Objective

- Part of the splitting process of #3692.

## Solution

- Remove / change the tuple structs inside of `gamepad.rs` of `bevy_input` to normal structs.

## Reasons

- It made the `gamepad_connection_system` cleaner.
- It made the `gamepad_input_events.rs` example cleaner (which is probably the most notable change for the user facing API).
- Tuple structs are not descriptive (`.0`, `.1`).
- Using tuple structs for more than 1 field is a bad idea (This means that the `Gamepad` type might be fine as a tuple struct, but I still prefer normal structs over tuple structs).

Feel free to discuss this change as this is more or less just a matter of taste.

## Changelog

### Changed

- The `Gamepad`, `GamepadButton`, `GamepadAxis`, `GamepadEvent` and `GamepadEventRaw` types are now normal structs instead of tuple structs and have a `new()` function.

## Migration Guide

- The `Gamepad`, `GamepadButton`, `GamepadAxis`, `GamepadEvent` and `GamepadEventRaw` types are now normal structs instead of tuple structs and have a `new()` function. To migrate change every instantiation to use the `new()` function instead and use the appropriate field names instead of `.0` and `.1`.
This commit is contained in:
KDecay 2022-05-02 13:20:55 +00:00
parent e9db69af81
commit 51509a9a3e
6 changed files with 117 additions and 53 deletions

View file

@ -1,7 +1,7 @@
use bevy_input::gamepad::{Gamepad, GamepadAxisType, GamepadButtonType}; use bevy_input::gamepad::{Gamepad, GamepadAxisType, GamepadButtonType};
pub fn convert_gamepad_id(gamepad_id: gilrs::GamepadId) -> Gamepad { pub fn convert_gamepad_id(gamepad_id: gilrs::GamepadId) -> Gamepad {
Gamepad(gamepad_id.into()) Gamepad::new(gamepad_id.into())
} }
pub fn convert_button(button: gilrs::Button) -> Option<GamepadButtonType> { pub fn convert_button(button: gilrs::Button) -> Option<GamepadButtonType> {

View file

@ -6,7 +6,7 @@ use gilrs::{EventType, Gilrs};
pub fn gilrs_event_startup_system(gilrs: NonSend<Gilrs>, mut events: EventWriter<GamepadEventRaw>) { pub fn gilrs_event_startup_system(gilrs: NonSend<Gilrs>, mut events: EventWriter<GamepadEventRaw>) {
for (id, _) in gilrs.gamepads() { for (id, _) in gilrs.gamepads() {
events.send(GamepadEventRaw( events.send(GamepadEventRaw::new(
convert_gamepad_id(id), convert_gamepad_id(id),
GamepadEventType::Connected, GamepadEventType::Connected,
)); ));
@ -17,20 +17,20 @@ pub fn gilrs_event_system(mut gilrs: NonSendMut<Gilrs>, mut events: EventWriter<
while let Some(gilrs_event) = gilrs.next_event() { while let Some(gilrs_event) = gilrs.next_event() {
match gilrs_event.event { match gilrs_event.event {
EventType::Connected => { EventType::Connected => {
events.send(GamepadEventRaw( events.send(GamepadEventRaw::new(
convert_gamepad_id(gilrs_event.id), convert_gamepad_id(gilrs_event.id),
GamepadEventType::Connected, GamepadEventType::Connected,
)); ));
} }
EventType::Disconnected => { EventType::Disconnected => {
events.send(GamepadEventRaw( events.send(GamepadEventRaw::new(
convert_gamepad_id(gilrs_event.id), convert_gamepad_id(gilrs_event.id),
GamepadEventType::Disconnected, GamepadEventType::Disconnected,
)); ));
} }
EventType::ButtonChanged(gilrs_button, value, _) => { EventType::ButtonChanged(gilrs_button, value, _) => {
if let Some(button_type) = convert_button(gilrs_button) { if let Some(button_type) = convert_button(gilrs_button) {
events.send(GamepadEventRaw( events.send(GamepadEventRaw::new(
convert_gamepad_id(gilrs_event.id), convert_gamepad_id(gilrs_event.id),
GamepadEventType::ButtonChanged(button_type, value), GamepadEventType::ButtonChanged(button_type, value),
)); ));
@ -38,7 +38,7 @@ pub fn gilrs_event_system(mut gilrs: NonSendMut<Gilrs>, mut events: EventWriter<
} }
EventType::AxisChanged(gilrs_axis, value, _) => { EventType::AxisChanged(gilrs_axis, value, _) => {
if let Some(axis_type) = convert_axis(gilrs_axis) { if let Some(axis_type) = convert_axis(gilrs_axis) {
events.send(GamepadEventRaw( events.send(GamepadEventRaw::new(
convert_gamepad_id(gilrs_event.id), convert_gamepad_id(gilrs_event.id),
GamepadEventType::AxisChanged(axis_type, value), GamepadEventType::AxisChanged(axis_type, value),
)); ));

View file

@ -77,7 +77,8 @@ mod tests {
]; ];
for (value, expected) in cases { for (value, expected) in cases {
let gamepad_button = GamepadButton(Gamepad(1), GamepadButtonType::RightTrigger); let gamepad_button =
GamepadButton::new(Gamepad::new(1), GamepadButtonType::RightTrigger);
let mut axis = Axis::<GamepadButton>::default(); let mut axis = Axis::<GamepadButton>::default();
axis.set(gamepad_button, value); axis.set(gamepad_button, value);
@ -92,7 +93,8 @@ mod tests {
let cases = [-1.0, -0.9, -0.1, 0.0, 0.1, 0.9, 1.0]; let cases = [-1.0, -0.9, -0.1, 0.0, 0.1, 0.9, 1.0];
for value in cases { for value in cases {
let gamepad_button = GamepadButton(Gamepad(1), GamepadButtonType::RightTrigger); let gamepad_button =
GamepadButton::new(Gamepad::new(1), GamepadButtonType::RightTrigger);
let mut axis = Axis::<GamepadButton>::default(); let mut axis = Axis::<GamepadButton>::default();
axis.set(gamepad_button, value); axis.set(gamepad_button, value);

View file

@ -5,7 +5,15 @@ use bevy_utils::{tracing::info, HashMap, HashSet};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub struct Gamepad(pub usize); pub struct Gamepad {
pub id: usize,
}
impl Gamepad {
pub fn new(id: usize) -> Self {
Self { id }
}
}
#[derive(Default)] #[derive(Default)]
/// Container of unique connected [`Gamepad`]s /// Container of unique connected [`Gamepad`]s
@ -48,11 +56,35 @@ pub enum GamepadEventType {
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub struct GamepadEvent(pub Gamepad, pub GamepadEventType); pub struct GamepadEvent {
pub gamepad: Gamepad,
pub event_type: GamepadEventType,
}
impl GamepadEvent {
pub fn new(gamepad: Gamepad, event_type: GamepadEventType) -> Self {
Self {
gamepad,
event_type,
}
}
}
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub struct GamepadEventRaw(pub Gamepad, pub GamepadEventType); pub struct GamepadEventRaw {
pub gamepad: Gamepad,
pub event_type: GamepadEventType,
}
impl GamepadEventRaw {
pub fn new(gamepad: Gamepad, event_type: GamepadEventType) -> Self {
Self {
gamepad,
event_type,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
@ -80,7 +112,19 @@ pub enum GamepadButtonType {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub struct GamepadButton(pub Gamepad, pub GamepadButtonType); pub struct GamepadButton {
pub gamepad: Gamepad,
pub button_type: GamepadButtonType,
}
impl GamepadButton {
pub fn new(gamepad: Gamepad, button_type: GamepadButtonType) -> Self {
Self {
gamepad,
button_type,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
@ -97,7 +141,16 @@ pub enum GamepadAxisType {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub struct GamepadAxis(pub Gamepad, pub GamepadAxisType); pub struct GamepadAxis {
pub gamepad: Gamepad,
pub axis_type: GamepadAxisType,
}
impl GamepadAxis {
pub fn new(gamepad: Gamepad, axis_type: GamepadAxisType) -> Self {
Self { gamepad, axis_type }
}
}
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct GamepadSettings { pub struct GamepadSettings {
@ -251,14 +304,14 @@ pub fn gamepad_connection_system(
mut gamepad_event: EventReader<GamepadEvent>, mut gamepad_event: EventReader<GamepadEvent>,
) { ) {
for event in gamepad_event.iter() { for event in gamepad_event.iter() {
match &event { match event.event_type {
GamepadEvent(gamepad, GamepadEventType::Connected) => { GamepadEventType::Connected => {
gamepads.register(*gamepad); gamepads.register(event.gamepad);
info!("{:?} Connected", gamepad); info!("{:?} Connected", event.gamepad);
} }
GamepadEvent(gamepad, GamepadEventType::Disconnected) => { GamepadEventType::Disconnected => {
gamepads.deregister(gamepad); gamepads.deregister(&event.gamepad);
info!("{:?} Disconnected", gamepad); info!("{:?} Disconnected", event.gamepad);
} }
_ => (), _ => (),
} }
@ -275,62 +328,61 @@ pub fn gamepad_event_system(
) { ) {
button_input.clear(); button_input.clear();
for event in raw_events.iter() { for event in raw_events.iter() {
let (gamepad, event) = (event.0, &event.1); match event.event_type {
match event {
GamepadEventType::Connected => { GamepadEventType::Connected => {
events.send(GamepadEvent(gamepad, event.clone())); events.send(GamepadEvent::new(event.gamepad, event.event_type.clone()));
for button_type in &ALL_BUTTON_TYPES { for button_type in &ALL_BUTTON_TYPES {
let gamepad_button = GamepadButton(gamepad, *button_type); let gamepad_button = GamepadButton::new(event.gamepad, *button_type);
button_input.reset(gamepad_button); button_input.reset(gamepad_button);
button_axis.set(gamepad_button, 0.0); button_axis.set(gamepad_button, 0.0);
} }
for axis_type in &ALL_AXIS_TYPES { for axis_type in &ALL_AXIS_TYPES {
axis.set(GamepadAxis(gamepad, *axis_type), 0.0); axis.set(GamepadAxis::new(event.gamepad, *axis_type), 0.0);
} }
} }
GamepadEventType::Disconnected => { GamepadEventType::Disconnected => {
events.send(GamepadEvent(gamepad, event.clone())); events.send(GamepadEvent::new(event.gamepad, event.event_type.clone()));
for button_type in &ALL_BUTTON_TYPES { for button_type in &ALL_BUTTON_TYPES {
let gamepad_button = GamepadButton(gamepad, *button_type); let gamepad_button = GamepadButton::new(event.gamepad, *button_type);
button_input.reset(gamepad_button); button_input.reset(gamepad_button);
button_axis.remove(gamepad_button); button_axis.remove(gamepad_button);
} }
for axis_type in &ALL_AXIS_TYPES { for axis_type in &ALL_AXIS_TYPES {
axis.remove(GamepadAxis(gamepad, *axis_type)); axis.remove(GamepadAxis::new(event.gamepad, *axis_type));
} }
} }
GamepadEventType::AxisChanged(axis_type, value) => { GamepadEventType::AxisChanged(axis_type, value) => {
let gamepad_axis = GamepadAxis(gamepad, *axis_type); let gamepad_axis = GamepadAxis::new(event.gamepad, axis_type);
if let Some(filtered_value) = settings if let Some(filtered_value) = settings
.get_axis_settings(gamepad_axis) .get_axis_settings(gamepad_axis)
.filter(*value, axis.get(gamepad_axis)) .filter(value, axis.get(gamepad_axis))
{ {
axis.set(gamepad_axis, filtered_value); axis.set(gamepad_axis, filtered_value);
events.send(GamepadEvent( events.send(GamepadEvent::new(
gamepad, event.gamepad,
GamepadEventType::AxisChanged(*axis_type, filtered_value), GamepadEventType::AxisChanged(axis_type, filtered_value),
)); ));
} }
} }
GamepadEventType::ButtonChanged(button_type, value) => { GamepadEventType::ButtonChanged(button_type, value) => {
let gamepad_button = GamepadButton(gamepad, *button_type); let gamepad_button = GamepadButton::new(event.gamepad, button_type);
if let Some(filtered_value) = settings if let Some(filtered_value) = settings
.get_button_axis_settings(gamepad_button) .get_button_axis_settings(gamepad_button)
.filter(*value, button_axis.get(gamepad_button)) .filter(value, button_axis.get(gamepad_button))
{ {
button_axis.set(gamepad_button, filtered_value); button_axis.set(gamepad_button, filtered_value);
events.send(GamepadEvent( events.send(GamepadEvent::new(
gamepad, event.gamepad,
GamepadEventType::ButtonChanged(*button_type, filtered_value), GamepadEventType::ButtonChanged(button_type, filtered_value),
)); ));
} }
let button_property = settings.get_button_settings(gamepad_button); let button_property = settings.get_button_settings(gamepad_button);
if button_input.pressed(gamepad_button) { if button_input.pressed(gamepad_button) {
if button_property.is_released(*value) { if button_property.is_released(value) {
button_input.release(gamepad_button); button_input.release(gamepad_button);
} }
} else if button_property.is_pressed(*value) { } else if button_property.is_pressed(value) {
button_input.press(gamepad_button); button_input.press(gamepad_button);
} }
} }

View file

@ -14,21 +14,25 @@ fn gamepad_system(
axes: Res<Axis<GamepadAxis>>, axes: Res<Axis<GamepadAxis>>,
) { ) {
for gamepad in gamepads.iter().cloned() { for gamepad in gamepads.iter().cloned() {
if button_inputs.just_pressed(GamepadButton(gamepad, GamepadButtonType::South)) { if button_inputs.just_pressed(GamepadButton::new(gamepad, GamepadButtonType::South)) {
info!("{:?} just pressed South", gamepad); info!("{:?} just pressed South", gamepad);
} else if button_inputs.just_released(GamepadButton(gamepad, GamepadButtonType::South)) { } else if button_inputs.just_released(GamepadButton::new(gamepad, GamepadButtonType::South))
{
info!("{:?} just released South", gamepad); info!("{:?} just released South", gamepad);
} }
let right_trigger = button_axes let right_trigger = button_axes
.get(GamepadButton(gamepad, GamepadButtonType::RightTrigger2)) .get(GamepadButton::new(
gamepad,
GamepadButtonType::RightTrigger2,
))
.unwrap(); .unwrap();
if right_trigger.abs() > 0.01 { if right_trigger.abs() > 0.01 {
info!("{:?} RightTrigger2 value is {}", gamepad, right_trigger); info!("{:?} RightTrigger2 value is {}", gamepad, right_trigger);
} }
let left_stick_x = axes let left_stick_x = axes
.get(GamepadAxis(gamepad, GamepadAxisType::LeftStickX)) .get(GamepadAxis::new(gamepad, GamepadAxisType::LeftStickX))
.unwrap(); .unwrap();
if left_stick_x.abs() > 0.01 { if left_stick_x.abs() > 0.01 {
info!("{:?} LeftStickX value is {}", gamepad, left_stick_x); info!("{:?} LeftStickX value is {}", gamepad, left_stick_x);

View file

@ -12,18 +12,24 @@ fn main() {
fn gamepad_events(mut gamepad_event: EventReader<GamepadEvent>) { fn gamepad_events(mut gamepad_event: EventReader<GamepadEvent>) {
for event in gamepad_event.iter() { for event in gamepad_event.iter() {
match &event { match event.event_type {
GamepadEvent(gamepad, GamepadEventType::Connected) => { GamepadEventType::Connected => {
info!("{:?} Connected", gamepad); info!("{:?} Connected", event.gamepad);
} }
GamepadEvent(gamepad, GamepadEventType::Disconnected) => { GamepadEventType::Disconnected => {
info!("{:?} Disconnected", gamepad); info!("{:?} Disconnected", event.gamepad);
} }
GamepadEvent(gamepad, GamepadEventType::ButtonChanged(button_type, value)) => { GamepadEventType::ButtonChanged(button_type, value) => {
info!("{:?} of {:?} is changed to {}", button_type, gamepad, value); info!(
"{:?} of {:?} is changed to {}",
button_type, event.gamepad, value
);
} }
GamepadEvent(gamepad, GamepadEventType::AxisChanged(axis_type, value)) => { GamepadEventType::AxisChanged(axis_type, value) => {
info!("{:?} of {:?} is changed to {}", axis_type, gamepad, value); info!(
"{:?} of {:?} is changed to {}",
axis_type, event.gamepad, value
);
} }
} }
} }