Make some events (and especially macros) faster by caching BareEvents and many key events in RAM

This commit is contained in:
Josh Klar 2018-10-08 05:04:06 -07:00
parent c0b78fe3f2
commit 0d847f99ef
No known key found for this signature in database
GPG Key ID: 220F99BD7DB7A99E
4 changed files with 106 additions and 60 deletions

View File

@ -32,6 +32,20 @@ KeycodeUpDown = namedtuple('KeycodeUpDown', ('type', 'keycode'))
NewMatrix = namedtuple('NewMatrix', ('type', 'matrix'))
BareEvent = namedtuple('BareEvent', ('type',))
hid_report_event = BareEvent(
type=HID_REPORT_EVENT,
)
macro_complete_event = BareEvent(
type=MACRO_COMPLETE_EVENT,
)
pending_keycode_pop_event = BareEvent(
type=PENDING_KEYCODE_POP_EVENT,
)
def init_firmware(keymap, row_pins, col_pins, diode_orientation):
return InitFirmware(
@ -88,24 +102,6 @@ def new_matrix_event(matrix):
)
def hid_report_event():
return BareEvent(
type=HID_REPORT_EVENT,
)
def macro_complete_event():
return BareEvent(
type=MACRO_COMPLETE_EVENT,
)
def pending_keycode_pop_event():
return BareEvent(
type=PENDING_KEYCODE_POP_EVENT,
)
def matrix_changed(new_pressed):
def _key_pressed(dispatch, get_state):
dispatch(new_matrix_event(new_pressed))
@ -113,7 +109,7 @@ def matrix_changed(new_pressed):
state = get_state()
if state.hid_pending:
dispatch(hid_report_event())
dispatch(hid_report_event)
if Keycodes.KMK.KC_RESET in state.keys_pressed:
reset_bootloader()
@ -122,13 +118,13 @@ def matrix_changed(new_pressed):
for key in state.pending_keys:
if not key.no_press:
dispatch(keycode_down_event(key))
dispatch(hid_report_event())
dispatch(hid_report_event)
if not key.no_release:
dispatch(keycode_up_event(key))
dispatch(hid_report_event())
dispatch(hid_report_event)
dispatch(pending_keycode_pop_event())
dispatch(pending_keycode_pop_event)
if state.macro_pending:
macro = state.macro_pending
@ -136,6 +132,6 @@ def matrix_changed(new_pressed):
for event in macro(state):
dispatch(event)
dispatch(macro_complete_event())
dispatch(macro_complete_event)
return _key_pressed

View File

@ -85,6 +85,7 @@ class ModifierKeycode(Keycode):
if modified_code is None and no_press is None and no_release is None:
return self
if modified_code is not None:
new_keycode = Keycode(
modified_code.code,
{self.code},
@ -94,6 +95,12 @@ class ModifierKeycode(Keycode):
if modified_code.has_modifiers:
new_keycode.has_modifiers |= modified_code.has_modifiers
else:
new_keycode = Keycode(
self.code,
no_press=no_press,
no_release=no_release,
)
return new_keycode

View File

@ -5,6 +5,21 @@ from kmk.common.event_defs import (hid_report_event, keycode_down_event,
from kmk.common.keycodes import Keycodes, Macro, RawKeycodes, char_lookup
from kmk.common.kmktime import sleep_ms
kc_lookup_cache = {}
def lookup_kc_with_cache(char):
found_code = kc_lookup_cache.get(
char,
getattr(Keycodes.Common, 'KC_{}'.format(char.upper())),
)
kc_lookup_cache[char] = found_code
kc_lookup_cache[char.upper()] = found_code
kc_lookup_cache[char.lower()] = found_code
return found_code
def simple_key_sequence(seq):
def _simple_key_sequence(state):
@ -15,11 +30,11 @@ def simple_key_sequence(seq):
if not getattr(key, 'no_press', None):
yield keycode_down_event(key)
yield hid_report_event()
yield hid_report_event
if not getattr(key, 'no_release', None):
yield keycode_up_event(key)
yield hid_report_event()
yield hid_report_event
return Macro(keydown=_simple_key_sequence)
@ -33,7 +48,7 @@ def send_string(message):
if char in char_lookup:
kc = char_lookup[char]
elif char in string.ascii_letters + string.digits:
kc = getattr(Keycodes.Common, 'KC_{}'.format(char.upper()))
kc = lookup_kc_with_cache(char)
if char.isupper():
kc = Keycodes.Modifiers.KC_LSHIFT(kc)

View File

@ -2,10 +2,20 @@ from kmk.common.consts import UnicodeModes
from kmk.common.event_defs import (hid_report_event, keycode_down_event,
keycode_up_event)
from kmk.common.keycodes import Common, Macro, Modifiers
from kmk.common.macros.simple import simple_key_sequence
from kmk.common.macros.simple import lookup_kc_with_cache, simple_key_sequence
from kmk.common.util import get_wide_ordinal
IBUS_KEY_COMBO = Modifiers.KC_LCTRL(Modifiers.KC_LSHIFT(Common.KC_U))
IBUS_KEY_DOWN = keycode_down_event(IBUS_KEY_COMBO)
IBUS_KEY_UP = keycode_up_event(IBUS_KEY_COMBO)
RALT_DOWN = keycode_down_event(Modifiers.KC_RALT)
RALT_UP = keycode_up_event(Modifiers.KC_RALT)
U_DOWN = keycode_down_event(Common.KC_U)
U_UP = keycode_up_event(Common.KC_U)
ENTER_DOWN = keycode_down_event(Common.KC_ENTER)
ENTER_UP = keycode_up_event(Common.KC_ENTER)
RALT_DOWN_NO_RELEASE = keycode_down_event(Modifiers.KC_RALT(no_release=True))
RALT_UP_NO_PRESS = keycode_up_event(Modifiers.KC_RALT(no_press=True))
def generate_codepoint_keysym_seq(codepoint):
@ -20,7 +30,7 @@ def generate_codepoint_keysym_seq(codepoint):
seq = [Common.KC_0 for _ in range(max(len(codepoint), 4))]
for idx, codepoint_fragment in enumerate(reversed(codepoint)):
seq[-(idx + 1)] = getattr(Common, 'KC_{}'.format(codepoint_fragment.upper()))
seq[-(idx + 1)] = lookup_kc_with_cache(codepoint_fragment)
return seq
@ -37,45 +47,63 @@ def unicode_string_sequence(unistring):
def unicode_codepoint_sequence(codepoints):
kc_seqs = (
generate_codepoint_keysym_seq(codepoint)
for codepoint in codepoints
)
kc_macros = [
simple_key_sequence(kc_seq)
for kc_seq in kc_seqs
]
def _unicode_sequence(state):
if state.unicode_mode == UnicodeModes.IBUS:
yield from _ibus_unicode_sequence(codepoints, state)
yield from _ibus_unicode_sequence(kc_macros, state)
elif state.unicode_mode == UnicodeModes.RALT:
yield from _ralt_unicode_sequence(codepoints, state)
yield from _ralt_unicode_sequence(kc_macros, state)
elif state.unicode_mode == UnicodeModes.WINC:
yield from _winc_unicode_sequence(codepoints, state)
yield from _winc_unicode_sequence(kc_macros, state)
return Macro(keydown=_unicode_sequence)
def _ralt_unicode_sequence(codepoints, state):
for codepoint in codepoints:
yield keycode_down_event(Modifiers.RALT(no_release=True))
yield from simple_key_sequence(generate_codepoint_keysym_seq(codepoint)).keydown(state)
yield keycode_up_event(Modifiers.RALT(no_press=True))
def _ralt_unicode_sequence(kc_macros, state):
for kc_macro in kc_macros:
yield RALT_DOWN_NO_RELEASE
yield hid_report_event
yield from kc_macro.keydown(state)
yield RALT_UP_NO_PRESS
yield hid_report_event
def _ibus_unicode_sequence(codepoints, state):
for codepoint in codepoints:
yield keycode_down_event(IBUS_KEY_COMBO)
yield hid_report_event()
yield keycode_up_event(IBUS_KEY_COMBO)
yield hid_report_event()
seq = generate_codepoint_keysym_seq(codepoint)
seq.append(Common.KC_ENTER)
yield from simple_key_sequence(seq).keydown(state)
def _ibus_unicode_sequence(kc_macros, state):
for kc_macro in kc_macros:
yield IBUS_KEY_DOWN
yield hid_report_event
yield IBUS_KEY_UP
yield hid_report_event
yield from kc_macro.keydown(state)
yield ENTER_DOWN
yield hid_report_event
yield ENTER_UP
yield hid_report_event
def _winc_unicode_sequence(codepoints, state):
def _winc_unicode_sequence(kc_macros, state):
'''
Send unicode sequence using WinCompose:
http://wincompose.info/
https://github.com/SamHocevar/wincompose
'''
for codepoint in codepoints:
yield keycode_down_event(Modifiers.RALT())
yield keycode_down_event(Common.KC_U())
yield from simple_key_sequence(generate_codepoint_keysym_seq(codepoint)).keydown(state)
for kc_macro in kc_macros:
yield RALT_DOWN
yield hid_report_event
yield RALT_UP
yield hid_report_event
yield U_DOWN
yield hid_report_event
yield U_UP
yield hid_report_event
yield from kc_macro.keydown(state)