Make some events (and especially macros) faster by caching BareEvents and many key events in RAM
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user