home · contact · privacy
Refactor Event queueing code.
authorChristian Heller <c.heller@plomlompom.de>
Fri, 30 May 2025 13:56:13 +0000 (15:56 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Fri, 30 May 2025 13:56:13 +0000 (15:56 +0200)
ircplom.py

index ef160ca6375e9b763d30984c51e8950f54315bc8..abafd7bb249ba663d2111bcf1fcf6962429004e7 100755 (executable)
@@ -34,6 +34,14 @@ class Event(NamedTuple):
     payload: Any = None
 
 
+class EventQueue(SimpleQueue):
+    'SimpleQueue wrapper optimized for handling Events.'
+
+    def eput(self, type_: str, payload: Any = None) -> None:
+        'Construct Event(type_, payload) and .put it onto queue.'
+        self.put(Event(type_, payload))
+
+
 class YX(NamedTuple):
     '2-dimensional coordinate.'
     y: int
@@ -53,7 +61,7 @@ class Terminal:
     _blessed: BlessedTerminal
 
     @contextmanager
-    def context(self, q_to_main: SimpleQueue) -> Generator:
+    def context(self, q_to_main: EventQueue) -> Generator:
         'Combine multiple contexts into one.'
         self._blessed = BlessedTerminal()
         with (self._blessed.raw(),
@@ -129,7 +137,7 @@ class Connection:
     @contextmanager
     def context(self,
                 address: tuple[str, int],
-                q_to_main: SimpleQueue
+                q_to_main: EventQueue
                 ) -> Generator:
         'Wrap socket and recv loop context.'
         with socket() as sock:
@@ -271,15 +279,15 @@ class IrcMessage:
 
 
 class Loop:
-    'Wraps thread looping over .put input queue, potential bonus iterator.'
+    'Wraps thread looping over .eput input queue, potential bonus iterator.'
 
     def __init__(self,
-                 q_to_main: SimpleQueue,
+                 q_to_main: EventQueue,
                  bonus_iterator: Optional[Iterator] = None
                  ) -> None:
         self._q_to_main = q_to_main
         self._bonus_iterator = bonus_iterator
-        self._q_input: SimpleQueue[Event] = SimpleQueue()
+        self._q_input = EventQueue()
         self._thread = Thread(target=self._loop, daemon=False)
         self._thread.start()
 
@@ -287,7 +295,7 @@ class Loop:
         return self
 
     def __exit__(self, *_) -> Literal[False]:
-        self._q_input.put(Event('QUIT'))
+        self._q_input.eput('QUIT')
         self._thread.join()
         return False  # re-raise any exception that above ignored
 
@@ -297,7 +305,7 @@ class Loop:
 
     def broadcast(self, type_: str, payload: Any = None) -> None:
         'Send event to main loop via queue.'
-        self._q_to_main.put(Event(type_, payload))
+        self._q_to_main.eput(type_, payload)
 
     def process_main(self, event: Event) -> bool:
         'Process event yielded from input queue.'
@@ -329,7 +337,7 @@ class Loop:
                     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.eput('EXCEPTION', e)
 
 
 class TuiLoop(Loop):
@@ -425,12 +433,12 @@ class KeyboardLoop(Loop):
 
 def run() -> None:
     'Main execution code / loop.'
-    q_to_main: SimpleQueue[Event] = SimpleQueue()
+    q_to_main = EventQueue()
     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.eput('SEND', IrcMessage('USER', [USERNAME, '0', '*',
+                                                       REALNAME]))
+            q_to_main.eput('SEND', IrcMessage('NICK', [NICKNAME]))
             while True:
                 event = q_to_main.get()
                 term.tui.put(event)
@@ -443,18 +451,15 @@ def run() -> None:
                 elif event.type_ == 'RECV':
                     msg: IrcMessage = event.payload
                     if msg.verb == 'PING':
-                        q_to_main.put(
-                                Event('SEND',
-                                      IrcMessage('PONG', [msg.parameters[0]])))
+                        q_to_main.eput('SEND',
+                                       IrcMessage('PONG', [msg.parameters[0]]))
                 elif event.type_ == 'PROMPT_COMMAND':
                     toks = event.payload.split(maxsplit=1)
                     if toks and toks[0] in {'QUIT'}:
-                        q_to_main.put(
-                                Event('SEND', IrcMessage(toks[0], toks[1:])))
+                        q_to_main.eput('SEND', IrcMessage(toks[0], toks[1:]))
                     else:
-                        q_to_main.put(
-                            Event('ALERT',
-                                  f'invalid message: {event.payload}'))
+                        q_to_main.eput('ALERT',
+                                       f'invalid message: {event.payload}')
 
 
 if __name__ == '__main__':