summaryrefslogtreecommitdiff
path: root/asciifarm/client
diff options
context:
space:
mode:
authortroido <troido@hotmail.com>2018-04-18 12:43:19 +0200
committertroido <troido@hotmail.com>2018-04-18 12:43:19 +0200
commitc0eb8ed32d53030de5b75b49a8e0f64e7c4a05ff (patch)
tree7213e87795d631f7177c7a930f3a86a8143a47ff /asciifarm/client
parentd4a2a5742f41234e5bf2dafb7e3bcea8c24bb712 (diff)
client is now threadsafe; closing can now show messages
Diffstat (limited to 'asciifarm/client')
-rw-r--r--asciifarm/client/gameclient.py59
-rw-r--r--asciifarm/client/start.py12
2 files changed, 48 insertions, 23 deletions
diff --git a/asciifarm/client/gameclient.py b/asciifarm/client/gameclient.py
index 7d29caa..ec90cc6 100644
--- a/asciifarm/client/gameclient.py
+++ b/asciifarm/client/gameclient.py
@@ -8,8 +8,10 @@ import threading
import json
import getpass
import argparse
-from .display.screen import Screen
import string
+from queue import Queue
+
+from .display.screen import Screen
from .display.display import Display
from .inputhandler import InputHandler
@@ -24,6 +26,7 @@ class Client:
self.keepalive = True
self.connection = connection
self.logFile = logFile
+ self.closeMessage = None
self.inputHandler = InputHandler(self, self.display, self.connection)
self.keybindings = keybindings["actions"]
@@ -31,6 +34,7 @@ class Client:
self.controlsString = keybindings.get("help", "")
self.display.showInfo(self.controlsString)
+ self.queue = Queue()
def send(self, data):
@@ -38,20 +42,34 @@ class Client:
def start(self):
threading.Thread(target=self.listen, daemon=True).start()
+ threading.Thread(target=self.getInput, daemon=True).start()
+
self.connection.send(json.dumps(["name", self.name]))
self.command_loop()
def listen(self):
- self.connection.listen(self.update, self.close)
+ self.connection.listen(self.pushMessage, self.onConnectionError)
+
+ def pushMessage(self, databytes):
+ self.queue.put(("message", databytes))
+
+ def onConnectionError(self, error):
+ self.queue.put(("error", error))
- def close(self, err=None):
+ def getInput(self):
+ while True:
+ key = self.stdscr.getch()
+ self.queue.put(("input", key))
+
+ def close(self, msg=None):
self.keepalive = False
- sys.exit()
+ self.closeMessage = msg
def update(self, databytes):
- if not self.keepalive:
- sys.exit()
+ if len(databytes) == 0:
+ self.close("Connection closed by server")
+ return
datastr = databytes.decode('utf-8')
data = json.loads(datastr)
if len(data) and isinstance(data[0], str):
@@ -61,12 +79,10 @@ class Client:
if msgType == 'error':
error = msg[1]
if error == "nametaken":
- print("error: name is already taken", file=sys.stderr)
- self.close()
+ self.close("error: name is already taken")
return
if error == "invalidname":
- print("error: "+ msg[2], file=sys.stderr)
- self.close()
+ self.close("error: "+ msg[2])
return
self.log(error)
if msgType == 'field':
@@ -112,15 +128,24 @@ class Client:
with(open(self.logFile, 'a')) as f:
f.write(text+'\n')
+ def onInput(self, key):
+ keyName = nameFromKey(key)
+ if keyName in self.keybindings:
+ self.inputHandler.execute(self.keybindings[keyName])
+
+
+
def command_loop(self):
while self.keepalive:
- key = self.stdscr.getch()
- if key == 27:
- self.keepalive = False
- return
- keyName = nameFromKey(key)
- if keyName in self.keybindings:
- self.inputHandler.execute(self.keybindings[keyName])
+ action = self.queue.get()
+ if action[0] == "message":
+ self.update(action[1])
+ elif action[0] == "input":
+ self.onInput(action[1])
+ elif action[0] == "error":
+ raise action[1]
+ else:
+ raise Exception("invalid action in queue")
diff --git a/asciifarm/client/start.py b/asciifarm/client/start.py
index 0a6cfa4..3e24e4a 100644
--- a/asciifarm/client/start.py
+++ b/asciifarm/client/start.py
@@ -23,19 +23,19 @@ def main(name, socketType, address, keybindings, characters, colours=False, logf
print("ERROR: Could not connect to server.\nAre you sure that the server is running and that you're connecting to the right address?", file=sys.stderr)
return
- caught_ctrl_c = False
+ closeMessage = None
def start(stdscr):
display = Display(stdscr, characters, colours)
client = Client(stdscr, display, name, connection, keybindings, logfile)
- nonlocal caught_ctrl_c
try:
client.start()
except KeyboardInterrupt:
- client.keepAlive = False
- caught_ctrl_c = True
+ client.close("^C caught, goodbye")
+ nonlocal closeMessage
+ closeMessage = client.closeMessage
curses.wrapper(start)
- if caught_ctrl_c:
- print('^C caught, goodbye!')
+ if closeMessage:
+ print(closeMessage, file=sys.stderr)