lighthouse_protocol/input/
gamepad_axis_2d_event.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{Direction, Vec2};
4
5/// A 2D axis event on a gamepad.
6#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
7#[serde(tag = "control", rename_all = "camelCase")]
8pub struct GamepadAxis2DEvent {
9    /// The 2D axes index (0 is the left stick, 1 is the right stick).
10    pub index: usize,
11    /// The value of the axis (each component is between -1.0 and 1.0, modeled after the Web Gamepad API).
12    pub value: Vec2<f64>,
13}
14
15impl GamepadAxis2DEvent {
16    /// The approximate direction (outside of a small deadzone).
17    pub fn direction(&self) -> Option<Direction> {
18        let deadzone_radius: f64 = 0.1;
19        if self.value.length() < deadzone_radius {
20            return None;
21        }
22
23        Direction::approximate_from(self.value)
24    }
25}
26
27#[cfg(test)]
28mod tests {
29    use crate::{Direction, Vec2, Zero};
30
31    use super::GamepadAxis2DEvent;
32
33    #[test]
34    fn directions() {
35        assert_eq!(event(Vec2::UP).direction(), Some(Direction::Up));
36        assert_eq!(event(Vec2::DOWN).direction(), Some(Direction::Down));
37        assert_eq!(event(Vec2::LEFT).direction(), Some(Direction::Left));
38        assert_eq!(event(Vec2::RIGHT).direction(), Some(Direction::Right));
39        assert_eq!(event(Vec2::ZERO).direction(), None);
40        assert_eq!(event(Vec2::new(-0.05, 0.05)).direction(), None); // within deadzone
41    }
42
43    fn event(value: Vec2<f64>) -> GamepadAxis2DEvent {
44        GamepadAxis2DEvent {
45            index: 0,
46            value,
47        }
48    }
49}