1use core::fmt::Debug;
2use core::ops::Index;
3
4use serde::Deserialize;
5
6use crate::input;
7use crate::key;
8
9const EXECUTION_QUEUE_SIZE: usize = 8;
10
11#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
13pub struct Ref(pub u8);
14
15#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
17pub struct Execution {
18 pub start: u16,
20 pub length: u16,
22}
23
24impl Execution {
25 pub const EMPTY: Self = Self {
27 start: 0,
28 length: 0,
29 };
30
31 pub const fn is_empty(&self) -> bool {
33 self.length == 0
34 }
35
36 pub fn incr(&mut self) {
38 if self.length > 0 {
39 self.start += 1;
40 self.length -= 1;
41 }
42 }
43}
44
45#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
47pub struct KeyInstructions {
48 pub on_press: Execution,
50 pub while_pressed: Execution,
52 pub on_release: Execution,
54}
55
56#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
58pub struct Key {
59 pub automation_instructions: KeyInstructions,
61}
62
63#[derive(Deserialize, Debug, Default, Clone, Copy, PartialEq)]
65pub enum Instruction {
66 #[default]
68 NoOp,
69 Press(key::KeyOutput),
71 Release(key::KeyOutput),
73 Tap(key::KeyOutput),
75 Wait(u16),
77}
78
79#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
81pub struct Config<const INSTRUCTION_COUNT: usize> {
82 #[serde(deserialize_with = "deserialize_instructions")]
86 pub instructions: [Instruction; INSTRUCTION_COUNT],
87
88 #[serde(default = "default_instruction_duration")]
90 pub instruction_duration: u16,
91}
92
93pub const fn instructions<const N: usize, const INSTRUCTION_COUNT: usize>(
95 instructions: [Instruction; N],
96) -> [Instruction; INSTRUCTION_COUNT] {
97 let mut cfg_instructions: [Instruction; INSTRUCTION_COUNT] =
98 [Instruction::NoOp; INSTRUCTION_COUNT];
99
100 if N > INSTRUCTION_COUNT {
101 panic!("Too many instructions for instructions array");
102 }
103
104 let mut i = 0;
105
106 while i < N {
107 cfg_instructions[i] = instructions[i];
108 i += 1;
109 }
110
111 cfg_instructions
112}
113
114fn deserialize_instructions<'de, D, const INSTRUCTION_COUNT: usize>(
116 deserializer: D,
117) -> Result<[Instruction; INSTRUCTION_COUNT], D::Error>
118where
119 D: serde::Deserializer<'de>,
120{
121 let instructions_vec: heapless::Vec<Instruction, INSTRUCTION_COUNT> =
122 Deserialize::deserialize(deserializer)?;
123
124 let mut instructions_array: [Instruction; INSTRUCTION_COUNT] =
125 [Instruction::NoOp; INSTRUCTION_COUNT];
126 for (i, instruction) in instructions_vec.iter().enumerate() {
127 instructions_array[i] = *instruction;
128 }
129
130 Ok(instructions_array)
131}
132
133fn default_instruction_duration() -> u16 {
134 DEFAULT_INSTRUCTION_DURATION
135}
136
137pub const DEFAULT_INSTRUCTION_DURATION: u16 = 10;
139
140impl<const INSTRUCTION_COUNT: usize> Config<INSTRUCTION_COUNT> {
141 pub const fn new() -> Self {
143 Self {
144 instructions: [{ Instruction::NoOp }; INSTRUCTION_COUNT],
145 instruction_duration: DEFAULT_INSTRUCTION_DURATION,
146 }
147 }
148}
149
150impl<const INSTRUCTION_COUNT: usize> Default for Config<INSTRUCTION_COUNT> {
151 fn default() -> Self {
152 Self::new()
153 }
154}
155
156#[derive(Debug, Clone, Copy, PartialEq)]
158pub struct Context<const INSTRUCTION_COUNT: usize> {
159 config: Config<INSTRUCTION_COUNT>,
160 execution_queue: [Execution; EXECUTION_QUEUE_SIZE],
161}
162
163impl<const INSTRUCTION_COUNT: usize> Context<INSTRUCTION_COUNT> {
164 pub const fn from_config(config: Config<INSTRUCTION_COUNT>) -> Self {
166 let execution_queue = [Execution::EMPTY; EXECUTION_QUEUE_SIZE];
167 Self {
168 config,
169 execution_queue,
170 }
171 }
172
173 pub fn enqueue(&mut self, new_execution: Execution) -> usize {
175 if new_execution.is_empty() {
177 return EXECUTION_QUEUE_SIZE;
178 }
179
180 for (i, exec) in self.execution_queue.iter_mut().enumerate() {
181 if exec.is_empty() {
182 *exec = new_execution;
183 return i;
184 }
185 }
186
187 EXECUTION_QUEUE_SIZE
189 }
190
191 fn execute_head(&mut self, keymap_index: u16) -> key::KeyEvents<Event> {
192 let mut pke = key_events_for(self.config, keymap_index, self.execution_queue[0]);
193
194 self.execution_queue[0].incr();
195
196 if self.execution_queue[0].is_empty() {
197 self.execution_queue.rotate_left(1);
198 self.execution_queue[EXECUTION_QUEUE_SIZE - 1] = Execution::EMPTY;
199
200 if !self.execution_queue[0].is_empty() {
202 pke.add_event(key::ScheduledEvent::after(
203 self.config.instruction_duration,
204 key::Event::Key {
205 keymap_index,
206 key_event: Event::NextInstruction,
207 },
208 ));
209 }
210 }
211
212 pke
213 }
214}
215
216impl<const INSTRUCTION_COUNT: usize> key::Context for Context<INSTRUCTION_COUNT> {
217 type Event = Event;
218
219 fn handle_event(&mut self, event: key::Event<Self::Event>) -> key::KeyEvents<Self::Event> {
220 match event {
221 key::Event::Key {
222 key_event: Event::Enqueue(execution),
223 keymap_index,
224 } if !execution.is_empty() => {
225 let exec_immediately = self.execution_queue[0].is_empty();
226
227 self.enqueue(execution);
228
229 if exec_immediately {
230 self.execute_head(keymap_index)
231 } else {
232 key::KeyEvents::no_events()
233 }
234 }
235 key::Event::Key {
236 key_event: Event::NextInstruction,
237 keymap_index,
238 } => {
239 if !self.execution_queue[0].is_empty() {
240 self.execute_head(keymap_index)
241 } else {
242 key::KeyEvents::no_events()
243 }
244 }
245 _ => key::KeyEvents::no_events(),
246 }
247 }
248}
249
250#[derive(Debug, Clone, Copy, PartialEq)]
252pub enum Event {
253 Enqueue(Execution),
255 NextInstruction,
257 ExecutionFinished,
259}
260
261pub fn key_events_for<const INSTRUCTION_COUNT: usize>(
263 config: Config<INSTRUCTION_COUNT>,
264 keymap_index: u16,
265 Execution { start, length }: Execution,
266) -> key::KeyEvents<Event> {
267 let instruction = config.instructions[start as usize];
268
269 let next_key_ev = if length > 1 {
270 key::Event::Key {
271 keymap_index,
272 key_event: Event::NextInstruction,
273 }
274 } else {
275 key::Event::Key {
276 keymap_index,
277 key_event: Event::ExecutionFinished,
278 }
279 };
280
281 match instruction {
282 Instruction::NoOp => {
283 let sch_ev = key::ScheduledEvent::after(config.instruction_duration, next_key_ev);
284 key::KeyEvents::scheduled_event(sch_ev)
285 }
286 Instruction::Press(key_output) => {
287 let sch_ev =
288 key::ScheduledEvent::immediate(key::Event::Input(input::Event::VirtualKeyPress {
289 key_output,
290 }));
291
292 let mut pke = key::KeyEvents::scheduled_event(sch_ev);
293 let sch_ev = key::ScheduledEvent::after(config.instruction_duration, next_key_ev);
294 pke.add_event(sch_ev);
295
296 pke
297 }
298 Instruction::Release(key_output) => {
299 let sch_ev = key::ScheduledEvent::immediate(key::Event::Input(
300 input::Event::VirtualKeyRelease { key_output },
301 ));
302
303 let mut pke = key::KeyEvents::scheduled_event(sch_ev);
304 let sch_ev = key::ScheduledEvent::after(config.instruction_duration, next_key_ev);
305 pke.add_event(sch_ev);
306
307 pke
308 }
309 Instruction::Tap(key_output) => {
310 let sch_press_ev =
311 key::ScheduledEvent::immediate(key::Event::Input(input::Event::VirtualKeyPress {
312 key_output,
313 }));
314 let sch_release_ev = key::ScheduledEvent::after(
315 config.instruction_duration,
316 key::Event::Input(input::Event::VirtualKeyRelease { key_output }),
317 );
318
319 let mut pke = key::KeyEvents::scheduled_event(sch_press_ev);
320 pke.add_event(sch_release_ev);
321 let sch_ev = key::ScheduledEvent::after(config.instruction_duration, next_key_ev);
322 pke.add_event(sch_ev);
323
324 pke
325 }
326 Instruction::Wait(ticks) => {
327 let sch_ev = key::ScheduledEvent::after(ticks, next_key_ev);
328 key::KeyEvents::scheduled_event(sch_ev)
329 }
330 }
331}
332
333#[derive(Debug, Clone, Copy, PartialEq)]
335pub struct PendingKeyState;
336
337#[derive(Debug, Clone, Copy, PartialEq)]
339pub struct KeyState;
340
341#[derive(Debug, Clone, Copy, PartialEq)]
343pub struct System<R: Debug, Keys: Index<usize, Output = Key>, const INSTRUCTION_COUNT: usize> {
344 keys: Keys,
345 _marker: core::marker::PhantomData<(R, [(); INSTRUCTION_COUNT])>,
346}
347
348impl<R: Debug, Keys: Index<usize, Output = Key>, const INSTRUCTION_COUNT: usize>
349 System<R, Keys, INSTRUCTION_COUNT>
350{
351 pub const fn new(keys: Keys) -> Self {
353 Self {
354 keys,
355 _marker: core::marker::PhantomData,
356 }
357 }
358}
359
360impl<R: Copy + Debug, Keys: Debug + Index<usize, Output = Key>, const INSTRUCTION_COUNT: usize>
361 key::System<R> for System<R, Keys, INSTRUCTION_COUNT>
362{
363 type Ref = Ref;
364 type Context = Context<INSTRUCTION_COUNT>;
365 type Event = Event;
366 type PendingKeyState = PendingKeyState;
367 type KeyState = KeyState;
368
369 fn new_pressed_key(
370 &self,
371 keymap_index: u16,
372 _context: &Self::Context,
373 Ref(key_index): Ref,
374 ) -> (
375 key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
376 key::KeyEvents<Self::Event>,
377 ) {
378 let pkr = key::PressedKeyResult::Resolved(KeyState);
379
380 let Key {
381 automation_instructions:
382 KeyInstructions {
383 on_press: execution,
384 ..
385 },
386 } = self.keys[key_index as usize];
387 let key_ev = key::Event::Key {
388 keymap_index,
389 key_event: if !execution.is_empty() {
390 Event::Enqueue(execution)
391 } else {
392 Event::ExecutionFinished
394 },
395 };
396 let pke = key::KeyEvents::event(key_ev);
397
398 (pkr, pke)
399 }
400
401 fn update_pending_state(
402 &self,
403 _pending_state: &mut Self::PendingKeyState,
404 _keymap_index: u16,
405 _context: &Self::Context,
406 _key_ref: Ref,
407 _event: key::Event<Self::Event>,
408 ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
409 panic!()
410 }
411
412 fn update_state(
413 &self,
414 _key_state: &mut Self::KeyState,
415 Ref(key_index): &Self::Ref,
416 _context: &Self::Context,
417 keymap_index: u16,
418 event: key::Event<Self::Event>,
419 ) -> key::KeyEvents<Self::Event> {
420 match event {
421 key::Event::Key {
422 key_event: Event::ExecutionFinished,
423 keymap_index: ev_kmi,
424 } if keymap_index == ev_kmi => {
425 let Key {
428 automation_instructions:
429 KeyInstructions {
430 while_pressed: execution,
431 ..
432 },
433 } = self.keys[*key_index as usize];
434 let key_ev = key::Event::Key {
435 keymap_index,
436 key_event: Event::Enqueue(execution),
437 };
438 key::KeyEvents::event(key_ev)
439 }
440 key::Event::Input(input::Event::Release {
441 keymap_index: ev_kmi,
442 }) if keymap_index == ev_kmi => {
443 let Key {
446 automation_instructions:
447 KeyInstructions {
448 on_release: execution,
449 ..
450 },
451 } = self.keys[*key_index as usize];
452 let key_ev = key::Event::Key {
453 keymap_index,
454 key_event: Event::Enqueue(execution),
455 };
456 key::KeyEvents::event(key_ev)
457 }
458 _ => key::KeyEvents::no_events(),
459 }
460 }
461
462 fn key_output(
463 &self,
464 _key_ref: &Self::Ref,
465 _key_state: &Self::KeyState,
466 ) -> Option<key::KeyOutput> {
467 None
468 }
469}
470
471#[cfg(test)]
472mod tests {
473 use super::*;
474
475 #[test]
476 fn test_sizeof_ref() {
477 assert_eq!(1, core::mem::size_of::<Ref>());
478 }
479
480 #[test]
481 fn test_sizeof_event() {
482 assert_eq!(6, core::mem::size_of::<Event>());
483 }
484}