Commit 1657bcd7 authored by anthraxx's avatar anthraxx
Browse files

implemented non-blocking input handling

parent a2246bbf
......@@ -4,6 +4,7 @@ import logging
from sys import exit
from signal import signal, SIGINT
from argparse import ArgumentParser
from time import sleep
from foobarpay.db import Database
from foobarpay.display import HIDrawDisplay, FifoDisplay
......@@ -18,6 +19,7 @@ class FooBarPay:
DEFAULT_DISPLAY = '/dev/hidraw1'
DEFAULT_DATABASE = 'sqlite:///foobarpay.sqlite'
ALLOW_CUSTOMER_CREATION = False
INPUT_BLOCK_TIME = 0.5
def __init__(self, cli_arguments):
logging.basicConfig(level=logging.DEBUG if cli_arguments.debug else logging.INFO)
......@@ -58,7 +60,12 @@ class FooBarPay:
logging.info("Welcome to foobarpay")
signal(SIGINT, lambda s, f: exit(0))
while True:
self.logic.handle_scanned_text(self.scanner.read())
sleep(self.INPUT_BLOCK_TIME)
line = self.scanner.read()
if line:
self.logic.handle_scanned_text(line)
continue
self.logic.tick()
if __name__ == "__main__":
parser = ArgumentParser()
......
......@@ -2,7 +2,7 @@ from foobarpay.model.customer import Customer
from foobarpay.model.product import Product
import logging
from time import sleep
from time import sleep, time
from enum import Enum
......@@ -18,12 +18,14 @@ class Logic(object):
self.display = display
self.database = database
self.allow_customer_creation = allow_customer_creation
self.last_action = 0
self.reset()
def reset(self, sleep_duration=0):
logging.debug("Resetting logic")
sleep(sleep_duration)
self.state = self.State.Idle
self.last_action = time()
self.cart = 0
self.customer = None
self.display.show_welcome()
......@@ -56,6 +58,7 @@ class Logic(object):
def handle_scanned_text(self, scanned_text):
try:
self.last_action = time()
if scanned_text.startswith(self.USER_ID_PREFIX):
# TODO: add proper checksum
scanned_text = scanned_text[:-1]
......@@ -102,3 +105,8 @@ class Logic(object):
)
except ValueError:
pass
def tick(self):
# TODO: check last_action and reset() with message
pass
from evdev import InputDevice, ecodes
from fcntl import fcntl, F_SETFL, F_GETFL
from os import O_NONBLOCK, read
class EvdevScanner(object):
def __init__(self, device):
self.device = InputDevice(device)
self.buffer = ""
self.scancodes = {
2: u'1',
3: u'2',
......@@ -47,19 +50,32 @@ class EvdevScanner(object):
self.device.grab()
def read(self):
input_buffer = ""
for event in self.device.read_loop():
if event.type == ecodes.EV_KEY and event.value == 1:
if event.code == 28:
break
else:
input_buffer += self.scancodes.get(event.code) or ""
return input_buffer
if event.type != ecodes.EV_KEY or event.value != 1:
return None
scanned_input = self.scancodes.get(event.code)
if scanned_input == "\n":
line = self.buffer
self.buffer = ""
return line
self.buffer += scanned_input or ""
class FifoScanner(object):
def __init__(self, device):
self.fifo = open(device, 'r')
self.fd = self.fifo.fileno()
self.buffer = ""
fcntl(self.fd, F_SETFL, fcntl(self.fd, F_GETFL) | O_NONBLOCK)
def read(self):
return self.fifo.readline()[:-1]
try:
block = read(self.fd, 1024)
self.buffer += block.decode()
if not self.buffer.endswith("\n"):
return None
line = self.buffer[:-1]
self.buffer = ""
return line
except BlockingIOError:
return None
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment