lighthouse_protocol/input/
input_event.rs

1use serde::{Deserialize, Serialize};
2
3use crate::Direction;
4
5use super::{EventSource, GamepadEvent, KeyEvent, MouseEvent};
6
7/// A user input event, as generated by the new frontend (LUNA).
8#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
9#[serde(tag = "type", rename_all = "camelCase")]
10pub enum InputEvent {
11    Key(KeyEvent),
12    Mouse(MouseEvent),
13    Gamepad(GamepadEvent),
14}
15
16impl InputEvent {
17    /// The event's source.
18    pub fn source(&self) -> &EventSource {
19        match self {
20            InputEvent::Key(KeyEvent { source, .. }) => source,
21            InputEvent::Mouse(MouseEvent { source, .. }) => source,
22            InputEvent::Gamepad(GamepadEvent { source, .. }) => source,
23        }
24    }
25
26    /// Parses the input event as an arbitrary direction.
27    pub fn direction(&self) -> Option<Direction> {
28        self.left_direction().or_else(|| self.right_direction())
29    }
30
31    /// The direction if the input event represents a WASD key, D-pad or left stick.
32    /// Commonly used e.g. for movement in games.
33    pub fn left_direction(&self) -> Option<Direction> {
34        match self {
35            InputEvent::Key(key) => key.wasd_direction(),
36            InputEvent::Gamepad(gamepad) => gamepad.left_direction(),
37            _ => None,
38        }
39    }
40
41    /// The direction if the input event represents an arrow key or right stick.
42    /// Commonly used e.g. for camera control in games.
43    pub fn right_direction(&self) -> Option<Direction> {
44        match self {
45            InputEvent::Key(key) => key.arrow_direction(),
46            InputEvent::Gamepad(gamepad) => gamepad.right_direction(),
47            _ => None,
48        }
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use serde_json::json;
55
56    use crate::{Delta, EventSource, GamepadAxis2DEvent, GamepadAxisEvent, GamepadButtonEvent, GamepadControlEvent, GamepadEvent, InputEvent, KeyEvent, KeyModifiers, MouseButton, MouseEvent, Pos, Vec2};
57
58    #[test]
59    fn key_event() {
60        assert_eq!(
61            serde_json::from_value::<InputEvent>(json!({
62                "type": "key",
63                "source": 0,
64                "down": true,
65                "repeat": false,
66                "code": "ArrowUp",
67                "modifiers": {
68                    "alt": false,
69                    "ctrl": false,
70                    "meta": false,
71                    "shift": false,
72                },
73            })).unwrap(),
74            InputEvent::Key(KeyEvent {
75                source: EventSource::Int(0),
76                down: true,
77                repeat: false,
78                code: "ArrowUp".into(),
79                modifiers: KeyModifiers::default(),
80            })
81        );
82    }
83
84    #[test]
85    fn mouse_event() {
86        assert_eq!(
87            serde_json::from_value::<InputEvent>(json!({
88                "type": "mouse",
89                "source": 1,
90                "button": "left",
91                "down": true,
92                "pointerLocked": false,
93                "pos": {
94                    "x": 2,
95                    "y": 4,
96                },
97                "movement": {
98                    "x": 6,
99                    "y": -3,
100                },
101            })).unwrap(),
102            InputEvent::Mouse(MouseEvent {
103                source: EventSource::Int(1),
104                button: MouseButton::Left,
105                down: true,
106                pointer_locked: false,
107                pos: Pos::new(2.0, 4.0),
108                movement: Delta::new(6.0, -3.0),
109            })
110        );
111    }
112
113    #[test]
114    fn gamepad_button_event() {
115        assert_eq!(
116            serde_json::from_value::<InputEvent>(json!({
117                "type": "gamepad",
118                "source": 1,
119                "control": "button",
120                "index": 42,
121                "down": true,
122                "value": 0.25,
123            })).unwrap(),
124            InputEvent::Gamepad(GamepadEvent {
125                source: EventSource::Int(1),
126                control: GamepadControlEvent::Button(GamepadButtonEvent {
127                    index: 42,
128                    down: true,
129                    value: 0.25,
130                }),
131            })
132        );
133    }
134
135    #[test]
136    fn gamepad_axis_event() {
137        assert_eq!(
138            serde_json::from_value::<InputEvent>(json!({
139                "type": "gamepad",
140                "source": 1,
141                "control": "axis",
142                "index": 42,
143                "value": 0.25,
144            })).unwrap(),
145            InputEvent::Gamepad(GamepadEvent {
146                source: EventSource::Int(1),
147                control: GamepadControlEvent::Axis(GamepadAxisEvent {
148                    index: 42,
149                    value: 0.25,
150                }),
151            })
152        );
153    }
154
155    #[test]
156    fn gamepad_axis_2d_event() {
157        assert_eq!(
158            serde_json::from_value::<InputEvent>(json!({
159                "type": "gamepad",
160                "source": 1,
161                "control": "axis2d",
162                "index": 42,
163                "value": {
164                    "x": 0.2,
165                    "y": -0.2,
166                },
167            })).unwrap(),
168            InputEvent::Gamepad(GamepadEvent {
169                source: EventSource::Int(1),
170                control: GamepadControlEvent::Axis2D(GamepadAxis2DEvent {
171                    index: 42,
172                    value: Vec2::new(0.2, -0.2),
173                }),
174            })
175        );
176    }
177}