use serde::{Deserialize, Serialize};
use crate::Direction;
use super::{EventSource, GamepadEvent, KeyEvent, MidiEvent, MotionEvent, MouseEvent, OrientationEvent, UnknownEvent};
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum InputEvent {
Key(KeyEvent),
Mouse(MouseEvent),
Gamepad(GamepadEvent),
Midi(MidiEvent),
Orientation(OrientationEvent),
Motion(MotionEvent),
#[serde(untagged)]
Unknown(UnknownEvent),
}
impl InputEvent {
pub fn source(&self) -> &EventSource {
match self {
InputEvent::Key(KeyEvent { source, .. }) => source,
InputEvent::Mouse(MouseEvent { source, .. }) => source,
InputEvent::Gamepad(GamepadEvent { source, .. }) => source,
InputEvent::Orientation(OrientationEvent { source, .. }) => source,
InputEvent::Motion(MotionEvent { source, .. }) => source,
InputEvent::Midi(MidiEvent { source, .. }) => source,
InputEvent::Unknown(UnknownEvent { source, .. }) => source,
}
}
pub fn direction(&self) -> Option<Direction> {
match self {
InputEvent::Orientation(orientation) => orientation.direction(),
_ => self.left_direction().or_else(|| self.right_direction()),
}
}
pub fn left_direction(&self) -> Option<Direction> {
match self {
InputEvent::Key(key) => key.wasd_direction(),
InputEvent::Gamepad(gamepad) => gamepad.left_direction(),
_ => None,
}
}
pub fn right_direction(&self) -> Option<Direction> {
match self {
InputEvent::Key(key) => key.arrow_direction(),
InputEvent::Gamepad(gamepad) => gamepad.right_direction(),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use serde_json::json;
use crate::{Delta, EventSource, GamepadAxis2DEvent, GamepadAxisEvent, GamepadButtonEvent, GamepadControlEvent, GamepadEvent, InputEvent, KeyEvent, KeyModifiers, MouseButton, MouseEvent, OrientationEvent, Pos, UnknownEvent, Vec2};
#[test]
fn key_event() {
assert_eq!(
serde_json::from_value::<InputEvent>(json!({
"type": "key",
"source": 0,
"down": true,
"repeat": false,
"code": "ArrowUp",
"modifiers": {
"alt": false,
"ctrl": false,
"meta": false,
"shift": false,
},
})).unwrap(),
InputEvent::Key(KeyEvent {
source: EventSource::Int(0),
down: true,
repeat: false,
code: "ArrowUp".into(),
modifiers: KeyModifiers::default(),
})
);
}
#[test]
fn mouse_event() {
assert_eq!(
serde_json::from_value::<InputEvent>(json!({
"type": "mouse",
"source": 1,
"button": "left",
"down": true,
"pointerLocked": false,
"pos": {
"x": 2,
"y": 4,
},
"movement": {
"x": 6,
"y": -3,
},
})).unwrap(),
InputEvent::Mouse(MouseEvent {
source: EventSource::Int(1),
button: MouseButton::Left,
down: true,
pointer_locked: false,
pos: Pos::new(2.0, 4.0),
movement: Delta::new(6.0, -3.0),
})
);
}
#[test]
fn gamepad_button_event() {
assert_eq!(
serde_json::from_value::<InputEvent>(json!({
"type": "gamepad",
"source": 1,
"control": "button",
"index": 42,
"down": true,
"value": 0.25,
})).unwrap(),
InputEvent::Gamepad(GamepadEvent {
source: EventSource::Int(1),
control: GamepadControlEvent::Button(GamepadButtonEvent {
index: 42,
down: true,
value: 0.25,
}),
})
);
}
#[test]
fn gamepad_axis_event() {
assert_eq!(
serde_json::from_value::<InputEvent>(json!({
"type": "gamepad",
"source": 1,
"control": "axis",
"index": 42,
"value": 0.25,
})).unwrap(),
InputEvent::Gamepad(GamepadEvent {
source: EventSource::Int(1),
control: GamepadControlEvent::Axis(GamepadAxisEvent {
index: 42,
value: 0.25,
}),
})
);
}
#[test]
fn gamepad_axis_2d_event() {
assert_eq!(
serde_json::from_value::<InputEvent>(json!({
"type": "gamepad",
"source": 1,
"control": "axis2d",
"index": 42,
"value": {
"x": 0.2,
"y": -0.2,
},
})).unwrap(),
InputEvent::Gamepad(GamepadEvent {
source: EventSource::Int(1),
control: GamepadControlEvent::Axis2D(GamepadAxis2DEvent {
index: 42,
value: Vec2::new(0.2, -0.2),
}),
})
);
}
#[test]
fn orientation_event() {
assert_eq!(
serde_json::from_value::<InputEvent>(json!({
"type": "orientation",
"source": 1,
"absolute": false,
"alpha": null,
"beta": 3.0,
"gamma": -10.0,
})).unwrap(),
InputEvent::Orientation(OrientationEvent {
source: EventSource::Int(1),
absolute: Some(false),
alpha: None,
beta: Some(3.0),
gamma: Some(-10.0),
})
)
}
#[test]
fn unknown_event() {
assert_eq!(
serde_json::from_value::<InputEvent>(json!({
"type": "someEventWeDoNotKnowAbout",
"source": 1,
"possibly": "abc",
"more": "def",
"fields": "ghi"
})).unwrap(),
InputEvent::Unknown(UnknownEvent {
source: EventSource::Int(1),
event_type: "someEventWeDoNotKnowAbout".into(),
})
)
}
}