1#![allow(clippy::let_unit_value)]
4#![allow(clippy::single_match)]
5
6use crate::{
7 interface::state::{
8 KeymapInfo,
9 config::StateConfig,
10 input_event::InputEvent,
11 output_event::{EventType, OutputEvent},
12 },
13 keymap::Keymap,
14};
15
16pub mod hid_report;
17mod key_resolver;
18mod shared;
19mod updater;
20
21pub struct State<
25 const LAYER: usize,
26 const ROW: usize,
27 const COL: usize,
28 const ENCODER_COUNT: usize,
29 const NORMAL_MAX_PRESSED_KEYS: usize,
30 const ONESHOT_STATE_SIZE: usize,
31 const TAP_DANCE_MAX_DEFINITIONS: usize,
32 const TAP_DANCE_MAX_REPEATS: usize,
33 const COMBO_KEY_MAX_DEFINITIONS: usize,
34 const COMBO_KEY_MAX_SOURCES: usize,
35> {
36 key_resolver: key_resolver::KeyResolver<
37 NORMAL_MAX_PRESSED_KEYS,
38 ONESHOT_STATE_SIZE,
39 TAP_DANCE_MAX_DEFINITIONS,
40 TAP_DANCE_MAX_REPEATS,
41 COMBO_KEY_MAX_DEFINITIONS,
42 COMBO_KEY_MAX_SOURCES,
43 >,
44 shared: shared::SharedState<
45 LAYER,
46 ROW,
47 COL,
48 ENCODER_COUNT,
49 TAP_DANCE_MAX_DEFINITIONS,
50 TAP_DANCE_MAX_REPEATS,
51 COMBO_KEY_MAX_DEFINITIONS,
52 COMBO_KEY_MAX_SOURCES,
53 >,
54 config: StateConfig,
55 updater_state: updater::UpdaterState,
56}
57
58impl<
59 const LAYER: usize,
60 const ROW: usize,
61 const COL: usize,
62 const ENCODER_COUNT: usize,
63 const NORMAL_MAX_PRESSED_KEYS: usize,
64 const ONESHOT_STATE_SIZE: usize,
65 const TAP_DANCE_MAX_DEFINITIONS: usize,
66 const TAP_DANCE_MAX_REPEATS: usize,
67 const COMBO_KEY_MAX_DEFINITIONS: usize,
68 const COMBO_KEY_MAX_SOURCES: usize,
69>
70 State<
71 LAYER,
72 ROW,
73 COL,
74 ENCODER_COUNT,
75 NORMAL_MAX_PRESSED_KEYS,
76 ONESHOT_STATE_SIZE,
77 TAP_DANCE_MAX_DEFINITIONS,
78 TAP_DANCE_MAX_REPEATS,
79 COMBO_KEY_MAX_DEFINITIONS,
80 COMBO_KEY_MAX_SOURCES,
81 >
82{
83 pub fn new(
85 keymap: Keymap<
86 LAYER,
87 ROW,
88 COL,
89 ENCODER_COUNT,
90 TAP_DANCE_MAX_DEFINITIONS,
91 TAP_DANCE_MAX_REPEATS,
92 COMBO_KEY_MAX_DEFINITIONS,
93 COMBO_KEY_MAX_SOURCES,
94 >,
95 config: StateConfig,
96 ) -> Self {
97 const {
98 assert!(LAYER >= 1, "Layer count must be at least 1");
99 }
100
101 Self {
102 config: config.clone(),
103 key_resolver: key_resolver::KeyResolver::new(
104 config.key_resolver,
105 keymap.tap_dance.clone(),
106 keymap.combo.clone(),
107 ),
108 shared: shared::SharedState::new(keymap),
109 updater_state: updater::UpdaterState::new(config.mouse),
110 }
111 }
112
113 pub fn get_keymap(
114 &self,
115 ) -> &Keymap<
116 LAYER,
117 ROW,
118 COL,
119 ENCODER_COUNT,
120 TAP_DANCE_MAX_DEFINITIONS,
121 TAP_DANCE_MAX_REPEATS,
122 COMBO_KEY_MAX_DEFINITIONS,
123 COMBO_KEY_MAX_SOURCES,
124 > {
125 &self.shared.keymap
126 }
127
128 pub fn get_config(&self) -> &StateConfig {
129 &self.config
130 }
131
132 pub fn get_layer_active(&self) -> &shared::LayerActive<LAYER> {
133 &self.shared.layer_active
134 }
135
136 pub fn get_keymap_info() -> KeymapInfo {
137 KeymapInfo {
138 layer_count: LAYER as u8,
139 max_tap_dance_key_count: TAP_DANCE_MAX_DEFINITIONS as u8,
140 max_tap_dance_repeat_count: TAP_DANCE_MAX_REPEATS as u8,
141 oneshot_state_size: ONESHOT_STATE_SIZE as u8,
142 }
143 }
144
145 pub fn update(
146 &mut self,
147 event: InputEvent,
148 since_last_update: core::time::Duration,
149 mut cb: impl FnMut(OutputEvent),
150 ) {
151 self.shared.now = self.shared.now + since_last_update.into();
152 let mut updater = self.updater_state.start_update();
153
154 let key_change = match event {
155 InputEvent::Key(key_change) => Some(key_change),
156 InputEvent::Mouse(movement) => {
157 updater.update_by_mouse_move(movement, &mut cb);
158 None
159 }
160 InputEvent::Encoder((id, dir)) => {
161 if let Some(kc) = self
162 .shared
163 .keymap
164 .get_encoder_key(self.shared.layer_active, id as usize, dir)
165 .copied()
166 {
167 updater.update_by_keycode(&kc, EventType::Pressed, &mut self.shared, &mut cb);
168 updater.update_by_keycode(&kc, EventType::Released, &mut self.shared, &mut cb);
169 }
170 None
171 }
172 _ => None,
173 };
174
175 self.key_resolver
176 .resolve_key(&mut self.shared, key_change.as_ref(), |shared, et, kc| {
177 updater.update_by_keycode(&kc, et, shared, &mut cb);
178 });
179
180 updater.end(self.shared.highest_layer(), &mut self.shared, cb);
181 }
182}
183
184#[cfg(test)]
185mod tests;