lighthouse_protocol/input/
input_event.rs

1use serde::{Deserialize, Serialize};
2
3use crate::Direction;
4
5use super::{EventSource, GamepadEvent, KeyEvent, MidiEvent, MotionEvent, MouseEvent, OrientationEvent, UnknownEvent};
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    Midi(MidiEvent),
15    Orientation(OrientationEvent),
16    Motion(MotionEvent),
17    #[serde(untagged)]
18    Unknown(UnknownEvent),
19}
20
21impl InputEvent {
22    /// The event's source.
23    pub fn source(&self) -> &EventSource {
24        match self {
25            InputEvent::Key(KeyEvent { source, .. }) => source,
26            InputEvent::Mouse(MouseEvent { source, .. }) => source,
27            InputEvent::Gamepad(GamepadEvent { source, .. }) => source,
28            InputEvent::Orientation(OrientationEvent { source, .. }) => source,
29            InputEvent::Motion(MotionEvent { source, .. }) => source,
30            InputEvent::Midi(MidiEvent { source, .. }) => source,
31            InputEvent::Unknown(UnknownEvent { source, .. }) => source,
32        }
33    }
34
35    /// Parses the input event as an arbitrary direction.
36    pub fn direction(&self) -> Option<Direction> {
37        match self {
38            InputEvent::Orientation(orientation) => orientation.direction(),
39            _ => self.left_direction().or_else(|| self.right_direction()),
40        }
41    }
42
43    /// The direction if the input event represents a WASD key, D-pad or left stick.
44    /// Commonly used e.g. for movement in games.
45    pub fn left_direction(&self) -> Option<Direction> {
46        match self {
47            InputEvent::Key(key) => key.wasd_direction(),
48            InputEvent::Gamepad(gamepad) => gamepad.left_direction(),
49            _ => None,
50        }
51    }
52
53    /// The direction if the input event represents an arrow key or right stick.
54    /// Commonly used e.g. for camera control in games.
55    pub fn right_direction(&self) -> Option<Direction> {
56        match self {
57            InputEvent::Key(key) => key.arrow_direction(),
58            InputEvent::Gamepad(gamepad) => gamepad.right_direction(),
59            _ => None,
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use serde_json::json;
67
68    use crate::{Delta, EventSource, GamepadAxis2DEvent, GamepadAxisEvent, GamepadButtonEvent, GamepadControlEvent, GamepadEvent, InputEvent, KeyEvent, KeyModifiers, MouseButton, MouseEvent, OrientationEvent, Pos, UnknownEvent, Vec2};
69
70    #[test]
71    fn key_event() {
72        assert_eq!(
73            serde_json::from_value::<InputEvent>(json!({
74                "type": "key",
75                "source": 0,
76                "down": true,
77                "repeat": false,
78                "code": "ArrowUp",
79                "modifiers": {
80                    "alt": false,
81                    "ctrl": false,
82                    "meta": false,
83                    "shift": false,
84                },
85            })).unwrap(),
86            InputEvent::Key(KeyEvent {
87                source: EventSource::Int(0),
88                down: true,
89                repeat: false,
90                code: "ArrowUp".into(),
91                modifiers: KeyModifiers::default(),
92            })
93        );
94    }
95
96    #[test]
97    fn mouse_event() {
98        assert_eq!(
99            serde_json::from_value::<InputEvent>(json!({
100                "type": "mouse",
101                "source": 1,
102                "button": "left",
103                "down": true,
104                "pointerLocked": false,
105                "pos": {
106                    "x": 2,
107                    "y": 4,
108                },
109                "movement": {
110                    "x": 6,
111                    "y": -3,
112                },
113            })).unwrap(),
114            InputEvent::Mouse(MouseEvent {
115                source: EventSource::Int(1),
116                button: MouseButton::Left,
117                down: true,
118                pointer_locked: false,
119                pos: Pos::new(2.0, 4.0),
120                movement: Delta::new(6.0, -3.0),
121            })
122        );
123    }
124
125    #[test]
126    fn gamepad_button_event() {
127        assert_eq!(
128            serde_json::from_value::<InputEvent>(json!({
129                "type": "gamepad",
130                "source": 1,
131                "control": "button",
132                "index": 42,
133                "down": true,
134                "value": 0.25,
135            })).unwrap(),
136            InputEvent::Gamepad(GamepadEvent {
137                source: EventSource::Int(1),
138                control: GamepadControlEvent::Button(GamepadButtonEvent {
139                    index: 42,
140                    down: true,
141                    value: 0.25,
142                }),
143            })
144        );
145    }
146
147    #[test]
148    fn gamepad_axis_event() {
149        assert_eq!(
150            serde_json::from_value::<InputEvent>(json!({
151                "type": "gamepad",
152                "source": 1,
153                "control": "axis",
154                "index": 42,
155                "value": 0.25,
156            })).unwrap(),
157            InputEvent::Gamepad(GamepadEvent {
158                source: EventSource::Int(1),
159                control: GamepadControlEvent::Axis(GamepadAxisEvent {
160                    index: 42,
161                    value: 0.25,
162                }),
163            })
164        );
165    }
166
167    #[test]
168    fn gamepad_axis_2d_event() {
169        assert_eq!(
170            serde_json::from_value::<InputEvent>(json!({
171                "type": "gamepad",
172                "source": 1,
173                "control": "axis2d",
174                "index": 42,
175                "value": {
176                    "x": 0.2,
177                    "y": -0.2,
178                },
179            })).unwrap(),
180            InputEvent::Gamepad(GamepadEvent {
181                source: EventSource::Int(1),
182                control: GamepadControlEvent::Axis2D(GamepadAxis2DEvent {
183                    index: 42,
184                    value: Vec2::new(0.2, -0.2),
185                }),
186            })
187        );
188    }
189
190    #[test]
191    fn orientation_event() {
192        assert_eq!(
193            serde_json::from_value::<InputEvent>(json!({
194                "type": "orientation",
195                "source": 1,
196                "absolute": false,
197                "alpha": null,
198                "beta": 3.0,
199                "gamma": -10.0,
200            })).unwrap(),
201            InputEvent::Orientation(OrientationEvent {
202                source: EventSource::Int(1),
203                absolute: Some(false),
204                alpha: None,
205                beta: Some(3.0),
206                gamma: Some(-10.0),
207            })
208        )
209    }
210
211    #[test]
212    fn unknown_event() {
213        assert_eq!(
214            serde_json::from_value::<InputEvent>(json!({
215                "type": "someEventWeDoNotKnowAbout",
216                "source": 1,
217                "possibly": "abc",
218                "more": "def",
219                "fields": "ghi"
220            })).unwrap(),
221            InputEvent::Unknown(UnknownEvent {
222                source: EventSource::Int(1),
223                event_type: "someEventWeDoNotKnowAbout".into(),
224            })
225        )
226    }
227}