From b69f30da99f9096834f4389a13dd4ffac26e7a80 Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Mon, 7 Jun 2021 01:27:30 +0200
Subject: [PATCH] More TUI client refactoring.

---
 plomrogue_client/tui.py | 30 +++++++++++++++++++++++++++++-
 rogue_chat_curses.py    | 18 +-----------------
 2 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/plomrogue_client/tui.py b/plomrogue_client/tui.py
index 7cfc011..9f28a04 100644
--- a/plomrogue_client/tui.py
+++ b/plomrogue_client/tui.py
@@ -3,10 +3,17 @@ import curses
 
 
 
+class AbortOnGetkey(Exception):
+    pass
+
+
+
 class TUI:
 
     def __init__(self):
         self._log = []
+        self.do_refresh = True
+        self.store_widechar = False
         curses.wrapper(self.run_loop)
 
     def addstr(self, y, x, line, attr=0):
@@ -35,11 +42,32 @@ class TUI:
         self.stdscr = stdscr
         self.init_loop()
         while True:
-            self.loop()
+            try:
+                self.loop()
+            except AbortOnGetkey:
+                continue
+            self.do_refresh = True
 
     def log(self, msg):
         self._log += [msg]
+        self.do_refresh = True
 
+    def get_key_and_keycode(self):
+        try:
+            key = self.stdscr.getkey()
+        except curses.error:
+            raise AbortOnGetkey
+        keycode = None
+        if len(key) == 1:
+            keycode = ord(key)
+            # workaround for <https://stackoverflow.com/a/56390915>
+            if self.store_widechar:
+                self.store_widechar = False
+                key = bytes([195, keycode]).decode()
+            if keycode == 195:
+                self.store_widechar = True
+                raise AbortOnGetkey
+        return key, keycode
 
 
 def msg_into_lines_of_width(msg, width):
diff --git a/rogue_chat_curses.py b/rogue_chat_curses.py
index f798047..60c46b2 100755
--- a/rogue_chat_curses.py
+++ b/rogue_chat_curses.py
@@ -498,7 +498,6 @@ class RogueChatTUI(TUI):
         self.game = Game()
         self.game.tui = self
         self.parser = Parser(self.game)
-        self.do_refresh = True
         self.login_name = None
         self.map_mode = 'terrain + things'
         self.password = 'foo'
@@ -558,7 +557,6 @@ class RogueChatTUI(TUI):
         self.offset = YX(0,0)
         self.explorer = YX(0, 0)
         self.input_ = ''
-        self.store_widechar = False
         self.input_prompt = '> '
         self.action_descriptions = {
             'move': 'move',
@@ -1186,21 +1184,7 @@ class RogueChatTUI(TUI):
             self.do_refresh = False
         for msg in self.socket.get_message():
             handle_input(msg)
-        try:
-            key = self.stdscr.getkey()
-            self.do_refresh = True
-        except curses.error:
-            return
-        keycode = None
-        if len(key) == 1:
-            keycode = ord(key)
-            # workaround for <https://stackoverflow.com/a/56390915>
-            if self.store_widechar:
-                self.store_widechar = False
-                key = bytes([195, keycode]).decode()
-            if keycode == 195:
-                self.store_widechar = True
-                return
+        key, keycode = self.get_key_and_keycode()
         self.show_help = False
         self.draw_face = False
         if key == 'KEY_RESIZE':
-- 
2.30.2