shared/
held_key.rs

1use embassy_time::Timer;
2use futures::{future, future::Either, pin_mut};
3
4use crate::{Key, KeyEvent};
5
6#[derive(Clone, Debug, PartialEq)]
7pub enum Event {
8    Down(Key),
9    Delay(Key),
10    Repeat(Key),
11}
12
13pub struct HeldKey {
14    down: Option<Key>,
15    timer: Option<Timer>,
16    delay_duration: u64,
17    repeat_period: u64,
18    repeating: bool,
19}
20
21use core::fmt;
22
23impl fmt::Debug for HeldKey {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
25        #[allow(dead_code)]
26        #[derive(Debug)]
27        struct MySettings {
28            down: Option<Key>,
29            delay_duration: u64,
30            repeat_period: u64,
31            repeating: bool,
32        }
33
34        let Self {
35            down,
36            delay_duration,
37            repeat_period,
38            repeating,
39            ..
40        } = self;
41
42        fmt::Debug::fmt(
43            &MySettings {
44                down: down.clone(),
45                delay_duration: *delay_duration,
46                repeat_period: *repeat_period,
47                repeating: *repeating,
48            },
49            f,
50        )
51    }
52}
53
54impl HeldKey {
55    pub fn new(delay_duration: u64, repeat_period: u64) -> Self {
56        Self {
57            down: None,
58            timer: None,
59            delay_duration,
60            repeat_period,
61            repeating: false,
62        }
63    }
64
65    fn timeout_event(&mut self) -> Option<Event> {
66        let result = self.down.clone();
67
68        if self.repeating {
69            self.timer = Some(embassy_time::Timer::after_millis(self.repeat_period));
70            result.map(Event::Repeat)
71        } else {
72            self.repeating = true;
73            self.timer = Some(embassy_time::Timer::after_millis(self.repeat_period));
74            result.map(Event::Delay)
75        }
76    }
77
78    fn key_event(&mut self, key_event: KeyEvent) -> Option<Event> {
79        match key_event {
80            KeyEvent::Down(key) => {
81                self.timer = Some(embassy_time::Timer::after_millis(self.delay_duration));
82                self.down = Some(key.clone());
83                Some(Event::Down(key))
84            }
85            KeyEvent::Up(_key) => {
86                self.timer = None;
87                self.down = None;
88                self.repeating = false;
89                None
90            }
91        }
92    }
93
94    pub async fn event<KEYPAD>(&mut self, keypad: &mut KEYPAD) -> Option<Event>
95    where
96        KEYPAD: crate::Keypad,
97    {
98        let event_future = keypad.event();
99        pin_mut!(event_future);
100
101        if let Some(timer) = &mut self.timer {
102            match future::select(timer, event_future).await {
103                Either::Left((..)) => self.timeout_event(),
104                Either::Right((e, _)) => self.key_event(e),
105            }
106        } else {
107            self.key_event(event_future.await)
108        }
109    }
110}