Skip to main content

chargrid_gamepad/
lib.rs

1use chargrid_input::{GamepadButton, GamepadInput};
2use gilrs::{Button, EventType, Gilrs};
3
4fn event_type_to_gamepad_button(event_type: EventType) -> Option<GamepadButton> {
5    if let EventType::ButtonPressed(button, _code) = event_type {
6        let gamepad_button = match button {
7            Button::DPadUp => GamepadButton::DPadUp,
8            Button::DPadRight => GamepadButton::DPadRight,
9            Button::DPadDown => GamepadButton::DPadDown,
10            Button::DPadLeft => GamepadButton::DPadLeft,
11            Button::North => GamepadButton::North,
12            Button::East => GamepadButton::East,
13            Button::South => GamepadButton::South,
14            Button::West => GamepadButton::West,
15            Button::Start => GamepadButton::Start,
16            Button::Select => GamepadButton::Select,
17            Button::LeftTrigger => GamepadButton::LeftBumper,
18            Button::RightTrigger => GamepadButton::RightBumper,
19            _ => return None,
20        };
21        Some(gamepad_button)
22    } else {
23        None
24    }
25}
26
27pub struct GamepadContext {
28    gilrs: Option<Gilrs>,
29}
30
31impl Default for GamepadContext {
32    fn default() -> Self {
33        Self::new()
34    }
35}
36
37impl GamepadContext {
38    pub fn new() -> Self {
39        let gilrs = Gilrs::new();
40        match gilrs {
41            Err(ref err) => log::error!("Couldn't connect to controller: {}", err),
42            Ok(ref gilrs) => {
43                for (_id, gamepad) in gilrs.gamepads() {
44                    log::info!("{} is {:?}", gamepad.name(), gamepad.power_info());
45                }
46            }
47        }
48        Self { gilrs: gilrs.ok() }
49    }
50
51    pub fn drain_input(&mut self) -> GamepadDrainInput<'_> {
52        GamepadDrainInput {
53            gilrs: self.gilrs.as_mut(),
54        }
55    }
56}
57
58pub struct GamepadDrainInput<'a> {
59    gilrs: Option<&'a mut Gilrs>,
60}
61
62impl<'a> Iterator for GamepadDrainInput<'a> {
63    type Item = GamepadInput;
64    fn next(&mut self) -> Option<Self::Item> {
65        if let Some(ref mut gilrs) = self.gilrs {
66            loop {
67                if let Some(event) = gilrs.next_event() {
68                    if let Some(button) = event_type_to_gamepad_button(event.event) {
69                        let id_usize: usize = event.id.into();
70                        let id = id_usize as u64;
71                        return Some(GamepadInput { button, id });
72                    }
73                } else {
74                    return None;
75                }
76            }
77        } else {
78            None
79        }
80    }
81}