SNIClient: prevent hang on exit if waiting on devices from SNI

This commit is contained in:
Fabian Dill 2022-06-12 03:20:03 +02:00 committed by Fabian Dill
parent e7ea827f02
commit 0869a2acc3
1 changed files with 18 additions and 11 deletions

View File

@ -78,7 +78,10 @@ class SNIClientCommandProcessor(ClientCommandProcessor):
snes_device_number = int(options[1]) snes_device_number = int(options[1])
self.ctx.snes_reconnect_address = None self.ctx.snes_reconnect_address = None
asyncio.create_task(snes_connect(self.ctx, snes_address, snes_device_number), name="SNES Connect") if self.ctx.snes_connect_task:
self.ctx.snes_connect_task.cancel()
self.ctx.snes_connect_task = asyncio.create_task(snes_connect(self.ctx, snes_address, snes_device_number),
name="SNES Connect")
return True return True
def _cmd_snes_close(self) -> bool: def _cmd_snes_close(self) -> bool:
@ -115,6 +118,7 @@ class Context(CommonContext):
command_processor = SNIClientCommandProcessor command_processor = SNIClientCommandProcessor
game = "A Link to the Past" game = "A Link to the Past"
items_handling = None # set in game_watcher items_handling = None # set in game_watcher
snes_connect_task: typing.Optional[asyncio.Task] = None
def __init__(self, snes_address, server_address, password): def __init__(self, snes_address, server_address, password):
super(Context, self).__init__(server_address, password) super(Context, self).__init__(server_address, password)
@ -181,6 +185,11 @@ class Context(CommonContext):
if not currently_dead: if not currently_dead:
self.death_state = DeathState.alive self.death_state = DeathState.alive
async def shutdown(self):
await super(Context, self).shutdown()
if self.snes_connect_task:
await self.snes_connect_task
def on_package(self, cmd: str, args: dict): def on_package(self, cmd: str, args: dict):
if cmd in {"Connected", "RoomUpdate"}: if cmd in {"Connected", "RoomUpdate"}:
if "checked_locations" in args and args["checked_locations"]: if "checked_locations" in args and args["checked_locations"]:
@ -653,16 +662,17 @@ async def get_snes_devices(ctx: Context) -> typing.List[str]:
} }
await socket.send(dumps(DeviceList_Request)) await socket.send(dumps(DeviceList_Request))
reply = loads(await socket.recv()) reply: dict = loads(await socket.recv())
devices = reply['Results'] if 'Results' in reply and len(reply['Results']) > 0 else None devices: typing.List[str] = reply['Results'] if 'Results' in reply and len(reply['Results']) > 0 else []
if not devices: if not devices:
snes_logger.info('No SNES device found. Please connect a SNES device to SNI.') snes_logger.info('No SNES device found. Please connect a SNES device to SNI.')
while not devices: while not devices and not ctx.exit_event.is_set():
await asyncio.sleep(1) await asyncio.sleep(0.1)
await socket.send(dumps(DeviceList_Request)) await socket.send(dumps(DeviceList_Request))
reply = loads(await socket.recv()) reply = loads(await socket.recv())
devices = reply['Results'] if 'Results' in reply and len(reply['Results']) > 0 else None devices = reply['Results'] if 'Results' in reply and len(reply['Results']) > 0 else []
if devices:
await verify_snes_app(socket) await verify_snes_app(socket)
await socket.close() await socket.close()
return sorted(devices) return sorted(devices)
@ -1319,7 +1329,7 @@ async def main():
ctx.run_gui() ctx.run_gui()
ctx.run_cli() ctx.run_cli()
snes_connect_task = asyncio.create_task(snes_connect(ctx, ctx.snes_address), name="SNES Connect") ctx.snes_connect_task = asyncio.create_task(snes_connect(ctx, ctx.snes_address), name="SNES Connect")
watcher_task = asyncio.create_task(game_watcher(ctx), name="GameWatcher") watcher_task = asyncio.create_task(game_watcher(ctx), name="GameWatcher")
await ctx.exit_event.wait() await ctx.exit_event.wait()
@ -1328,15 +1338,12 @@ async def main():
ctx.snes_reconnect_address = None ctx.snes_reconnect_address = None
if ctx.snes_socket is not None and not ctx.snes_socket.closed: if ctx.snes_socket is not None and not ctx.snes_socket.closed:
await ctx.snes_socket.close() await ctx.snes_socket.close()
if snes_connect_task:
snes_connect_task.cancel()
await watcher_task await watcher_task
await ctx.shutdown() await ctx.shutdown()
def get_alttp_settings(romfile: str): def get_alttp_settings(romfile: str):
lastSettings = Utils.get_adjuster_settings(GAME_ALTTP) lastSettings = Utils.get_adjuster_settings(GAME_ALTTP)
adjusted = False
adjustedromfile = '' adjustedromfile = ''
if lastSettings: if lastSettings:
choice = 'no' choice = 'no'