from socket import socket
from threading import Thread
from typing import (
- Callable, Generator, Iterator, Literal, NamedTuple, Optional, Self)
+ Any, Callable, Generator, Iterator, Literal, NamedTuple, Optional, Self)
from blessed import Terminal as BlessedTerminal
class Event(NamedTuple):
'Communication unit between threads.'
type_: str
- args: tuple = tuple()
+ payload: Any = None
class YX(NamedTuple):
'Send event into thread loop.'
self._q_input.put(event)
- def broadcast(self, type_, *args) -> None:
+ def broadcast(self, type_: str, payload: Any = None) -> None:
'Send event to main loop via queue.'
- self._q_to_main.put(Event(type_, args))
+ self._q_to_main.put(Event(type_, payload))
def process_main(self, event: Event) -> bool:
'Process event yielded from input queue.'
if yield_bonus:
self.process_bonus(yield_bonus)
except Exception as e: # pylint: disable=broad-exception-caught
- self._q_to_main.put(Event('EXCEPTION', (e,)))
+ self._q_to_main.put(Event('EXCEPTION', e))
class TuiLoop(Loop):
if not super().process_main(event):
return False
if event.type_ == 'ALERT':
- self._log_buffer += [f'???? {event.args[0]}']
+ self._log_buffer += [f'???? {event.payload}']
self._draw_log()
elif event.type_ == 'RECV':
- self._log_buffer += [f'<--- {event.args[0]}']
+ self._log_buffer += [f'<--- {event.payload}']
self._draw_log()
elif event.type_ == 'SEND':
- self._log_buffer += [f'---> {event.args[0]}']
+ self._log_buffer += [f'---> {event.payload}']
self._draw_log()
elif event.type_ == 'INPUT_PROMPT':
- if event.args[0] == 'ENTER':
+ if event.payload[0] == 'ENTER':
toks = self._prompt.split(maxsplit=1)
if toks and toks[0] in {'QUIT'}:
self.broadcast('SEND', IrcMessage(toks[0], toks[1:]))
else:
self.broadcast('ALERT', f'invalid message: {self._prompt}')
self._prompt = ''
- elif event.args[0] == 'BACKSPACE':
+ elif event.payload[0] == 'BACKSPACE':
self._prompt = self._prompt[:-1]
- elif event.args[0] == 'CHARACTER':
- self._prompt += event.args[1]
+ elif event.payload[0] == 'CHARACTER':
+ self._prompt += event.payload[1]
self._draw_prompt()
elif event.type_ == 'SIGWINCH':
self._calc_and_draw_all()
# from traceback import format_exception
# self._log_buffer += [
# f'DEBUG {line}' for line
- # in '\n'.join(format_exception(event.args[0])).split('\n')]
+ # in '\n'.join(format_exception(event.payload)).split('\n')]
# self._draw_log()
self._term.flush()
return True
def process_bonus(self, yielded: str) -> None:
if yielded == 'KEY_ENTER':
- self.broadcast('INPUT_PROMPT', 'ENTER')
+ self.broadcast('INPUT_PROMPT', ('ENTER',))
elif yielded == 'KEY_BACKSPACE':
- self.broadcast('INPUT_PROMPT', 'BACKSPACE')
+ self.broadcast('INPUT_PROMPT', ('BACKSPACE',))
elif len(yielded) == 1:
- self.broadcast('INPUT_PROMPT', 'CHARACTER', yielded)
+ self.broadcast('INPUT_PROMPT', ('CHARACTER', yielded))
elif yielded == '[81]':
self.broadcast('QUIT')
else:
q_to_main: SimpleQueue[Event] = SimpleQueue()
with Terminal().context(q_to_main) as term:
with Connection().context((HOST, PORT), q_to_main) as conn:
- q_to_main.put(
- Event('SEND',
- (IrcMessage('USER', [USERNAME, '0', '*', REALNAME]),)))
- q_to_main.put(
- Event('SEND',
- (IrcMessage('NICK', [NICKNAME]),)))
+ q_to_main.put(Event('SEND', IrcMessage('USER', [USERNAME, '0', '*',
+ REALNAME])))
+ q_to_main.put(Event('SEND', IrcMessage('NICK', [NICKNAME])))
while True:
event = q_to_main.get()
if event.type_ == 'QUIT':
term.tui.put(event)
elif event.type_ == 'SEND':
term.tui.put(event)
- event.args[0].send(conn)
+ event.payload.send(conn)
elif event.type_ == 'PING':
q_to_main.put(
- Event('SEND',
- (IrcMessage('PONG', [event.args[0]]),)))
+ Event('SEND', IrcMessage('PONG', [event.payload])))
elif event.type_ == 'RECV':
term.tui.put(event)
elif event.type_ == 'EXCEPTION':
- raise event.args[0]
+ raise event.payload
elif event.type_ == 'ALERT':
term.tui.put(event)
# elif event.type_ == 'DEBUG':