1#[cfg(feature = "std")]
2mod distinct_reports;
3mod event_scheduler;
4pub mod hid_keyboard_reporter;
6#[cfg(feature = "std")]
7mod observed_eb_keymap;
8#[cfg(feature = "std")]
9mod observed_keymap;
10
11use core::cmp::PartialEq;
12use core::fmt::Debug;
13use core::marker::Copy;
14use core::ops::Index;
15
16use serde::Deserialize;
17
18use crate::input;
19use crate::key;
20
21use key::Event;
22
23#[cfg(feature = "std")]
24pub use distinct_reports::DistinctReports;
25use event_scheduler::EventScheduler;
26use hid_keyboard_reporter::HIDKeyboardReporter;
27#[cfg(feature = "std")]
28pub use observed_eb_keymap::ObservedKeymap as ObservedEventBasedKeymap;
29#[cfg(feature = "std")]
30pub use observed_keymap::ObservedKeymap;
31
32pub const MAX_PRESSED_KEYS: usize = 16;
34
35const MAX_QUEUED_INPUT_EVENTS: usize = 32;
36
37pub const INPUT_QUEUE_TICK_DELAY: u8 = 1;
39
40#[derive(Debug, PartialEq)]
42pub struct KeymapOutput {
43 pressed_key_codes: heapless::Vec<key::KeyOutput, { MAX_PRESSED_KEYS }>,
44}
45
46impl Default for KeymapOutput {
47 fn default() -> Self {
48 Self {
49 pressed_key_codes: heapless::Vec::new(),
50 }
51 }
52}
53
54impl KeymapOutput {
55 pub fn new(pressed_key_codes: heapless::Vec<key::KeyOutput, { MAX_PRESSED_KEYS }>) -> Self {
57 Self { pressed_key_codes }
58 }
59
60 pub fn pressed_key_codes(&self) -> heapless::Vec<u8, 24> {
62 let mut result = heapless::Vec::new();
63
64 let modifiers = self
65 .pressed_key_codes
66 .iter()
67 .fold(key::KeyboardModifiers::new(), |acc, &ko| {
68 acc.union(&ko.key_modifiers())
69 });
70
71 result.extend(modifiers.as_key_codes());
72
73 result.extend(
74 self.pressed_key_codes
75 .iter()
76 .flat_map(|ko| match ko.key_code() {
77 key::KeyUsage::Keyboard(kc) => Some(kc),
78 _ => None,
79 }),
80 );
81
82 result
83 }
84
85 pub fn as_hid_boot_keyboard_report(&self) -> [u8; 8] {
87 let mut report = [0u8; 8];
88
89 let modifiers = self
90 .pressed_key_codes
91 .iter()
92 .fold(key::KeyboardModifiers::new(), |acc, &ko| {
93 acc.union(&ko.key_modifiers())
94 });
95
96 report[0] = modifiers.as_byte();
97
98 let key_codes = self
99 .pressed_key_codes
100 .iter()
101 .flat_map(|ko| match ko.key_code() {
102 key::KeyUsage::Keyboard(kc) => Some(kc),
103 _ => None,
104 })
105 .filter(|&kc| kc != 0);
106
107 for (i, key_code) in key_codes.take(6).enumerate() {
108 report[i + 2] = key_code;
109 }
110
111 report
112 }
113
114 pub fn pressed_consumer_codes(&self) -> heapless::Vec<u8, 24> {
116 self.pressed_key_codes
117 .iter()
118 .flat_map(|ko| match ko.key_code() {
119 key::KeyUsage::Consumer(uc) => Some(uc),
120 _ => None,
121 })
122 .collect()
123 }
124
125 pub fn pressed_custom_codes(&self) -> heapless::Vec<u8, 24> {
127 self.pressed_key_codes
128 .iter()
129 .flat_map(|ko| match ko.key_code() {
130 key::KeyUsage::Custom(kc) => Some(kc),
131 _ => None,
132 })
133 .collect()
134 }
135
136 pub fn pressed_mouse_output(&self) -> key::MouseOutput {
138 self.pressed_key_codes
139 .iter()
140 .filter_map(|ko| match ko.key_code() {
141 key::KeyUsage::Mouse(mo) => Some(mo),
142 _ => None,
143 })
144 .fold(key::MouseOutput::NO_OUTPUT, |acc, mo| acc.combine(&mo))
145 }
146}
147
148#[derive(Debug)]
149struct PendingState<R, Ev, PKS> {
150 keymap_index: u16,
151 key_ref: R,
152 pending_key_state: PKS,
153 queued_events: heapless::Vec<key::Event<Ev>, { MAX_PRESSED_KEYS }>,
154}
155
156#[derive(Deserialize, Debug, Clone, Copy, Eq, PartialEq)]
158pub enum BluetoothProfileCommand {
159 Disconnect,
161 Clear,
163 ClearAll,
165 Previous,
167 Next,
169 Select(u8),
171}
172
173#[derive(Deserialize, Debug, Clone, Copy, Eq, PartialEq)]
175pub enum KeymapCallback {
176 Reset,
178 ResetToBootloader,
180 Bluetooth(BluetoothProfileCommand),
182 Custom(u8, u8),
184}
185
186#[derive(Debug, Clone, Copy)]
188pub struct KeymapContext {
189 pub time_ms: u32,
191
192 pub idle_time_ms: u32,
194}
195
196impl KeymapContext {
197 pub const fn new() -> Self {
199 KeymapContext {
200 time_ms: 0,
201 idle_time_ms: 0,
202 }
203 }
204}
205
206pub trait SetKeymapContext {
208 fn set_keymap_context(&mut self, context: KeymapContext);
210}
211
212#[derive(Debug, Clone, Copy, PartialEq, Eq)]
214pub enum KeymapEvent {
215 Callback(KeymapCallback),
217 ResolvedKeyOutput {
219 keymap_index: u16,
221 key_output: key::KeyOutput,
223 },
224}
225
226#[derive(Debug)]
227enum CallbackFunction {
228 ExternC(extern "C" fn() -> ()),
230 Rust(fn() -> ()),
232}
233
234pub struct Keymap<I: Index<usize, Output = R>, R, Ctx, Ev: Debug, PKS, KS, S> {
236 key_refs: I,
237 key_system: S,
238 context: Ctx,
239 pressed_inputs: heapless::Vec<input::PressedInput<R, KS>, { MAX_PRESSED_KEYS }>,
240 event_scheduler: EventScheduler<Ev>,
241 ms_per_tick: u8,
242 idle_time: u32,
243 hid_reporter: HIDKeyboardReporter,
244 pending_key_state: Option<PendingState<R, Ev, PKS>>,
245 input_queue: heapless::spsc::Queue<input::Event, { MAX_QUEUED_INPUT_EVENTS }>,
246 input_queue_delay_counter: u8,
247 callbacks: heapless::LinearMap<KeymapCallback, CallbackFunction, 2>,
248}
249
250impl<
251 I: Debug + Index<usize, Output = R>,
252 R: Debug,
253 Ctx: Debug,
254 Ev: Debug,
255 PKS: Debug,
256 KS: Debug,
257 S: Debug,
258 > core::fmt::Debug for Keymap<I, R, Ctx, Ev, PKS, KS, S>
259{
260 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
261 f.debug_struct("Keymap")
262 .field("context", &self.context)
263 .field("event_scheduler", &self.event_scheduler)
264 .field("ms_per_tick", &self.ms_per_tick)
265 .field("idle_time", &self.idle_time)
266 .field("hid_reporter", &self.hid_reporter)
267 .field("input_queue", &self.input_queue)
268 .field("input_queue_delay_counter", &self.input_queue_delay_counter)
269 .field("pending_key_state", &self.pending_key_state)
270 .field("pressed_inputs", &self.pressed_inputs)
271 .finish_non_exhaustive()
272 }
273}
274
275impl<
276 I: Debug + Index<usize, Output = R>,
277 R: Copy + Debug,
278 Ctx: Debug + key::Context<Event = Ev> + SetKeymapContext,
279 Ev: Copy + Debug,
280 PKS: Debug,
281 KS: Copy + Debug + From<key::NoOpKeyState>,
282 S: key::System<R, Ref = R, Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS>,
283 > Keymap<I, R, Ctx, Ev, PKS, KS, S>
284{
285 pub const fn new(key_refs: I, context: Ctx, key_system: S) -> Self {
287 Self {
288 key_refs,
289 key_system,
290 context,
291 pressed_inputs: heapless::Vec::new(),
292 event_scheduler: EventScheduler::new(),
293 ms_per_tick: 1,
294 idle_time: 0,
295 hid_reporter: HIDKeyboardReporter::new(),
296 pending_key_state: None,
297 input_queue: heapless::spsc::Queue::new(),
298 input_queue_delay_counter: 0,
299 callbacks: heapless::LinearMap::new(),
300 }
301 }
302
303 pub fn init(&mut self) {
305 self.pressed_inputs.clear();
306 self.event_scheduler.init();
307 self.hid_reporter.init();
308 self.pending_key_state = None;
309 while !self.input_queue.is_empty() {
310 self.input_queue.dequeue().unwrap();
311 }
312 self.input_queue_delay_counter = 0;
313 self.ms_per_tick = 1;
314 self.idle_time = 0;
315 }
316
317 pub fn set_callback(&mut self, callback_id: KeymapCallback, callback_fn: fn() -> ()) {
321 self.callbacks
322 .insert(callback_id, CallbackFunction::Rust(callback_fn))
323 .unwrap();
324 }
325
326 pub fn set_callback_extern(
330 &mut self,
331 callback_id: KeymapCallback,
332 callback_fn: extern "C" fn() -> (),
333 ) {
334 self.callbacks
335 .insert(callback_id, CallbackFunction::ExternC(callback_fn))
336 .unwrap();
337 }
338
339 pub fn set_ms_per_tick(&mut self, ms_per_tick: u8) {
341 self.ms_per_tick = ms_per_tick;
342 }
343
344 fn resolve_pending_key_state(&mut self, key_state: KS) {
347 if let Some(PendingState {
348 keymap_index,
349 key_ref,
350 queued_events,
351 ..
352 }) = self.pending_key_state.take()
353 {
354 self.event_scheduler
356 .cancel_events_for_keymap_index(keymap_index);
357
358 self.pressed_inputs
360 .push(input::PressedInput::pressed_key(
361 keymap_index,
362 key_ref,
363 key_state,
364 ))
365 .unwrap();
366
367 let mut i = 1;
371 let mut old_input_queue: heapless::spsc::Queue<input::Event, MAX_QUEUED_INPUT_EVENTS> =
372 core::mem::take(&mut self.input_queue);
373
374 let (pending_input_ev, queued_events): (
378 heapless::Vec<key::Event<Ev>, { MAX_PRESSED_KEYS }>,
379 heapless::Vec<key::Event<Ev>, { MAX_PRESSED_KEYS }>,
380 ) = queued_events.iter().partition(|ev| match ev {
381 key::Event::Input(input::Event::Press {
382 keymap_index: queued_kmi,
383 }) => *queued_kmi == keymap_index,
384 key::Event::Input(input::Event::Release {
385 keymap_index: queued_kmi,
386 }) => *queued_kmi == keymap_index,
387 key::Event::Key {
388 keymap_index: queued_kmi,
389 ..
390 } => *queued_kmi == keymap_index,
391 _ => false,
392 });
393
394 for ev in queued_events.iter().chain(pending_input_ev.last()) {
395 match ev {
396 key::Event::Input(ie) => {
397 self.input_queue.enqueue(*ie).unwrap();
398 }
399 _ => {
400 self.event_scheduler.schedule_after(i, *ev);
401 i += 1;
402 }
403 }
404 }
405
406 while let Some(ie) = old_input_queue.dequeue() {
407 self.input_queue.enqueue(ie).unwrap();
408 }
409
410 self.handle_pending_events();
411
412 if let Some(key_output) = self.key_system.key_output(&key_ref, &key_state) {
414 let km_ev = KeymapEvent::ResolvedKeyOutput {
415 keymap_index,
416 key_output,
417 };
418 self.handle_event(key::Event::Keymap(km_ev));
419 }
420 }
421 }
422
423 pub fn handle_input(&mut self, ev: input::Event) {
427 self.idle_time = 0;
428
429 if self.input_queue.is_full() {
430 return;
431 }
432
433 self.input_queue.enqueue(ev).unwrap();
434
435 if self.input_queue_delay_counter == 0 {
436 let ie = self.input_queue.dequeue().unwrap();
437 self.process_input(ie);
438 self.input_queue_delay_counter = INPUT_QUEUE_TICK_DELAY;
439 }
440 }
441
442 fn has_pressed_input_with_keymap_index(&self, keymap_index: u16) -> bool {
443 self.pressed_inputs.iter().any(|pi| match pi {
444 &input::PressedInput::Key(input::PressedKey {
445 keymap_index: ki, ..
446 }) => keymap_index == ki,
447 _ => false,
448 })
449 }
450
451 fn update_pending_state(&mut self, ev: key::Event<Ev>) {
452 if let Some(PendingState {
453 keymap_index,
454 key_ref,
455 pending_key_state,
456 queued_events,
457 ..
458 }) = &mut self.pending_key_state
459 {
460 let (mut maybe_npk, pke) = self.key_system.update_pending_state(
461 pending_key_state,
462 *keymap_index,
463 &self.context,
464 *key_ref,
465 ev,
466 );
467
468 pke.into_iter()
469 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
470
471 while let Some(npk) = maybe_npk.take() {
472 let pkr = match npk {
473 key::NewPressedKey::Key(new_key_ref) => {
474 *key_ref = new_key_ref;
475 let (pkr, pke) = self.key_system.new_pressed_key(
476 *keymap_index,
477 &self.context,
478 new_key_ref,
479 );
480 pke.into_iter()
481 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
482 pkr
483 }
484 key::NewPressedKey::NoOp => {
485 let no_op_ks: KS = key::NoOpKeyState.into();
486 key::PressedKeyResult::Resolved(no_op_ks)
487 }
488 };
489
490 match pkr {
491 key::PressedKeyResult::Resolved(ks) => {
492 self.resolve_pending_key_state(ks);
493 break;
494 }
495 key::PressedKeyResult::NewPressedKey(key::NewPressedKey::Key(new_key_ref)) => {
496 maybe_npk = Some(key::NewPressedKey::Key(new_key_ref));
497 }
498 key::PressedKeyResult::NewPressedKey(key::NewPressedKey::NoOp) => {
499 self.resolve_pending_key_state(key::NoOpKeyState.into());
500 break;
501 }
502 key::PressedKeyResult::Pending(pks) => {
503 *pending_key_state = pks;
504
505 let orig_input_queue = core::mem::take(&mut self.input_queue);
508 while let Some(ev) = queued_events.pop() {
509 if let key::Event::Input(input_ev) = ev {
510 self.input_queue.enqueue(input_ev).unwrap();
511 }
512 }
513 orig_input_queue.iter().for_each(|&ev| {
514 self.input_queue.enqueue(ev).unwrap();
515 });
516 }
517 }
518 }
519 }
520 }
521
522 fn process_input(&mut self, ev: input::Event) {
523 if let Some(pending_state) = &mut self.pending_key_state {
524 pending_state.queued_events.push(ev.into()).unwrap();
525 self.update_pending_state(ev.into());
526 } else {
527 self.pressed_inputs.iter_mut().for_each(|pi| {
529 if let input::PressedInput::Key(input::PressedKey {
530 key_ref,
531 key_state,
532 keymap_index,
533 }) = pi
534 {
535 self.key_system
536 .update_state(key_state, key_ref, &self.context, *keymap_index, ev.into())
537 .into_iter()
538 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
539 }
540 });
541
542 self.context
543 .handle_event(ev.into())
544 .into_iter()
545 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
546
547 match ev {
548 input::Event::Press { keymap_index }
549 if !self.has_pressed_input_with_keymap_index(keymap_index) =>
550 {
551 let mut maybe_key_ref = Some(self.key_refs[keymap_index as usize]);
552
553 while let Some(key_ref) = maybe_key_ref.take() {
554 let (pkr, pke) =
555 self.key_system
556 .new_pressed_key(keymap_index, &self.context, key_ref);
557
558 pke.into_iter()
559 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
560
561 match pkr {
562 key::PressedKeyResult::Resolved(key_state) => {
563 self.pressed_inputs
564 .push(input::PressedInput::pressed_key(
565 keymap_index,
566 key_ref,
567 key_state,
568 ))
569 .unwrap();
570
571 if let Some(key_output) =
573 self.key_system.key_output(&key_ref, &key_state)
574 {
575 let km_ev = KeymapEvent::ResolvedKeyOutput {
576 keymap_index,
577 key_output,
578 };
579 self.handle_event(key::Event::Keymap(km_ev));
580 }
581 }
582 key::PressedKeyResult::NewPressedKey(key::NewPressedKey::Key(
583 new_key_ref,
584 )) => {
585 maybe_key_ref = Some(new_key_ref);
586 }
587 key::PressedKeyResult::NewPressedKey(key::NewPressedKey::NoOp) => {
588 let key_state: KS = key::NoOpKeyState.into();
589
590 self.pressed_inputs
591 .push(input::PressedInput::pressed_key(
592 keymap_index,
593 key_ref,
594 key_state,
595 ))
596 .unwrap();
597 }
598 key::PressedKeyResult::Pending(pending_key_state) => {
599 self.pending_key_state = Some(PendingState {
600 keymap_index,
601 key_ref,
602 pending_key_state,
603 queued_events: heapless::Vec::new(),
604 });
605 }
606 }
607 }
608 }
609 input::Event::Release { keymap_index } => {
610 self.pressed_inputs
611 .iter()
612 .position(|pi| match pi {
613 &input::PressedInput::Key(input::PressedKey {
614 keymap_index: ki,
615 ..
616 }) => keymap_index == ki,
617 _ => false,
618 })
619 .map(|i| self.pressed_inputs.remove(i));
620 }
621
622 input::Event::VirtualKeyPress { key_output } => {
623 let pressed_key = input::PressedInput::Virtual(key_output);
624 self.pressed_inputs.push(pressed_key).unwrap();
625 }
626 input::Event::VirtualKeyRelease { key_output } => {
627 self.pressed_inputs
629 .iter()
630 .position(|k| match k {
631 input::PressedInput::Virtual(ko) => key_output == *ko,
632 _ => false,
633 })
634 .map(|i| self.pressed_inputs.remove(i));
635 }
636
637 _ => {}
638 }
639 }
640
641 self.handle_pending_events();
642 }
643
644 fn handle_event(&mut self, ev: key::Event<Ev>) {
647 if let key::Event::Keymap(KeymapEvent::Callback(callback_id)) = ev {
648 match self.callbacks.get(&callback_id) {
649 Some(CallbackFunction::Rust(callback_fn)) => {
650 callback_fn();
651 }
652 Some(CallbackFunction::ExternC(callback_fn)) => {
653 callback_fn();
654 }
655 None => {}
656 }
657 }
658
659 self.update_pending_state(ev);
661
662 self.pressed_inputs.iter_mut().for_each(|pi| {
664 if let input::PressedInput::Key(input::PressedKey {
665 key_state,
666 key_ref,
667 keymap_index,
668 }) = pi
669 {
670 self.key_system
671 .update_state(key_state, key_ref, &self.context, *keymap_index, ev)
672 .into_iter()
673 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
674 }
675 });
676
677 self.context
679 .handle_event(ev)
680 .into_iter()
681 .for_each(|sch_ev| self.event_scheduler.schedule_event(sch_ev));
682
683 if let Event::Input(input_ev) = ev {
684 self.process_input(input_ev);
685 }
686 }
687
688 fn handle_pending_events(&mut self) {
689 while let Some(ev) = self.event_scheduler.dequeue() {
691 self.handle_event(ev);
692 }
693 }
694
695 pub fn tick(&mut self) {
697 let km_context = KeymapContext {
698 time_ms: self.event_scheduler.schedule_counter,
699 idle_time_ms: self.idle_time,
700 };
701 self.context.set_keymap_context(km_context);
702
703 if !self.input_queue.is_empty() && self.input_queue_delay_counter == 0 {
704 let ie = self.input_queue.dequeue().unwrap();
705 self.process_input(ie);
706 self.input_queue_delay_counter = INPUT_QUEUE_TICK_DELAY;
707 }
708
709 if self.input_queue_delay_counter > 0 {
710 self.input_queue_delay_counter -= 1;
711 }
712
713 self.event_scheduler.tick(self.ms_per_tick);
714
715 self.handle_pending_events();
716
717 self.idle_time += self.ms_per_tick as u32;
718 }
719
720 pub fn pressed_keys(&self) -> heapless::Vec<key::KeyOutput, { MAX_PRESSED_KEYS }> {
722 let pressed_key_codes = self.pressed_inputs.iter().filter_map(|pi| match pi {
723 input::PressedInput::Key(input::PressedKey {
724 key_ref, key_state, ..
725 }) => self.key_system.key_output(key_ref, key_state),
726 &input::PressedInput::Virtual(key_output) => Some(key_output),
727 });
728
729 pressed_key_codes.collect()
730 }
731
732 fn tick_by(&mut self, delta_ms: u32) {
733 if delta_ms == 0 {
734 self.tick();
735 } else {
736 for _ in 0..(delta_ms / self.ms_per_tick as u32) {
737 self.tick();
738 }
739 }
740 }
741
742 pub fn handle_input_after_time(&mut self, delta_ms: u32, ev: input::Event) -> Option<u32> {
749 self.tick_by(delta_ms);
750 self.handle_input(ev);
751 let next_event_time = self.event_scheduler.next_event_time();
752 debug_assert!(next_event_time != Some(0));
753 next_event_time
754 }
755
756 pub fn tick_to_next_scheduled_event(&mut self) -> Option<u32> {
762 if let Some(delta_ms) = self.event_scheduler.next_event_time() {
763 self.tick_by(delta_ms);
764 self.event_scheduler.next_event_time()
765 } else {
766 None
767 }
768 }
769
770 pub fn report_output(&mut self) -> KeymapOutput {
772 self.hid_reporter.update(self.pressed_keys());
773 self.hid_reporter.report_sent();
774
775 KeymapOutput::new(self.hid_reporter.reportable_key_outputs())
776 }
777
778 #[doc(hidden)]
780 pub fn boot_keyboard_report(&self) -> [u8; 8] {
781 KeymapOutput::new(self.pressed_keys()).as_hid_boot_keyboard_report()
782 }
783
784 #[doc(hidden)]
785 pub fn has_scheduled_events(&self) -> bool {
786 !self.event_scheduler.pending_events.is_empty()
787 || !self.event_scheduler.scheduled_events.is_empty()
788 || !self.input_queue.is_empty()
789 }
790}
791
792#[cfg(test)]
793mod tests {
794 use super::*;
795
796 #[test]
797 fn test_keymap_output_pressed_key_codes_includes_modifier_key_code() {
798 let mut input: heapless::Vec<key::KeyOutput, { MAX_PRESSED_KEYS }> = heapless::Vec::new();
800 input.push(key::KeyOutput::from_key_code(0x04)).unwrap();
801 input.push(key::KeyOutput::from_key_code(0xE0)).unwrap();
802
803 let keymap_output = KeymapOutput::new(input);
805 let pressed_key_codes = keymap_output.pressed_key_codes();
806
807 assert!(pressed_key_codes.contains(&0xE0))
809 }
810
811 #[test]
812 fn test_keymap_output_as_hid_boot_keyboard_report_gathers_modifiers() {
813 let mut input: heapless::Vec<key::KeyOutput, { MAX_PRESSED_KEYS }> = heapless::Vec::new();
815 input.push(key::KeyOutput::from_key_code(0x04)).unwrap();
816 input.push(key::KeyOutput::from_key_code(0xE0)).unwrap();
817
818 let keymap_output = KeymapOutput::new(input);
820 let actual_report: [u8; 8] = keymap_output.as_hid_boot_keyboard_report();
821
822 let expected_report: [u8; 8] = [0x01, 0, 0x04, 0, 0, 0, 0, 0];
824 assert_eq!(expected_report, actual_report);
825 }
826
827 #[test]
828 fn test_keymap_many_input_events_without_tick_or_report() {
829 let mut keymap = {
831 use crate as smart_keymap;
832 use smart_keymap::key::composite as key_system;
833
834 use key_system::Context;
835 use key_system::Ref;
836 const KEY_COUNT: usize = 1;
837 const KEY_REFS: [Ref; KEY_COUNT] = [smart_keymap::key::composite::Ref::Keyboard(
838 smart_keymap::key::keyboard::Ref::KeyCode(0x04),
839 )];
840 const CONTEXT: Context = Context::from_config(key_system::Config::new());
841
842 smart_keymap::keymap::Keymap::new(
843 KEY_REFS,
844 CONTEXT,
845 smart_keymap::key::composite::System::array_based(
846 smart_keymap::key::automation::System::new([]),
847 smart_keymap::key::callback::System::new([]),
848 smart_keymap::key::chorded::System::new([], []),
849 smart_keymap::key::keyboard::System::new([]),
850 smart_keymap::key::layered::System::new([], []),
851 smart_keymap::key::sticky::System::new([]),
852 smart_keymap::key::tap_dance::System::new([]),
853 smart_keymap::key::tap_hold::System::new([]),
854 ),
855 )
856 };
857
858 for _ in 0..100 {
860 keymap.handle_input(input::Event::Press { keymap_index: 0 });
861 keymap.handle_input(input::Event::Release { keymap_index: 0 });
862 }
863
864 }
867}