Skip to main content

smart_keymap_core/keymap/
observed_eb_keymap.rs

1use core::fmt::Debug;
2use core::ops::Index;
3
4use crate::input;
5use crate::key;
6use crate::keymap;
7
8use keymap::Keymap;
9use keymap::SetKeymapContext;
10
11/// Wrapper around a [crate::keymap::Keymap] that also tracks distinct HID reports.
12#[derive(Debug)]
13pub struct ObservedKeymap<I: Index<usize, Output = R>, R, Ctx, Ev: Debug, PKS, KS, S> {
14    keymap: Keymap<I, R, Ctx, Ev, PKS, KS, S>,
15    distinct_reports: keymap::DistinctReports,
16}
17
18impl<
19        I: Debug + Index<usize, Output = R>,
20        R: Copy + Debug,
21        Ctx: Debug + key::Context<Event = Ev> + SetKeymapContext,
22        Ev: Copy + Debug,
23        PKS: Debug,
24        KS: Copy + Debug + From<key::NoOpKeyState>,
25        S: key::System<R, Ref = R, Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS>,
26    > ObservedKeymap<I, R, Ctx, Ev, PKS, KS, S>
27{
28    /// Constructs an observed keymap with a new [keymap::DistinctReports].
29    pub fn new(keymap: Keymap<I, R, Ctx, Ev, PKS, KS, S>) -> Self {
30        ObservedKeymap {
31            keymap,
32            distinct_reports: keymap::DistinctReports::new(),
33        }
34    }
35
36    /// Proxies [keymap::Keymap::handle_input_after_time], `tick`'ing the keymap appropriately.
37    pub fn handle_input_after_time(&mut self, delta_ms: u32, ev: input::Event) -> Option<u32> {
38        let ObservedKeymap {
39            keymap,
40            distinct_reports,
41        } = self;
42
43        let next_ev = keymap.handle_input_after_time(delta_ms, ev);
44
45        distinct_reports.update(keymap.report_output().as_hid_boot_keyboard_report());
46
47        // Clear input-queue pacing so a follow-up handle_input can process next.
48        keymap.tick();
49        distinct_reports.update(keymap.report_output().as_hid_boot_keyboard_report());
50
51        next_ev
52    }
53
54    /// Proxies [keymap::Keymap::tick_to_next_scheduled_event], updating reports appropriately.
55    pub fn tick_to_next_scheduled_event(&mut self) -> Option<u32> {
56        let ObservedKeymap {
57            keymap,
58            distinct_reports,
59        } = self;
60
61        let next_ev = keymap.tick_to_next_scheduled_event();
62
63        distinct_reports.update(keymap.report_output().as_hid_boot_keyboard_report());
64
65        next_ev
66    }
67
68    /// Proxies [keymap::Keymap::boot_keyboard_report].
69    pub fn boot_keyboard_report(&self) -> [u8; 8] {
70        let ObservedKeymap { keymap, .. } = self;
71
72        keymap::KeymapOutput::new(keymap.pressed_keys()).as_hid_boot_keyboard_report()
73    }
74
75    /// Reference to distinct reports.
76    pub fn distinct_reports(&self) -> &keymap::DistinctReports {
77        &self.distinct_reports
78    }
79
80    /// Ticks the keymap until there are no scheduled events, updating reports appropriately.
81    pub fn tick_until_no_scheduled_events(&mut self) {
82        let ObservedKeymap {
83            keymap,
84            distinct_reports,
85        } = self;
86
87        while keymap.has_scheduled_events() {
88            keymap.tick();
89            distinct_reports.update(keymap.report_output().as_hid_boot_keyboard_report());
90        }
91    }
92
93    /// Proxies [keymap::Keymap::requires_polling].
94    pub fn requires_polling(&self) -> bool {
95        let ObservedKeymap { keymap, .. } = self;
96
97        keymap.requires_polling()
98    }
99
100    /// Proxies [keymap::Keymap::tick], updating reports appropriately.
101    pub fn tick(&mut self) {
102        let ObservedKeymap {
103            keymap,
104            distinct_reports,
105        } = self;
106
107        keymap.tick();
108        distinct_reports.update(keymap.report_output().as_hid_boot_keyboard_report());
109    }
110}