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, 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
93struct InstructionsDebugHelper<'a, const INSTRUCTION_COUNT: usize> {
94 instructions: &'a [Instruction; INSTRUCTION_COUNT],
95}
96
97impl<'a, const INSTRUCTION_COUNT: usize> core::fmt::Debug
98 for InstructionsDebugHelper<'a, INSTRUCTION_COUNT>
99{
100 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
101 let last_non_noop_inst_pos = self
103 .instructions
104 .iter()
105 .rposition(|inst| *inst != Instruction::NoOp)
106 .map_or(0, |pos| pos + 1);
107 if last_non_noop_inst_pos < INSTRUCTION_COUNT {
108 f.debug_list()
109 .entries(&self.instructions[..last_non_noop_inst_pos])
110 .finish_non_exhaustive()
111 } else {
112 f.debug_list().entries(&self.instructions[..]).finish()
113 }
114 }
115}
116
117impl<const INSTRUCTION_COUNT: usize> core::fmt::Debug for Config<INSTRUCTION_COUNT> {
118 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
119 f.debug_struct("Config")
120 .field(
121 "instructions",
122 &InstructionsDebugHelper {
123 instructions: &self.instructions,
124 },
125 )
126 .field("instruction_duration", &self.instruction_duration)
127 .finish()
128 }
129}
130
131pub const fn instructions<const N: usize, const INSTRUCTION_COUNT: usize>(
133 instructions: [Instruction; N],
134) -> [Instruction; INSTRUCTION_COUNT] {
135 let mut cfg_instructions: [Instruction; INSTRUCTION_COUNT] =
136 [Instruction::NoOp; INSTRUCTION_COUNT];
137
138 if N > INSTRUCTION_COUNT {
139 panic!("Too many instructions for instructions array");
140 }
141
142 let mut i = 0;
143
144 while i < N {
145 cfg_instructions[i] = instructions[i];
146 i += 1;
147 }
148
149 cfg_instructions
150}
151
152fn deserialize_instructions<'de, D, const INSTRUCTION_COUNT: usize>(
154 deserializer: D,
155) -> Result<[Instruction; INSTRUCTION_COUNT], D::Error>
156where
157 D: serde::Deserializer<'de>,
158{
159 let instructions_vec: heapless::Vec<Instruction, INSTRUCTION_COUNT> =
160 Deserialize::deserialize(deserializer)?;
161
162 let mut instructions_array: [Instruction; INSTRUCTION_COUNT] =
163 [Instruction::NoOp; INSTRUCTION_COUNT];
164 for (i, instruction) in instructions_vec.iter().enumerate() {
165 instructions_array[i] = *instruction;
166 }
167
168 Ok(instructions_array)
169}
170
171fn default_instruction_duration() -> u16 {
172 DEFAULT_INSTRUCTION_DURATION
173}
174
175pub const DEFAULT_INSTRUCTION_DURATION: u16 = 10;
177
178impl<const INSTRUCTION_COUNT: usize> Config<INSTRUCTION_COUNT> {
179 pub const fn new() -> Self {
181 Self {
182 instructions: [{ Instruction::NoOp }; INSTRUCTION_COUNT],
183 instruction_duration: DEFAULT_INSTRUCTION_DURATION,
184 }
185 }
186}
187
188impl<const INSTRUCTION_COUNT: usize> Default for Config<INSTRUCTION_COUNT> {
189 fn default() -> Self {
190 Self::new()
191 }
192}
193
194struct ExecutionsDebugHelper<'a> {
195 execution_queue: &'a [Execution; EXECUTION_QUEUE_SIZE],
196}
197
198impl core::fmt::Debug for ExecutionsDebugHelper<'_> {
199 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
200 let last_non_empty_exec_pos = self
202 .execution_queue
203 .iter()
204 .rposition(|exec| !exec.is_empty())
205 .map_or(0, |pos| pos + 1);
206 if last_non_empty_exec_pos < EXECUTION_QUEUE_SIZE {
207 f.debug_list()
208 .entries(&self.execution_queue[..last_non_empty_exec_pos])
209 .finish_non_exhaustive()
210 } else {
211 f.debug_list().entries(&self.execution_queue[..]).finish()
212 }
213 }
214}
215
216#[derive(Clone, Copy, PartialEq)]
218pub struct Context<const INSTRUCTION_COUNT: usize> {
219 config: Config<INSTRUCTION_COUNT>,
220 execution_queue: [Execution; EXECUTION_QUEUE_SIZE],
221}
222
223impl<const INSTRUCTION_COUNT: usize> core::fmt::Debug for Context<INSTRUCTION_COUNT> {
224 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
225 f.debug_struct("Context")
226 .field("config", &self.config)
227 .field(
228 "execution_queue",
229 &ExecutionsDebugHelper {
230 execution_queue: &self.execution_queue,
231 },
232 )
233 .finish()
234 }
235}
236
237impl<const INSTRUCTION_COUNT: usize> Context<INSTRUCTION_COUNT> {
238 pub const fn from_config(config: Config<INSTRUCTION_COUNT>) -> Self {
240 let execution_queue = [Execution::EMPTY; EXECUTION_QUEUE_SIZE];
241 Self {
242 config,
243 execution_queue,
244 }
245 }
246
247 pub fn reset(&mut self) {
249 *self = Self::from_config(self.config);
250 }
251
252 pub fn enqueue(&mut self, new_execution: Execution) -> usize {
254 if new_execution.is_empty() {
256 return EXECUTION_QUEUE_SIZE;
257 }
258
259 for (i, exec) in self.execution_queue.iter_mut().enumerate() {
260 if exec.is_empty() {
261 *exec = new_execution;
262 return i;
263 }
264 }
265
266 EXECUTION_QUEUE_SIZE
268 }
269
270 fn execute_head(&mut self, keymap_index: u16) -> key::KeyEvents<Event> {
271 let mut pke = key_events_for(self.config, keymap_index, self.execution_queue[0]);
272
273 self.execution_queue[0].incr();
274
275 if self.execution_queue[0].is_empty() {
276 self.execution_queue.rotate_left(1);
277 self.execution_queue[EXECUTION_QUEUE_SIZE - 1] = Execution::EMPTY;
278
279 if !self.execution_queue[0].is_empty() {
281 pke.schedule_event(
282 self.config.instruction_duration,
283 key::Event::Key {
284 keymap_index,
285 key_event: Event::NextInstruction,
286 },
287 );
288 }
289 }
290
291 pke
292 }
293}
294
295impl<const INSTRUCTION_COUNT: usize> key::Context for Context<INSTRUCTION_COUNT> {
296 type Event = Event;
297
298 fn reset(&mut self) {
299 Context::reset(self);
300 }
301
302 fn handle_event(&mut self, event: key::Event<Self::Event>) -> key::KeyEvents<Self::Event> {
303 match event {
304 key::Event::Key {
305 key_event: Event::Enqueue(execution),
306 keymap_index,
307 } if !execution.is_empty() => {
308 let exec_immediately = self.execution_queue[0].is_empty();
309
310 self.enqueue(execution);
311
312 if exec_immediately {
313 self.execute_head(keymap_index)
314 } else {
315 key::KeyEvents::no_events()
316 }
317 }
318 key::Event::Key {
319 key_event: Event::NextInstruction,
320 keymap_index,
321 } => {
322 if !self.execution_queue[0].is_empty() {
323 self.execute_head(keymap_index)
324 } else {
325 key::KeyEvents::no_events()
326 }
327 }
328 _ => key::KeyEvents::no_events(),
329 }
330 }
331}
332
333#[derive(Debug, Clone, Copy, PartialEq)]
335pub enum Event {
336 Enqueue(Execution),
338 NextInstruction,
340 ExecutionFinished,
342}
343
344pub fn key_events_for<const INSTRUCTION_COUNT: usize>(
346 config: Config<INSTRUCTION_COUNT>,
347 keymap_index: u16,
348 Execution { start, length }: Execution,
349) -> key::KeyEvents<Event> {
350 let instruction = config.instructions[start as usize];
351
352 let next_key_ev = if length > 1 {
353 key::Event::Key {
354 keymap_index,
355 key_event: Event::NextInstruction,
356 }
357 } else {
358 key::Event::Key {
359 keymap_index,
360 key_event: Event::ExecutionFinished,
361 }
362 };
363
364 match instruction {
365 Instruction::NoOp => {
366 let mut pke = key::KeyEvents::no_events();
367 pke.schedule_event(config.instruction_duration, next_key_ev);
368 pke
369 }
370 Instruction::Press(key_output) => {
371 let mut pke = key::KeyEvents::event(key::Event::Input(input::Event::VirtualKeyPress {
372 key_output,
373 }));
374 pke.schedule_event(config.instruction_duration, next_key_ev);
375 pke
376 }
377 Instruction::Release(key_output) => {
378 let mut pke =
379 key::KeyEvents::event(key::Event::Input(input::Event::VirtualKeyRelease {
380 key_output,
381 }));
382 pke.schedule_event(config.instruction_duration, next_key_ev);
383 pke
384 }
385 Instruction::Tap(key_output) => {
386 let mut pke = key::KeyEvents::event(key::Event::Input(input::Event::VirtualKeyPress {
387 key_output,
388 }));
389 pke.schedule_event(
390 config.instruction_duration,
391 key::Event::Input(input::Event::VirtualKeyRelease { key_output }),
392 );
393 pke.schedule_event(config.instruction_duration, next_key_ev);
394 pke
395 }
396 Instruction::Wait(ticks) => {
397 let mut pke = key::KeyEvents::no_events();
398 pke.schedule_event(ticks, next_key_ev);
399 pke
400 }
401 }
402}
403
404#[derive(Debug, Clone, Copy, PartialEq)]
406pub struct PendingKeyState;
407
408#[derive(Debug, Clone, Copy, PartialEq)]
410pub struct KeyState;
411
412#[derive(Debug, Clone, Copy, PartialEq)]
414pub struct System<R: Debug, Keys: Index<usize, Output = Key>, const INSTRUCTION_COUNT: usize> {
415 keys: Keys,
416 _marker: core::marker::PhantomData<(R, [(); INSTRUCTION_COUNT])>,
417}
418
419impl<R: Debug, Keys: Index<usize, Output = Key>, const INSTRUCTION_COUNT: usize>
420 System<R, Keys, INSTRUCTION_COUNT>
421{
422 pub const fn new(keys: Keys) -> Self {
424 Self {
425 keys,
426 _marker: core::marker::PhantomData,
427 }
428 }
429}
430
431impl<R: Copy + Debug, Keys: Debug + Index<usize, Output = Key>, const INSTRUCTION_COUNT: usize>
432 key::System<R> for System<R, Keys, INSTRUCTION_COUNT>
433{
434 type Ref = Ref;
435 type Context = Context<INSTRUCTION_COUNT>;
436 type Event = Event;
437 type PendingKeyState = PendingKeyState;
438 type KeyState = KeyState;
439
440 fn new_pressed_key(
441 &self,
442 keymap_index: u16,
443 _context: &Self::Context,
444 Ref(key_index): Ref,
445 ) -> (
446 key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
447 key::KeyEvents<Self::Event>,
448 ) {
449 let pkr = key::PressedKeyResult::Resolved(KeyState);
450
451 let Key {
452 automation_instructions:
453 KeyInstructions {
454 on_press: execution,
455 ..
456 },
457 } = self.keys[key_index as usize];
458 let key_ev = key::Event::Key {
459 keymap_index,
460 key_event: if !execution.is_empty() {
461 Event::Enqueue(execution)
462 } else {
463 Event::ExecutionFinished
465 },
466 };
467 let pke = key::KeyEvents::event(key_ev);
468
469 (pkr, pke)
470 }
471
472 fn update_pending_state(
473 &self,
474 _pending_state: &mut Self::PendingKeyState,
475 _keymap_index: u16,
476 _context: &Self::Context,
477 _key_ref: Ref,
478 _event: key::Event<Self::Event>,
479 ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
480 panic!()
481 }
482
483 fn update_state(
484 &self,
485 _key_state: &mut Self::KeyState,
486 Ref(key_index): &Self::Ref,
487 _context: &Self::Context,
488 keymap_index: u16,
489 event: key::Event<Self::Event>,
490 ) -> key::KeyEvents<Self::Event> {
491 match event {
492 key::Event::Key {
493 key_event: Event::ExecutionFinished,
494 keymap_index: ev_kmi,
495 } if keymap_index == ev_kmi => {
496 let Key {
499 automation_instructions:
500 KeyInstructions {
501 while_pressed: execution,
502 ..
503 },
504 } = self.keys[*key_index as usize];
505 let key_ev = key::Event::Key {
506 keymap_index,
507 key_event: Event::Enqueue(execution),
508 };
509 key::KeyEvents::event(key_ev)
510 }
511 key::Event::Input(input::Event::Release {
512 keymap_index: ev_kmi,
513 }) if keymap_index == ev_kmi => {
514 let Key {
517 automation_instructions:
518 KeyInstructions {
519 on_release: execution,
520 ..
521 },
522 } = self.keys[*key_index as usize];
523 let key_ev = key::Event::Key {
524 keymap_index,
525 key_event: Event::Enqueue(execution),
526 };
527 key::KeyEvents::event(key_ev)
528 }
529 _ => key::KeyEvents::no_events(),
530 }
531 }
532
533 fn key_output(
534 &self,
535 _key_ref: &Self::Ref,
536 _key_state: &Self::KeyState,
537 ) -> Option<key::KeyOutput> {
538 None
539 }
540}
541
542#[cfg(test)]
543mod tests {
544 use super::*;
545
546 #[test]
547 fn test_sizeof_ref() {
548 assert_eq!(1, core::mem::size_of::<Ref>());
549 }
550
551 #[test]
552 fn test_sizeof_event() {
553 assert_eq!(6, core::mem::size_of::<Event>());
554 }
555}