Skip to content

Commit

Permalink
Change gamepad.rs tuples to normal structs (bevyengine#4519)
Browse files Browse the repository at this point in the history
# Objective

- Part of the splitting process of bevyengine#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`.
  • Loading branch information
KDecay authored and ItsDoot committed Feb 1, 2023
1 parent 164afda commit c7948b3
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 53 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_gilrs/src/converter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use bevy_input::gamepad::{Gamepad, GamepadAxisType, GamepadButtonType};

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> {
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_gilrs/src/gilrs_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use gilrs::{EventType, Gilrs};

pub fn gilrs_event_startup_system(gilrs: NonSend<Gilrs>, mut events: EventWriter<GamepadEventRaw>) {
for (id, _) in gilrs.gamepads() {
events.send(GamepadEventRaw(
events.send(GamepadEventRaw::new(
convert_gamepad_id(id),
GamepadEventType::Connected,
));
Expand All @@ -17,28 +17,28 @@ pub fn gilrs_event_system(mut gilrs: NonSendMut<Gilrs>, mut events: EventWriter<
while let Some(gilrs_event) = gilrs.next_event() {
match gilrs_event.event {
EventType::Connected => {
events.send(GamepadEventRaw(
events.send(GamepadEventRaw::new(
convert_gamepad_id(gilrs_event.id),
GamepadEventType::Connected,
));
}
EventType::Disconnected => {
events.send(GamepadEventRaw(
events.send(GamepadEventRaw::new(
convert_gamepad_id(gilrs_event.id),
GamepadEventType::Disconnected,
));
}
EventType::ButtonChanged(gilrs_button, value, _) => {
if let Some(button_type) = convert_button(gilrs_button) {
events.send(GamepadEventRaw(
events.send(GamepadEventRaw::new(
convert_gamepad_id(gilrs_event.id),
GamepadEventType::ButtonChanged(button_type, value),
));
}
}
EventType::AxisChanged(gilrs_axis, value, _) => {
if let Some(axis_type) = convert_axis(gilrs_axis) {
events.send(GamepadEventRaw(
events.send(GamepadEventRaw::new(
convert_gamepad_id(gilrs_event.id),
GamepadEventType::AxisChanged(axis_type, value),
));
Expand Down
6 changes: 4 additions & 2 deletions crates/bevy_input/src/axis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ mod tests {
];

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();

axis.set(gamepad_button, value);
Expand All @@ -92,7 +93,8 @@ mod tests {
let cases = [-1.0, -0.9, -0.1, 0.0, 0.1, 0.9, 1.0];

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();

axis.set(gamepad_button, value);
Expand Down
116 changes: 84 additions & 32 deletions crates/bevy_input/src/gamepad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ use bevy_utils::{tracing::info, HashMap, HashSet};

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[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)]
/// Container of unique connected [`Gamepad`]s
Expand Down Expand Up @@ -48,11 +56,35 @@ pub enum GamepadEventType {

#[derive(Debug, Clone, PartialEq)]
#[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)]
#[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)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
Expand Down Expand Up @@ -80,7 +112,19 @@ pub enum GamepadButtonType {

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[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)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
Expand All @@ -97,7 +141,16 @@ pub enum GamepadAxisType {

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[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)]
pub struct GamepadSettings {
Expand Down Expand Up @@ -251,14 +304,14 @@ pub fn gamepad_connection_system(
mut gamepad_event: EventReader<GamepadEvent>,
) {
for event in gamepad_event.iter() {
match &event {
GamepadEvent(gamepad, GamepadEventType::Connected) => {
gamepads.register(*gamepad);
info!("{:?} Connected", gamepad);
match event.event_type {
GamepadEventType::Connected => {
gamepads.register(event.gamepad);
info!("{:?} Connected", event.gamepad);
}
GamepadEvent(gamepad, GamepadEventType::Disconnected) => {
gamepads.deregister(gamepad);
info!("{:?} Disconnected", gamepad);
GamepadEventType::Disconnected => {
gamepads.deregister(&event.gamepad);
info!("{:?} Disconnected", event.gamepad);
}
_ => (),
}
Expand All @@ -275,62 +328,61 @@ pub fn gamepad_event_system(
) {
button_input.clear();
for event in raw_events.iter() {
let (gamepad, event) = (event.0, &event.1);
match event {
match event.event_type {
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 {
let gamepad_button = GamepadButton(gamepad, *button_type);
let gamepad_button = GamepadButton::new(event.gamepad, *button_type);
button_input.reset(gamepad_button);
button_axis.set(gamepad_button, 0.0);
}
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 => {
events.send(GamepadEvent(gamepad, event.clone()));
events.send(GamepadEvent::new(event.gamepad, event.event_type.clone()));
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_axis.remove(gamepad_button);
}
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) => {
let gamepad_axis = GamepadAxis(gamepad, *axis_type);
let gamepad_axis = GamepadAxis::new(event.gamepad, axis_type);
if let Some(filtered_value) = settings
.get_axis_settings(gamepad_axis)
.filter(*value, axis.get(gamepad_axis))
.filter(value, axis.get(gamepad_axis))
{
axis.set(gamepad_axis, filtered_value);
events.send(GamepadEvent(
gamepad,
GamepadEventType::AxisChanged(*axis_type, filtered_value),
events.send(GamepadEvent::new(
event.gamepad,
GamepadEventType::AxisChanged(axis_type, filtered_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
.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);
events.send(GamepadEvent(
gamepad,
GamepadEventType::ButtonChanged(*button_type, filtered_value),
events.send(GamepadEvent::new(
event.gamepad,
GamepadEventType::ButtonChanged(button_type, filtered_value),
));
}

let button_property = settings.get_button_settings(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);
}
} else if button_property.is_pressed(*value) {
} else if button_property.is_pressed(value) {
button_input.press(gamepad_button);
}
}
Expand Down
12 changes: 8 additions & 4 deletions examples/input/gamepad_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,25 @@ fn gamepad_system(
axes: Res<Axis<GamepadAxis>>,
) {
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);
} 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);
}

let right_trigger = button_axes
.get(GamepadButton(gamepad, GamepadButtonType::RightTrigger2))
.get(GamepadButton::new(
gamepad,
GamepadButtonType::RightTrigger2,
))
.unwrap();
if right_trigger.abs() > 0.01 {
info!("{:?} RightTrigger2 value is {}", gamepad, right_trigger);
}

let left_stick_x = axes
.get(GamepadAxis(gamepad, GamepadAxisType::LeftStickX))
.get(GamepadAxis::new(gamepad, GamepadAxisType::LeftStickX))
.unwrap();
if left_stick_x.abs() > 0.01 {
info!("{:?} LeftStickX value is {}", gamepad, left_stick_x);
Expand Down
24 changes: 15 additions & 9 deletions examples/input/gamepad_input_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,24 @@ fn main() {

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

0 comments on commit c7948b3

Please sign in to comment.