macro_recorder: basic macro optimizer
parent
abf62439e4
commit
e5e342d397
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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)])
|
||||
Loading…
Reference in New Issue