arci/clients/
dummy_gamepad.rs

1use std::{future, sync::Mutex};
2
3use async_trait::async_trait;
4
5use crate::gamepad::{Axis, Button, Gamepad, GamepadEvent};
6
7/// Dummy Gamepad for debug or tests.
8#[derive(Debug)]
9pub struct DummyGamepad {
10    pub events: Vec<GamepadEvent>,
11    index: Mutex<usize>,
12    stopped: Mutex<bool>,
13}
14
15impl DummyGamepad {
16    /// Creates a new `DummyGamepad` which returns the given events.
17    pub fn new(events: Vec<GamepadEvent>) -> Self {
18        Self {
19            events,
20            index: Mutex::default(),
21            stopped: Mutex::default(),
22        }
23    }
24
25    /// Creates a new `DummyGamepad` which returns all patterns of the GamepadEvent.
26    pub fn with_all_events() -> Self {
27        const ALL_BUTTONS: &[Button] = &[
28            Button::South,
29            Button::East,
30            Button::North,
31            Button::West,
32            Button::LeftTrigger,
33            Button::LeftTrigger2,
34            Button::RightTrigger,
35            Button::RightTrigger2,
36            Button::Select,
37            Button::Start,
38            Button::Mode,
39            Button::LeftThumb,
40            Button::RightThumb,
41            Button::DPadUp,
42            Button::DPadDown,
43            Button::DPadLeft,
44            Button::DPadRight,
45            Button::Unknown,
46        ];
47        const ALL_AXIS: &[Axis] = &[
48            Axis::LeftStickX,
49            Axis::LeftStickY,
50            Axis::LeftTrigger,
51            Axis::RightStickX,
52            Axis::RightStickY,
53            Axis::RightTrigger,
54            Axis::DPadX,
55            Axis::DPadY,
56            Axis::Unknown,
57        ];
58
59        let mut events = vec![];
60        for &b in ALL_BUTTONS {
61            events.push(GamepadEvent::ButtonPressed(b));
62        }
63        for &b in ALL_BUTTONS {
64            events.push(GamepadEvent::ButtonReleased(b));
65        }
66        for &a in ALL_AXIS {
67            events.push(GamepadEvent::AxisChanged(a, 1.0));
68            events.push(GamepadEvent::AxisChanged(a, 0.0));
69            events.push(GamepadEvent::AxisChanged(a, -1.0));
70        }
71        events.push(GamepadEvent::Unknown);
72        Self::new(events)
73    }
74
75    pub fn is_stopped(&self) -> bool {
76        *self.stopped.lock().unwrap()
77    }
78}
79
80#[async_trait]
81impl Gamepad for DummyGamepad {
82    async fn next_event(&self) -> GamepadEvent {
83        *self.stopped.lock().unwrap() = false;
84        {
85            let mut index = self.index.lock().unwrap();
86            if let Some(event) = self.events.get(*index).cloned() {
87                *index += 1;
88                return event;
89            }
90        }
91        future::pending::<()>().await;
92        unreachable!()
93    }
94
95    fn stop(&self) {
96        *self.stopped.lock().unwrap() = true;
97    }
98}