use specialized namedtuple for events
This commit is contained in:
parent
5347f41d73
commit
bca21a7220
|
@ -23,7 +23,7 @@ if __name__ == '__main__':
|
|||
arg_parser = argparse.ArgumentParser(prog=APP_TITLE)
|
||||
arg_parser.add_argument('-v', '--verbose', action='count', default=0,
|
||||
help='increase the logger verbosity (may be repeated)')
|
||||
arg_parser.add_argument('-s', '--systray', action='store_true',
|
||||
arg_parser.add_argument('-S', '--no-systray', action='store_false', dest='systray',
|
||||
help='embed the application into the systray')
|
||||
arg_parser.add_argument('-N', '--no-notifications', action='store_false', dest='notifications',
|
||||
help='disable desktop notifications (if systray is enabled)')
|
||||
|
@ -67,5 +67,4 @@ if __name__ == '__main__':
|
|||
Gtk.main()
|
||||
|
||||
watcher.stop()
|
||||
if args.notifications:
|
||||
ui.notify.set_active(False)
|
||||
ui.notify.set_active(False)
|
||||
|
|
|
@ -132,7 +132,7 @@ class Watcher(Thread):
|
|||
return None
|
||||
|
||||
if type(dev) == int:
|
||||
# assert self.listener
|
||||
assert self.listener
|
||||
dev = self.listener.request(api.get_device_info, dev)
|
||||
|
||||
if dev:
|
||||
|
@ -177,33 +177,33 @@ class Watcher(Thread):
|
|||
|
||||
devstatus.code = status_code
|
||||
devstatus.text = status_text
|
||||
_l.debug("%s update %s => %s: %s", devstatus, old_status_code, status_code, status_text)
|
||||
_l.debug("%s update %s => %s: %s", devstatus, old_status_code, status_code, status_text)
|
||||
|
||||
if self.notify and (status_code <= C.STATUS.CONNECTED or status_code != old_status_code):
|
||||
self.notify(devstatus.code, devstatus.name, devstatus.text)
|
||||
|
||||
return True
|
||||
|
||||
def _events_callback(self, code, devnumber, data):
|
||||
# _l.debug("event %s", (code, devnumber, data))
|
||||
def _events_callback(self, event):
|
||||
# _l.debug("event %s", event)
|
||||
|
||||
updated = False
|
||||
|
||||
if devnumber in self.devices:
|
||||
devstatus = self.devices[devnumber]
|
||||
if code == 0x10 and data[:1] == b'\x8F':
|
||||
if event.devnumber in self.devices:
|
||||
devstatus = self.devices[event.devnumber]
|
||||
if event.code == 0x10 and event.data[:1] == b'\x8F':
|
||||
updated = True
|
||||
self._device_status_changed(devstatus, C.STATUS.UNAVAILABLE)
|
||||
elif code == 0x11:
|
||||
status = devices.process_event(devstatus, data, self.listener)
|
||||
elif event.code == 0x11:
|
||||
status = devices.process_event(devstatus, event.data, self.listener)
|
||||
updated |= self._device_status_changed(devstatus, status)
|
||||
else:
|
||||
_l.warn("unknown event code %02x", code)
|
||||
elif devnumber:
|
||||
self._new_device(devnumber)
|
||||
_l.warn("unknown event %s", event)
|
||||
elif event.devnumber:
|
||||
self._new_device(event.devnumber)
|
||||
updated = True
|
||||
else:
|
||||
_l.warn("don't know how to handle event %s", (code, devnumber, data))
|
||||
_l.warn("don't know how to handle event %s", event)
|
||||
|
||||
if updated:
|
||||
self._update_status_text()
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
# Some common functions and types.
|
||||
#
|
||||
|
||||
from binascii import hexlify as _hexlify
|
||||
|
||||
|
||||
class FallbackDict(dict):
|
||||
def __init__(self, fallback_function=lambda x: None, *args, **kwargs):
|
||||
super(FallbackDict, self).__init__(*args, **kwargs)
|
||||
|
@ -46,4 +49,8 @@ ReprogrammableKeyInfo = namedtuple('ReprogrammableKeyInfo', [
|
|||
'task_name',
|
||||
'flags'])
|
||||
|
||||
class Packet(namedtuple('Packet', ['code', 'devnumber', 'data'])):
|
||||
def __str__(self):
|
||||
return 'Packet(0x%02x,%d,%s)' % (self.code, self.devnumber, _hexlify(self.data))
|
||||
|
||||
del namedtuple
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
from logging import getLogger as _Logger
|
||||
from threading import (Thread, Event, Lock)
|
||||
from time import sleep as _sleep
|
||||
# from time import sleep as _sleep
|
||||
|
||||
from . import base as _base
|
||||
from . import exceptions as E
|
||||
from .common import Packet
|
||||
|
||||
# for both Python 2 and 3
|
||||
try:
|
||||
|
@ -21,16 +22,15 @@ _l = _Logger('lur.listener')
|
|||
|
||||
|
||||
_READ_EVENT_TIMEOUT = int(_base.DEFAULT_TIMEOUT / 5) # ms
|
||||
_IDLE_SLEEP = _base.DEFAULT_TIMEOUT / 5 # ms
|
||||
|
||||
|
||||
def _callback_caller(listener, callback):
|
||||
# _l.log(_LOG_LEVEL, "%s starting callback caller", listener)
|
||||
while listener._active:
|
||||
while listener._active or not listener.events.empty():
|
||||
event = listener.events.get()
|
||||
_l.log(_LOG_LEVEL, "%s delivering event %s", listener, event)
|
||||
try:
|
||||
callback.__call__(*event)
|
||||
callback.__call__(event)
|
||||
except:
|
||||
_l.exception("callback for %s", event)
|
||||
# _l.log(_LOG_LEVEL, "%s stopped callback caller", listener)
|
||||
|
@ -55,11 +55,10 @@ class EventsListener(Thread):
|
|||
|
||||
self.task = None
|
||||
self.task_processing = Lock()
|
||||
|
||||
self.task_reply = None
|
||||
self.task_done = Event()
|
||||
|
||||
self.events = Queue(16)
|
||||
self.events = Queue(32)
|
||||
|
||||
self.event_caller = Thread(group='Unifying Receiver', name='Callback-%x' % receiver, target=_callback_caller, args=(self, events_callback))
|
||||
self.event_caller.daemon = True
|
||||
|
@ -77,23 +76,22 @@ class EventsListener(Thread):
|
|||
_base.unhandled_hook = self._unhandled
|
||||
|
||||
while self._active:
|
||||
event = None
|
||||
try:
|
||||
event = _base.read(self.receiver, _READ_EVENT_TIMEOUT)
|
||||
except E.NoReceiver:
|
||||
_l.warn("%s receiver disconnected", self)
|
||||
self.events.put(Packet(0xFF, 0xFF, None))
|
||||
self._active = False
|
||||
|
||||
if self._active:
|
||||
if event:
|
||||
# _l.log(_LOG_LEVEL, "%s queueing event %s", self, event)
|
||||
self.events.put(event)
|
||||
if event:
|
||||
_l.log(_LOG_LEVEL, "%s queueing event %s", self, event)
|
||||
self.events.put(Packet(*event))
|
||||
|
||||
if self.task is None:
|
||||
# _l.log(_LOG_LEVEL, "%s idle sleep", self)
|
||||
_sleep(_IDLE_SLEEP / 1000.0)
|
||||
else:
|
||||
self.task_reply = self._make_request(*self.task)
|
||||
self.task_done.set()
|
||||
if self.task:
|
||||
task, self.task = self.task, None
|
||||
self.task_reply = self._make_request(*task)
|
||||
self.task_done.set()
|
||||
|
||||
_base.close(self.receiver)
|
||||
self.__str_cached = 'Events(%x)' % self.receiver
|
||||
|
@ -102,9 +100,10 @@ class EventsListener(Thread):
|
|||
|
||||
def stop(self):
|
||||
"""Tells the listener to stop as soon as possible."""
|
||||
_l.log(_LOG_LEVEL, "%s stopping", self)
|
||||
self._active = False
|
||||
self.join()
|
||||
if self._active:
|
||||
_l.log(_LOG_LEVEL, "stopping %s", self)
|
||||
self._active = False
|
||||
self.join()
|
||||
|
||||
def request(self, api_function, *args, **kwargs):
|
||||
"""Make an UR API request through this listener's receiver.
|
||||
|
@ -114,14 +113,14 @@ class EventsListener(Thread):
|
|||
"""
|
||||
# _l.log(_LOG_LEVEL, "%s request '%s.%s' with %s, %s", self, api_function.__module__, api_function.__name__, args, kwargs)
|
||||
|
||||
self.task_processing.acquire()
|
||||
self.task_done.clear()
|
||||
self.task = (api_function, args, kwargs)
|
||||
if not self._active:
|
||||
return None
|
||||
|
||||
self.task_done.wait()
|
||||
reply = self.task_reply
|
||||
self.task = self.task_reply = None
|
||||
self.task_processing.release()
|
||||
with self.task_processing:
|
||||
self.task_done.clear()
|
||||
self.task = (api_function, args, kwargs)
|
||||
self.task_done.wait()
|
||||
reply, self.task_reply = self.task_reply, None
|
||||
|
||||
# _l.log(_LOG_LEVEL, "%s request '%s.%s' => %s", self, api_function.__module__, api_function.__name__, repr(reply))
|
||||
if isinstance(reply, Exception):
|
||||
|
@ -139,8 +138,8 @@ class EventsListener(Thread):
|
|||
self.task_reply = e
|
||||
|
||||
def _unhandled(self, reply_code, devnumber, data):
|
||||
event = (reply_code, devnumber, data)
|
||||
_l.log(_LOG_LEVEL, "%s queueing unhandled event %s", self, event)
|
||||
event = Packet(reply_code, devnumber, data)
|
||||
# _l.log(_LOG_LEVEL, "%s queueing unhandled event %s", self, event)
|
||||
self.events.put(event)
|
||||
|
||||
def __str__(self):
|
||||
|
|
Loading…
Reference in New Issue