70 lines
2.0 KiB
Python
70 lines
2.0 KiB
Python
import logging
|
|
|
|
from kmk.common.event_defs import KEY_DOWN_EVENT, KEY_UP_EVENT
|
|
|
|
|
|
class ReduxStore:
|
|
def __init__(self, reducer, log_level=logging.NOTSET):
|
|
self.reducer = reducer
|
|
self.logger = logging.getLogger(__name__)
|
|
self.logger.setLevel(log_level)
|
|
self.state = self.reducer(logger=self.logger)
|
|
|
|
def dispatch(self, action):
|
|
self.logger.debug('Dispatching action: {}'.format(action))
|
|
self.state = self.reducer(self.state, action)
|
|
self.logger.debug('Dispatching complete: {}'.format(action))
|
|
|
|
def get_state(self):
|
|
return self.state
|
|
|
|
|
|
class InternalState:
|
|
modifiers_pressed = frozenset()
|
|
keys_pressed = frozenset()
|
|
|
|
def __repr__(self):
|
|
return 'InternalState(mods={}, keys={})'.format(
|
|
self.modifiers_pressed,
|
|
self.keys_pressed,
|
|
)
|
|
|
|
def copy(self, modifiers_pressed=None, keys_pressed=None):
|
|
new_state = InternalState()
|
|
|
|
if modifiers_pressed is None:
|
|
new_state.modifiers_pressed = self.modifiers_pressed.copy()
|
|
else:
|
|
new_state.modifiers_pressed = modifiers_pressed
|
|
|
|
if keys_pressed is None:
|
|
new_state.keys_pressed = self.keys_pressed.copy()
|
|
else:
|
|
new_state.keys_pressed = keys_pressed
|
|
|
|
return new_state
|
|
|
|
|
|
def kmk_reducer(state=None, action=None, logger=None):
|
|
if state is None:
|
|
state = InternalState()
|
|
|
|
if logger is not None:
|
|
logger.debug('Reducer received state of None, creating new')
|
|
|
|
if action is None:
|
|
if logger is not None:
|
|
logger.debug('No action received, returning state unmodified')
|
|
|
|
return state
|
|
|
|
if action['type'] == KEY_UP_EVENT:
|
|
return state.copy(keys_pressed=frozenset(
|
|
key for key in state.keys_pressed if key != action['keycode']
|
|
))
|
|
|
|
if action['type'] == KEY_DOWN_EVENT:
|
|
return state.copy(keys_pressed=(
|
|
state.keys_pressed | {action['keycode']}
|
|
))
|