_generic.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. # -*- coding: utf-8 -*-
  2. from threading import Thread, Lock
  3. import traceback
  4. import functools
  5. try:
  6. from queue import Queue
  7. except ImportError:
  8. from Queue import Queue
  9. class GenericListener(object):
  10. lock = Lock()
  11. def __init__(self):
  12. self.handlers = []
  13. self.listening = False
  14. self.queue = Queue()
  15. def invoke_handlers(self, event):
  16. for handler in self.handlers:
  17. try:
  18. if handler(event):
  19. # Stop processing this hotkey.
  20. return 1
  21. except Exception as e:
  22. traceback.print_exc()
  23. def start_if_necessary(self):
  24. """
  25. Starts the listening thread if it wans't already.
  26. """
  27. self.lock.acquire()
  28. try:
  29. if not self.listening:
  30. self.init()
  31. self.listening = True
  32. self.listening_thread = Thread(target=self.listen)
  33. self.listening_thread.daemon = True
  34. self.listening_thread.start()
  35. self.processing_thread = Thread(target=self.process)
  36. self.processing_thread.daemon = True
  37. self.processing_thread.start()
  38. finally:
  39. self.lock.release()
  40. def pre_process_event(self, event):
  41. raise NotImplementedError('This method should be implemented in the child class.')
  42. def process(self):
  43. """
  44. Loops over the underlying queue of events and processes them in order.
  45. """
  46. assert self.queue is not None
  47. while True:
  48. event = self.queue.get()
  49. if self.pre_process_event(event):
  50. self.invoke_handlers(event)
  51. self.queue.task_done()
  52. def add_handler(self, handler):
  53. """
  54. Adds a function to receive each event captured, starting the capturing
  55. process if necessary.
  56. """
  57. self.start_if_necessary()
  58. self.handlers.append(handler)
  59. def remove_handler(self, handler):
  60. """ Removes a previously added event handler. """
  61. self.handlers.remove(handler)