improved 0x30 input report mode performance, better error handling

This commit is contained in:
Robert Martin
2020-02-13 14:39:51 +09:00
parent eac7ca0a6f
commit 9b8cb2d949
6 changed files with 249 additions and 161 deletions
+3 -116
View File
@@ -1,133 +1,19 @@
import argparse
import asyncio
import inspect
import logging
import os
from contextlib import contextmanager
from aioconsole import ainput
from joycontrol import logging_default as log
from joycontrol.command_line_interface import ControllerCLI
from joycontrol.controller import Controller
from joycontrol.controller_state import button_push, ControllerState
from joycontrol.memory import FlashMemory
from joycontrol.protocol import controller_protocol_factory
from joycontrol.server import create_hid_server
logger = logging.getLogger(__name__)
class ControllerCLI:
def __init__(self, controller_state: ControllerState):
self.controller_state = controller_state
self.commands = {}
async def cmd_help(self):
print('Buttons can be used as commands: ', ', '.join(self.controller_state.button_state.get_available_buttons()))
for name, fun in inspect.getmembers(self):
if name.startswith('cmd_') and fun.__doc__:
print(fun.__doc__)
print('Commands can be chained using "&&"')
print('Type "exit" to close.')
@staticmethod
def _set_stick(stick, direction, value):
if direction == 'center':
stick.set_center()
elif direction == 'up':
stick.set_up()
elif direction == 'down':
stick.set_down()
elif direction == 'left':
stick.set_left()
elif direction == 'right':
stick.set_right()
elif direction in ('h', 'horizontal'):
if value is None:
raise ValueError(f'Missing value')
try:
val = int(value)
except ValueError:
raise ValueError(f'Unexpected stick value "{value}"')
stick.set_h(val)
elif direction in ('v', 'vertical'):
if value is None:
raise ValueError(f'Missing value')
try:
val = int(value)
except ValueError:
raise ValueError(f'Unexpected stick value "{value}"')
stick.set_v(val)
else:
raise ValueError(f'Unexpected argument "{direction}"')
return f'{stick.__class__.__name__} was set to ({stick.get_h()}, {stick.get_v()}).'
async def cmd_stick(self, side, direction, value=None):
"""
stick - Command to set stick positions.
:param side: 'l', 'left' for left control stick; 'r', 'right' for right control stick
:param direction: 'center', 'up', 'down', 'left', 'right';
'h', 'horizontal' or 'v', 'vertical' to set the value directly to the "value" argument
:param value: horizontal or vertical value
"""
if side in ('l', 'left'):
stick = self.controller_state.l_stick_state
return ControllerCLI._set_stick(stick, direction, value)
elif side in ('r', 'right'):
stick = self.controller_state.r_stick_state
return ControllerCLI._set_stick(stick, direction, value)
else:
raise ValueError('Value of side must be "l", "left" or "r", "right"')
def add_command(self, name, command):
if name in self.commands:
raise ValueError(f'Command {name} already registered.')
self.commands[name] = command
async def run(self):
while True:
user_input = await ainput(prompt='cmd >> ')
if not user_input:
continue
buttons_to_push = []
for command in user_input.split('&&'):
cmd, *args = command.split()
if cmd == 'exit':
return
available_buttons = self.controller_state.button_state.get_available_buttons()
if hasattr(self, f'cmd_{cmd}'):
try:
result = await getattr(self, f'cmd_{cmd}')(*args)
if result:
print(result)
except Exception as e:
print(e)
elif cmd in self.commands:
try:
result = await self.commands[cmd](*args)
if result:
print(result)
except Exception as e:
print(e)
elif cmd in available_buttons:
buttons_to_push.append(cmd)
else:
print('command', cmd, 'not found, call help for help.')
if buttons_to_push:
await button_push(self.controller_state, *buttons_to_push)
else:
await self.controller_state.send()
async def _main(controller, capture_file=None, spi_flash=None):
factory = controller_protocol_factory(controller, spi_flash=spi_flash)
transport, protocol = await create_hid_server(factory, 17, 19, capture_file=capture_file)
@@ -147,7 +33,8 @@ if __name__ == '__main__':
raise PermissionError('Script must be run as root!')
# setup logging
log.configure(console_level=logging.ERROR)
#log.configure(console_level=logging.ERROR)
log.configure()
parser = argparse.ArgumentParser()
parser.add_argument('controller', help='JOYCON_R, JOYCON_L or PRO_CONTROLLER')