diff --git a/buttonreader.py b/buttonreader.py index 34ad2e5..54f9e20 100644 --- a/buttonreader.py +++ b/buttonreader.py @@ -2,7 +2,78 @@ # https://gist.github.com/elshaka/2999082 # and make this configureable from __future__ import print_function + +import os +import serial from PySide import QtCore +from player import ButtonEvent + +_inputs = {} + +def _add_input(inputType, inputClass): + global _inputs + _inputs[inputType] = inputClass + +def get_input(inputType, args, app): + global _inputs + if inputType not in _inputs: + raise ValueError("'%s' is an unknown input type" % inputType) + return _inputs[inputType](app, *args) + +class BaseInput(QtCore.QThread): + def __init__(self, app, parent=None): + super(BaseInput, self).__init__(parent) + self._app = app + + def _sendButtonEvent(self, btn): + if self._app.activeWindow(): + QtCore.QCoreApplication.postEvent(self._app.activeWindow(), ButtonEvent(int(btn))) + class SerialThread(QtCore.QThread): dataReady = QtCore.Signal(str) + +class SerialInput(BaseInput): + def __init__(self, app, device, baudrate=9600, bytesize=8, parity='N', stopbits=1): + super(SerialInput, self).__init__(app) + try: + self._serial = serial.Serial(device, baudrate, bytesize, parity, stopbits) + except serial.SerialException as e: + raise InputException("Error: %s" % e) + + print(" >> serial %s initialized with rate %s %s%s%s" % (device, baudrate, bytesize, parity, stopbits)) + + def run(self): + while True: + c = self._serial.read(1) + if len(c) == 1 and ord(c) > ord('0') and ord(c) <= ord('9'): + self._sendButtonEvent(c) + +_add_input("Serial", SerialInput) + +class FifoInput(BaseInput): + def __init__(self, app, fifoPath, debug=False): + super(FifoInput, self).__init__(app) + self._path = fifoPath + self._debug = debug + if not os.path.exists(self._path): + try: + os.mkfifo(self._path) + except OSError as e: + raise InputException("Could not create fifo '%s': %s" % (self._path, e)) + if os.path.isfile(self._path) or os.path.isdir(self._path): + raise InputException("Fifo '%s' is not a fifo" % self._path) + + print(" >> Fifo initialized, using '%s'" % self._path) + + def run(self): + fifo = open(self._path) + while True: + c = fifo.read(1) + if len(c) == 1 and ord(c) > ord('0') and ord(c) <= ord('9'): + self._sendButtonEvent(c) + +_add_input("Fifo", FifoInput) + +class InputException(Exception): + pass diff --git a/seopardy.py b/seopardy.py index 9458f94..07dd996 100755 --- a/seopardy.py +++ b/seopardy.py @@ -11,6 +11,7 @@ from question import Questions, QuestionException from gamestate import GameState from game import SeopardyGame from config import check_config +from buttonreader import get_input, InputException def _parser(): parser = argparse.ArgumentParser(description="Sebas jeopardy/beopardy clone") @@ -69,6 +70,23 @@ if __name__ == '__main__': print("Error: Could not load music %s (file %s)" % (name, path), file=sys.stderr) sys.exit(1) + # create and start input threads + print(config["playerInput"]) + inputs = [] + for playerInput in config["playerInput"]: + args = playerInput.get("Args", []) + if args is None: + args = [] + + try: + inp = get_input(playerInput["Type"], args, app) + inputs.append(inp) + except InputException as e: + print("Error: %s" % e, file=sys.stderr) + sys.exit(1) + + inputs[-1].start() + # create board board = SeopardyGame(questions, gamestate) board.show()