summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortroido <troido@hotmail.com>2018-04-18 23:27:34 +0200
committertroido <troido@hotmail.com>2018-04-18 23:27:34 +0200
commit757ad925b47d24b1d0714671b8f04147a5748480 (patch)
treebc67553d76ac3301db7d2c20881448afc411221d
parentc0eb8ed32d53030de5b75b49a8e0f64e7c4a05ff (diff)
improved input handling
renamed InputHandler to CommandHandler. made InputHandler for input code that used to be in gameclient also started my own getstr() replacement.
-rw-r--r--asciifarm/client/commandhandler.py84
-rw-r--r--asciifarm/client/gameclient.py12
-rw-r--r--asciifarm/client/inputhandler.py129
3 files changed, 139 insertions, 86 deletions
diff --git a/asciifarm/client/commandhandler.py b/asciifarm/client/commandhandler.py
new file mode 100644
index 0000000..7eefe5b
--- /dev/null
+++ b/asciifarm/client/commandhandler.py
@@ -0,0 +1,84 @@
+
+import shlex
+
+class InvalidCommandException(Exception):
+ pass
+
+
+class CommandHandler:
+
+ def __init__(self, client):
+ self.client = client
+
+ self.commands = {
+ "send": self.send,
+ "input": self.input,
+ "move": self.move,
+ "say": self.say,
+ "chat": self.chat,
+ "log": self.log,
+ "do": self.do,
+ "runinput": self.runInput,
+ "select": self.select,
+ "inputwithselected": self.actWithSelected,
+ "eval": self.eval,
+ "exec": self.exec,
+ "scrollchat": self.scrollChat
+ }
+
+ def execute(self, action):
+ if isinstance(action[0], str):
+ command = action[0]
+ if command in self.commands:
+ self.commands[command](*action[1:])
+ else:
+ raise InvalidCommandException("Invalid command '{}'".format(command))
+ else:
+ raise Exception("Command should be a string")
+
+
+ # Commands
+
+ def send(self, data):
+ self.client.send(data)
+
+ def input(self, action):
+ self.send(["input", action])
+
+ def move(self, direction):
+ self.input(["move", direction])
+
+ def say(self, text):
+ self.input(["say", text])
+
+ def chat(self, text):
+ self.send(["chat", text])
+
+ def log(self, text):
+ self.client.log(text)
+
+ def do(self, actions):
+ for action in actions:
+ self.execute(action)
+
+ def runInput(self):
+ self.client.inputHandler.typing = True
+
+ def select(self, widget, value, relative=False, modular=False):
+ self.client.display.getWidget(widget).select(value, relative, modular)
+
+ def actWithSelected(self, action, widget):
+ self.input([action, self.client.display.getWidget(widget).getSelected()])
+
+ def eval(self, *texts):
+ text = " ".join(texts)
+ self.log(eval(text, {"self": self, "client": self.client, "connection": self.client.connection, "display": self.client.display}))
+
+ def exec(self, *texts):
+ text = " ".join(texts)
+ exec(text, {"self": self, "client": self.client, "connection": self.client.connection, "display": self.client.display})
+
+ def scrollChat(self, lines):
+ self.client.display.scrollBack(lines)
+
+
diff --git a/asciifarm/client/gameclient.py b/asciifarm/client/gameclient.py
index ec90cc6..0a9b243 100644
--- a/asciifarm/client/gameclient.py
+++ b/asciifarm/client/gameclient.py
@@ -15,7 +15,6 @@ from .display.screen import Screen
from .display.display import Display
from .inputhandler import InputHandler
-from .keynames import nameFromKey
class Client:
@@ -28,8 +27,7 @@ class Client:
self.logFile = logFile
self.closeMessage = None
- self.inputHandler = InputHandler(self, self.display, self.connection)
- self.keybindings = keybindings["actions"]
+ self.inputHandler = InputHandler(self, keybindings["actions"])
self.controlsString = keybindings.get("help", "")
@@ -128,12 +126,6 @@ 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:
@@ -141,7 +133,7 @@ class Client:
if action[0] == "message":
self.update(action[1])
elif action[0] == "input":
- self.onInput(action[1])
+ self.inputHandler.onInput(action[1])
elif action[0] == "error":
raise action[1]
else:
diff --git a/asciifarm/client/inputhandler.py b/asciifarm/client/inputhandler.py
index 7fb18ad..1d907e9 100644
--- a/asciifarm/client/inputhandler.py
+++ b/asciifarm/client/inputhandler.py
@@ -1,96 +1,73 @@
-import shlex
-
-class InvalidCommandException(Exception):
- pass
-
+from commandhandler import CommandHandler
+from .keynames import nameFromKey
+import curses
+import curses.ascii
class InputHandler:
- def __init__(self, client, display, connection):
+ def __init__(self, client, keybindings):
self.client = client
- self.display = display
- self.connection = connection
+ self.keybindings = keybindings
+ self.commandHandler = CommandHandler(self.client)
- self.commands = {
- "send": self.send,
- "input": self.input,
- "move": self.move,
- "say": self.say,
- "chat": self.chat,
- "log": self.log,
- "do": self.do,
- "runinput": self.runInput,
- "select": self.select,
- "inputwithselected": self.actWithSelected,
- "eval": self.eval,
- "exec": self.exec,
- "scrollchat": self.scrollChat
- }
-
- def execute(self, action):
- if isinstance(action[0], str):
- command = action[0]
- if command in self.commands:
- self.commands[command](*action[1:])
- else:
- raise InvalidCommandException("Invalid command '{}'".format(command))
- else:
- raise Exception("Command should be a string")
-
-
-
- def send(self, data):
- self.client.send(data)
-
- def input(self, action):
- self.send(["input", action])
-
- def move(self, direction):
- self.input(["move", direction])
+ self.typing = False
+ self.string = ""
+ self.cursor = 0
- def say(self, text):
- self.input(["say", text])
- def chat(self, text):
- self.send(["chat", text])
-
- def log(self, text):
- self.client.log(text)
+ def onInput(self, key):
+ if not self.typing:
+ keyName = nameFromKey(key)
+ if keyName in self.keybindings:
+ self.commandHandler.execute(self.keybindings[keyName])
+ else:
+ self.addKey(key)
- def do(self, actions):
- for action in actions:
- self.execute(action)
- def runInput(self):
- message = self.display.getString()
+ def processString(self, message):
if message:
if message[0] == '/':
if message[1] == '/':
- self.chat(message[1:])
+ self.commandHandler.chat(message[1:])
else:
try:
- self.execute(shlex.split(message[1:]))
+ self.commandHandler.execute(shlex.split(message[1:]))
except InvalidCommandException as e:
- self.log(", ".join(e.args))
+ self.client.log(", ".join(e.args))
else:
- self.chat(message)
-
- def select(self, widget, value, relative=False, modular=False):
- self.display.getWidget(widget).select(value, relative, modular)
-
- def actWithSelected(self, action, widget):
- self.input([action, self.display.getWidget(widget).getSelected()])
-
- def eval(self, *texts):
- text = " ".join(texts)
- self.log(eval(text, {"self": self, "client": self.client, "connection": self.connection, "display": self.display}))
-
- def exec(self, *texts):
- text = " ".join(texts)
- exec(text, {"self": self, "client": self.client, "connection": self.connection, "display": self.display})
+ self.commandHandler.chat(message)
+
+
+ def addKey(self, key):
+ if curses.ascii.isprint(key):
+ self.string = self.string[:self.cursor] + chr(key) + self.string[self.cursor:]
+ self.cursor += 1
+ elif key == curses.KEY_BACKSPACE or key == curses.ascii.BS or key == curses.ascii.DEL:
+ self.string = self.string[:self.cursor-1] + self.string[self.cursor:]
+ self.cursor = max(self.cursor - 1, 0)
+ elif key == curses.KEY_RIGHT:
+ self.cursor = max(self.cursor + 1, len(self.string))
+ elif key == curses.KEY_LEFT:
+ self.cursor = max(self.cursor - 1, 0)
+ elif key == curses.KEY_DC:
+ self.string = self.string[:self.cursor] + self.string[self.cursor+1:]
+ elif key == curses.KEY_HOME:
+ self.cursor = 0
+ elif key == curses.KEY_END:
+ self.cursor = len(self.string)
+
+ elif key == curses.ascii.ESC or key == curses.KEY_DL:
+ self.typing = False
+ self.string = ""
+ self.cursor = 0
+ elif key == curses.ascii.LF or key == curses.ascii.CR:
+ message = self.string
+ self.string = ""
+ self.cursor = 0
+ self.typing = False
+ self.processString(message)
+
- def scrollChat(self, lines):
- self.display.scrollBack(lines)