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}