prelim module support

This commit is contained in:
Kyle Brown
2020-11-12 14:33:39 -08:00
parent a85ec2cc3f
commit 8839c1c7ec
13 changed files with 235 additions and 159 deletions

View File

@@ -8,12 +8,12 @@ class Extension:
def enable(self, keyboard):
self._enabled = True
self.on_runtime_enable(self, keyboard)
self.on_runtime_enable(keyboard)
def disable(self, keyboard):
self._enabled = False
self.on_runtime_disable(self, keyboard)
self.on_runtime_disable(keyboard)
# The below methods should be implemented by subclasses
@@ -32,7 +32,7 @@ class Extension:
'''
raise NotImplementedError
def after_matrix_scan(self, keyboard, matrix_update):
def after_matrix_scan(self, keyboard):
'''
Return value will be replace matrix update if supplied
'''

View File

@@ -31,29 +31,29 @@ class International(Extension):
make_key(code=151, names=('LANG8',))
make_key(code=152, names=('LANG9',))
def on_runtime_enable(self, keyboard):
def on_runtime_enable(self, sandbox):
return
def on_runtime_disable(self, keyboard):
def on_runtime_disable(self, sandbox):
return
def during_bootup(self, keyboard):
def during_bootup(self, sandbox):
return
def before_matrix_scan(self, keyboard):
def before_matrix_scan(self, sandbox):
return
def after_matrix_scan(self, keyboard, matrix_update):
def after_matrix_scan(self, sandbox):
return
def before_hid_send(self, keyboard):
def before_hid_send(self, sandbox):
return
def after_hid_send(self, keyboard):
def after_hid_send(self, sandbox):
return
def on_powersave_enable(self, keyboard):
def on_powersave_enable(self, sandbox):
return
def on_powersave_disable(self, keyboard):
def on_powersave_disable(self, sandbox):
return

View File

@@ -75,34 +75,33 @@ class LED(Extension):
'val': self.val,
}
def on_runtime_enable(self, keyboard):
def on_runtime_enable(self, sandbox):
return
def on_runtime_disable(self, keyboard):
def on_runtime_disable(self, sandbox):
return
def during_bootup(self, keyboard):
def during_bootup(self, sandbox):
return
def before_matrix_scan(self, keyboard):
def before_matrix_scan(self, sandbox):
return
def after_matrix_scan(self, keyboard, matrix_update):
def after_matrix_scan(self, sandbox):
return
def before_hid_send(self, keyboard):
def before_hid_send(self, sandbox):
return
def after_hid_send(self, keyboard):
def after_hid_send(self, sandbox):
if self._enabled and self.animation_mode:
self.animate()
return keyboard
def on_powersave_enable(self, keyboard):
return
def on_powersave_disable(self, keyboard):
def on_powersave_enable(self, sandbox):
return
def on_powersave_disable(self, sandbox):
return
def _init_effect(self):

View File

@@ -27,29 +27,29 @@ class MediaKeys(Extension):
make_consumer_key(code=179, names=('MEDIA_FAST_FORWARD', 'MFFD')) # 0xB3
make_consumer_key(code=180, names=('MEDIA_REWIND', 'MRWD')) # 0xB4
def on_runtime_enable(self, keyboard):
def on_runtime_enable(self, sandbox):
return
def on_runtime_disable(self, keyboard):
def on_runtime_disable(self, sandbox):
return
def during_bootup(self, keyboard):
def during_bootup(self, sandbox):
return
def before_matrix_scan(self, keyboard):
def before_matrix_scan(self, sandbox):
return
def after_matrix_scan(self, keyboard, matrix_update):
def after_matrix_scan(self, sandbox):
return
def before_hid_send(self, keyboard):
def before_hid_send(self, sandbox):
return
def after_hid_send(self, keyboard):
def after_hid_send(self, sandbox):
return
def on_powersave_enable(self, keyboard):
def on_powersave_enable(self, sandbox):
return
def on_powersave_disable(self, keyboard):
def on_powersave_disable(self, sandbox):
return

View File

@@ -141,37 +141,37 @@ class RGB(Extension):
on_release=handler_passthrough,
)
def on_runtime_enable(self, keyboard):
def on_runtime_enable(self, sandbox):
return
def on_runtime_disable(self, keyboard):
def on_runtime_disable(self, sandbox):
return
def during_bootup(self, keyboard):
def during_bootup(self, sandbox):
return
def before_matrix_scan(self, keyboard):
def before_matrix_scan(self, sandbox):
return
def after_matrix_scan(self, keyboard, matrix_update):
def after_matrix_scan(self, sandbox):
return
def before_hid_send(self, keyboard):
def before_hid_send(self, sandbox):
return
def after_hid_send(self, keyboard):
def after_hid_send(self, sandbox):
if self.animation_mode:
self.loopcounter += 1
if self.loopcounter >= 7:
self.animate()
self.loopcounter = 0
return keyboard
def on_powersave_enable(self, keyboard):
return
def on_powersave_disable(self, keyboard):
def on_powersave_enable(self, sandbox):
return
def on_powersave_disable(self, sandbox):
self._do_update()
@staticmethod

View File

@@ -26,7 +26,13 @@ class KMKKeyboard:
unicode_mode = UnicodeMode.NOOP
tap_time = 300
modules = []
extensions = []
sandbox = {
'matrix_update': None,
'secondary_matrix_update': None,
'active_layers': [0],
}
#####
# Internal State
@@ -298,9 +304,8 @@ class KMKKeyboard:
and do an isinstance check, but instead do string detection
'''
if any(
x.__class__.__module__
in {'kmk.extensions.split', 'kmk.extensions.ble_split'}
for x in self.extensions
x.__class__.__module__ in {'kmk.modules.split', 'kmk.modules.ble_split'}
for x in self.modules
):
return
@@ -335,6 +340,95 @@ class KMKKeyboard:
return self
def before_matrix_scan(self):
for module in self.modules:
try:
module.before_matrix_scan(self)
except Exception as err:
if self.debug_enabled:
print('Failed to run pre matrix function in module: ', err, module)
for ext in self.extensions:
try:
ext.before_matrix_scan(self.sandbox)
except Exception as err:
if self.debug_enabled:
print('Failed to run pre matrix function in extension: ', err, ext)
def after_matrix_scan(self):
for module in self.modules:
try:
module.after_matrix_scan(self)
except Exception as err:
if self.debug_enabled:
print('Failed to run post matrix function in module: ', err, module)
for ext in self.extensions:
try:
ext.after_matrix_scan(self.sandbox)
except Exception as err:
if self.debug_enabled:
print('Failed to run post matrix function in extension: ', err, ext)
def before_hid_send(self):
for module in self.modules:
try:
module.before_hid_send(self)
except Exception as err:
if self.debug_enabled:
print('Failed to run pre hid function in module: ', err, module)
for ext in self.extensions:
try:
ext.before_hid_send(self.sandbox)
except Exception as err:
if self.debug_enabled:
print('Failed to run pre hid function in extension: ', err, ext)
def after_hid_send(self):
for module in self.modules:
try:
module.after_hid_send(self)
except Exception as err:
if self.debug_enabled:
print('Failed to run post hid function in module: ', err, module)
for ext in self.extensions:
try:
ext.after_hid_send(self.sandbox)
except Exception as err:
if self.debug_enabled:
print('Failed to run post hid function in extension: ', err, ext)
def powersave_enable(self):
for module in self.modules:
try:
module.on_powersave_enable(self)
except Exception as err:
if self.debug_enabled:
print('Failed to run post hid function in module: ', err, module)
for ext in self.extensions:
try:
ext.on_powersave_enable(self.sandbox)
except Exception as err:
if self.debug_enabled:
print('Failed to run post hid function in extension: ', err, ext)
def powersave_disable(self):
for module in self.extensions:
try:
module.on_powersave_disable(self)
except Exception as err:
if self.debug_enabled:
print('Failed to run post hid function in module: ', err, module)
for ext in self.extensions:
try:
ext.on_powersave_disable(self.sandbox)
except Exception as err:
if self.debug_enabled:
print('Failed to run post hid function in extension: ', err, ext)
def go(self, hid_type=HIDModes.USB, **kwargs):
self.hid_type = hid_type
@@ -346,7 +440,8 @@ class KMKKeyboard:
try:
ext.during_bootup(self)
except Exception:
print('Failed to load extention', ext)
if self.debug_enabled:
print('Failed to load extention', ext)
self._init_matrix()
@@ -354,39 +449,23 @@ class KMKKeyboard:
while True:
self.state_changed = False
self.sandbox.active_layers = self.active_layers
for ext in self.extensions:
try:
ret = ext.before_matrix_scan(self)
if ret is not None:
if len(ret) == 3:
# f len is 3, assume matrix update
self.secondary_matrix_update = ret
except Exception as err:
print('Failed to run pre matrix function: ', err, ext)
self.before_matrix_scan()
self.matrix_update = self.matrix.scan_for_changes()
self.matrix_update = (
self.sandbox.matrix_update
) = self.matrix.scan_for_changes()
self.sandbox.secondary_matrix_update = self.secondary_matrix_update
for ext in self.extensions:
try:
self._matrix_modify = ext.after_matrix_scan(
self, self.matrix_update
)
if self._matrix_modify is not None:
self.matrix_update = self._matrix_modify
except Exception as err:
print('Failed to run post matrix function: ', err, ext)
self.after_matrix_scan()
self._handle_matrix_report(self.secondary_matrix_update)
self.secondary_matrix_update = None
self._handle_matrix_report(self.matrix_update)
self.matrix_update = None
for ext in self.extensions:
try:
ext.before_hid_send(self)
except Exception as err:
print('Failed to run pre hid function: ', err, ext)
self.before_hid_send()
if self.hid_pending:
self._send_hid()
@@ -400,25 +479,13 @@ class KMKKeyboard:
if self.hid_pending:
self._send_hid()
for ext in self.extensions:
try:
ext.after_hid_send(self)
except Exception as err:
print('Failed to run post hid function: ', err, ext)
self.after_hid_send()
if self._trigger_powersave_enable:
for ext in self.extensions:
try:
ext.on_powersave_enable(self)
except Exception as err:
print('Failed to run post hid function: ', err, ext)
self.powersave_enable()
if self._trigger_powersave_disable:
for ext in self.extensions:
try:
ext.on_powersave_disable(self)
except Exception as err:
print('Failed to run post hid function: ', err, ext)
self.powersave_disable()
if self.state_changed:
self._print_debug_cycle()

40
kmk/modules/__init__.py Normal file
View File

@@ -0,0 +1,40 @@
class InvalidExtensionEnvironment(Exception):
pass
class Module:
'''
Modules differ from extensions in that they not only can read the state, but
are allowed to modify the state. The will be loaded on boot, and are not
allowed to be unloaded as they are required to continue functioning in a
consistant manner.
'''
# The below methods should be implemented by subclasses
def during_bootup(self, keyboard):
raise NotImplementedError
def before_matrix_scan(self, keyboard):
'''
Return value will be injected as an extra matrix update
'''
raise NotImplementedError
def after_matrix_scan(self, keyboard):
'''
Return value will be replace matrix update if supplied
'''
raise NotImplementedError
def before_hid_send(self, keyboard):
raise NotImplementedError
def after_hid_send(self, keyboard):
raise NotImplementedError
def on_powersave_enable(self, keyboard):
raise NotImplementedError
def on_powersave_disable(self, keyboard):
raise NotImplementedError

View File

@@ -2,14 +2,14 @@
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from kmk.extensions import Extension
from kmk.hid import HIDModes
from kmk.kmktime import ticks_diff, ticks_ms
from kmk.matrix import intify_coordinate
from kmk.modules import Module
from storage import getmount
class BLE_Split(Extension):
class BLE_Split(Module):
'''Enables splitting keyboards wirelessly'''
def __init__(
@@ -46,12 +46,6 @@ class BLE_Split(Extension):
'_split_side': self.split_side,
}
def on_runtime_enable(self, keyboard):
return
def on_runtime_disable(self, keyboard):
return
def during_bootup(self, keyboard):
self._debug_enabled = keyboard.debug_enabled
self._ble.name = str(getmount('/').label)
@@ -83,13 +77,12 @@ class BLE_Split(Extension):
def before_matrix_scan(self, keyboard):
self._check_all_connections()
return self._receive()
return self._receive(keyboard)
def after_matrix_scan(self, keyboard, matrix_update):
if matrix_update:
matrix_update = self._send(matrix_update)
return matrix_update
return None
def after_matrix_scan(self, keyboard):
if keyboard.matrix_update:
keyboard.matrix_update = self._send(keyboard.matrix_update)
return
def before_hid_send(self, keyboard):
return
@@ -195,12 +188,12 @@ class BLE_Split(Extension):
self._uart = None
return update
def _receive(self):
def _receive(self, keyboard):
if self._uart is not None and self._uart.in_waiting > 0 or self._uart_buffer:
while self._uart.in_waiting >= 3:
self._uart_buffer.append(self._uart.read(3))
if self._uart_buffer:
update = bytearray(self._uart_buffer.pop(0))
return update
keyboard.secondary_matrix_update = bytearray(self._uart_buffer.pop(0))
return
return None

View File

@@ -1,10 +1,10 @@
'''One layer isn't enough. Adds keys to get to more of them'''
from micropython import const
from kmk.extensions import Extension
from kmk.key_validators import layer_key_validator
from kmk.keys import make_argumented_key
from kmk.kmktime import accurate_ticks, accurate_ticks_diff
from kmk.modules import Module
class LayerType:
@@ -18,7 +18,7 @@ class LayerType:
TT = const(5)
class Layers(Extension):
class Layers(Module):
'''Gives access to the keys used to enable the layer system'''
def __init__(self):
@@ -63,19 +63,13 @@ class Layers(Extension):
on_release=self._tt_released,
)
def on_runtime_enable(self, keyboard):
return
def on_runtime_disable(self, keyboard):
return
def during_bootup(self, keyboard):
return
def before_matrix_scan(self, keyboard):
return
def after_matrix_scan(self, keyboard, matrix_update):
def after_matrix_scan(self, keyboard):
return
def before_hid_send(self, keyboard):

View File

@@ -1,10 +1,10 @@
from kmk.extensions import Extension
from kmk.key_validators import mod_tap_validator
from kmk.keys import make_argumented_key
from kmk.kmktime import accurate_ticks, accurate_ticks_diff
from kmk.modules import Module
class ModTap(Extension):
class ModTap(Module):
def __init__(self):
self._mod_tap_timer = None
make_argumented_key(
@@ -14,19 +14,13 @@ class ModTap(Extension):
on_release=self.mt_released,
)
def on_runtime_enable(self, keyboard):
return
def on_runtime_disable(self, keyboard):
return
def during_bootup(self, keyboard):
return
def before_matrix_scan(self, keyboard):
return
def after_matrix_scan(self, keyboard, matrix_update):
def after_matrix_scan(self, keyboard):
return
def before_hid_send(self, keyboard):
@@ -41,21 +35,23 @@ class ModTap(Extension):
def on_powersave_disable(self, keyboard):
return
def mt_pressed(self, key, state, *args, **kwargs):
def mt_pressed(self, key, keyboard, *args, **kwargs):
'''Sets the timer start and acts like a modifier otherwise'''
state.keys_pressed.add(key.meta.mods)
keyboard.keys_pressed.add(key.meta.mods)
self._mod_tap_timer = accurate_ticks()
return state
return keyboard
def mt_released(self, key, state, *args, **kwargs):
def mt_released(self, key, keyboard, *args, **kwargs):
''' On keyup, check timer, and press key if needed.'''
state.keys_pressed.discard(key.meta.mods)
keyboard.keys_pressed.discard(key.meta.mods)
if self._mod_tap_timer and (
accurate_ticks_diff(accurate_ticks(), self._mod_tap_timer, state.tap_time)
accurate_ticks_diff(
accurate_ticks(), self._mod_tap_timer, keyboard.tap_time
)
):
state.hid_pending = True
state.tap_key(key.meta.kc)
keyboard.hid_pending = True
keyboard.tap_key(key.meta.kc)
self._mod_tap_timer = None
return state
return keyboard

View File

@@ -1,13 +1,13 @@
import board
import digitalio
from kmk.extensions import Extension
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import make_key
from kmk.kmktime import sleep_ms, ticks_diff, ticks_ms
from kmk.modules import Module
class Power(Extension):
class Power(Module):
def __init__(self, powersave_pin=None):
self.enable = False
self.powersave_pin = powersave_pin # Powersave pin board object
@@ -39,15 +39,8 @@ class Power(Extension):
'_psp': self._psp,
}
def on_runtime_enable(self, keyboard):
return
def on_runtime_disable(self, keyboard):
self.disable_powersave()
def during_bootup(self, keyboard):
self._i2c_scan()
return
def before_matrix_scan(self, keyboard):
return
@@ -55,7 +48,6 @@ class Power(Extension):
def after_matrix_scan(self, keyboard, matrix_update):
if matrix_update or keyboard.secondary_matrix_update:
self.psave_time_reset()
return
def before_hid_send(self, keyboard):
return

View File

@@ -1,7 +1,7 @@
import busio
from kmk.extensions import Extension
from kmk.matrix import intify_coordinate
from kmk.modules import Module
from storage import getmount
@@ -11,7 +11,7 @@ class SplitType:
ONEWIRE = 3 # unused
class Split(Extension):
class Split(Module):
def __init__(
self,
is_target=True,
@@ -40,12 +40,6 @@ class Split(Extension):
self.uart_pin2 = uart_pin2
self.uart_timeout = uart_timeout
def on_runtime_enable(self, keyboard):
return
def on_runtime_disable(self, keyboard):
return
def during_bootup(self, keyboard):
try:
# Working around https://github.com/adafruit/circuitpython/issues/1769
@@ -94,12 +88,12 @@ class Split(Extension):
def before_matrix_scan(self, keyboard):
if self._is_target or self.uart_pin2:
return self._receive()
return self._receive(keyboard)
return None
def after_matrix_scan(self, keyboard, matrix_update):
if matrix_update is not None and not self._is_target:
self._send(matrix_update)
def after_matrix_scan(self, keyboard):
if keyboard.matrix_update is not None and not self._is_target:
self._send(keyboard.matrix_update)
def before_hid_send(self, keyboard):
return
@@ -121,7 +115,7 @@ class Split(Extension):
if self._uart is not None:
self._uart.write(update)
def _receive(self):
def _receive(self, keyboard):
if self._uart is not None and self._uart.in_waiting > 0 or self._uart_buffer:
if self._uart.in_waiting >= 60:
# This is a dirty hack to prevent crashes in unrealistic cases
@@ -132,8 +126,8 @@ class Split(Extension):
while self._uart.in_waiting >= 3:
self._uart_buffer.append(self._uart.read(3))
if self._uart_buffer:
update = bytearray(self._uart_buffer.pop(0))
keyboard.secondary_matrix_update = bytearray(self._uart_buffer.pop(0))
return update
return
return None