macro_recorder: basic macro optimizer

main
Ilya Zhuravlev 2020-12-24 09:25:59 -05:00
parent abf62439e4
commit e5e342d397
4 changed files with 80 additions and 4 deletions

View File

@ -2,7 +2,12 @@
from keycodes import keycode_label
class KeyDown:
class BasicAction:
pass
class KeyDown(BasicAction):
def __init__(self, keycode):
self.keycode = keycode
@ -10,8 +15,11 @@ class KeyDown:
def __repr__(self):
return "Down({})".format(keycode_label(self.keycode.code))
def __eq__(self, other):
return isinstance(other, KeyDown) and other.keycode == self.keycode
class KeyUp:
class KeyUp(BasicAction):
def __init__(self, keycode):
self.keycode = keycode
@ -19,8 +27,11 @@ class KeyUp:
def __repr__(self):
return "Up({})".format(keycode_label(self.keycode.code))
def __eq__(self, other):
return isinstance(other, KeyUp) and other.keycode == self.keycode
class KeyTap:
class KeyTap(BasicAction):
def __init__(self, keycode):
self.keycode = keycode
@ -28,11 +39,17 @@ class KeyTap:
def __repr__(self):
return "Tap({})".format(keycode_label(self.keycode.code))
def __eq__(self, other):
return isinstance(other, KeyTap) and other.keycode == self.keycode
class KeyString:
class KeyString(BasicAction):
def __init__(self, string):
self.string = string
def __repr__(self):
return "SendString({})".format(self.string)
def __eq__(self, other):
return isinstance(other, KeyString) and other.string == self.string

View File

@ -0,0 +1,35 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from macro_key import KeyUp, KeyDown, KeyTap
def remove_repeats(sequence):
""" Removes exact repetition, i.e. two Down or two Up of the same key """
out = []
for k in sequence:
if out and (isinstance(k, KeyDown) or isinstance(k, KeyUp)) and k == out[-1]:
continue
out.append(k)
return out
def replace_with_tap(sequence):
""" Replaces a sequence of Down/Up with a Tap """
out = []
sequence = sequence[:]
while len(sequence) > 0:
if len(sequence) >= 2 and isinstance(sequence[0], KeyDown) and isinstance(sequence[1], KeyUp) and \
sequence[0].keycode == sequence[1].keycode:
key = KeyTap(sequence[0].keycode)
out.append(key)
sequence.pop(0)
sequence.pop(0)
else:
out.append(sequence[0])
sequence.pop(0)
return out
def macro_optimize(sequence):
sequence = remove_repeats(sequence)
sequence = replace_with_tap(sequence)
return sequence

View File

@ -9,6 +9,7 @@ from fbs_runtime.application_context import is_frozen
from basic_editor import BasicEditor
from keycodes import KEYCODES_BASIC
from macro_key import KeyDown, KeyUp
from macro_optimizer import macro_optimize
from util import tr
from vial_device import VialKeyboard
@ -202,6 +203,7 @@ class MacroRecorder(BasicEditor):
self.recorder.start()
def on_stop(self):
self.keystrokes = macro_optimize(self.keystrokes)
print(self.keystrokes)
def on_keystroke(self, keystroke):

View File

@ -0,0 +1,22 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import unittest
from keycodes import find_keycode
from macro_key import KeyDown, KeyTap
from macro_optimizer import remove_repeats
KC_A = find_keycode(0x04)
KC_B = find_keycode(0x05)
KC_C = find_keycode(0x06)
class TestMacro(unittest.TestCase):
def test_remove_repeats(self):
self.assertEqual(remove_repeats([KeyDown(KC_A), KeyDown(KC_A)]), [KeyDown(KC_A)])
self.assertEqual(remove_repeats([KeyDown(KC_A), KeyDown(KC_B), KeyDown(KC_B), KeyDown(KC_C), KeyDown(KC_C)]),
[KeyDown(KC_A), KeyDown(KC_B), KeyDown(KC_C)])
# don't remove repeated taps
self.assertEqual(remove_repeats([KeyTap(KC_A), KeyTap(KC_A)]), [KeyTap(KC_A), KeyTap(KC_A)])