8 changed files with 10 additions and 122 deletions
@ -1,113 +0,0 @@ |
|||
from collections import defaultdict |
|||
import gevent |
|||
from gevent.event import AsyncResult |
|||
|
|||
|
|||
class EventEmitter(object): |
|||
""" |
|||
Implements event emitter using ``gevent`` module. |
|||
Other modules can inherit from this object. |
|||
|
|||
.. code:: python |
|||
|
|||
class SomeClass(EventEmitter): |
|||
pass |
|||
|
|||
""" |
|||
|
|||
def emit(self, event, *args): |
|||
""" |
|||
Emit event with some arguments |
|||
|
|||
:type event: any |
|||
:param args: any or no arguments |
|||
""" |
|||
|
|||
gevent.idle() |
|||
|
|||
if hasattr(self, '_EventEmitter__callbacks'): |
|||
if event in self.__callbacks: |
|||
for callback in list(self.__callbacks[event]): |
|||
if isinstance(callback, AsyncResult): |
|||
self.remove_listener(event, callback) |
|||
|
|||
result = args |
|||
if len(args) == 1: |
|||
result = args[0] |
|||
|
|||
callback.set(result) |
|||
else: |
|||
gevent.spawn(callback, *args) |
|||
|
|||
gevent.idle() |
|||
|
|||
# every event is also emitted as None |
|||
if event is not None: |
|||
self.emit(None, event, *args) |
|||
|
|||
def remove_listener(self, event, callback): |
|||
""" |
|||
Removes callback for the specified event |
|||
|
|||
:param event: event identifier |
|||
:param callback: callback reference |
|||
:type callback: function, method or :py:class:`gevent.event.AsyncResult` |
|||
""" |
|||
|
|||
if not hasattr(self, '_EventEmitter__callbacks'): |
|||
return |
|||
|
|||
if event in self.__callbacks: |
|||
del self.__callbacks[event][callback] |
|||
|
|||
if not self.__callbacks[event]: |
|||
del self.__callbacks[event] |
|||
|
|||
def wait_event(self, event, timeout=None): |
|||
""" |
|||
Blocks until an event and returns the results |
|||
|
|||
:param event: event identifier |
|||
:param timeout: seconds to wait before raising an exception |
|||
:type timeout: int |
|||
:return: returns event arguments, if any. If there are many, returns tuple. |
|||
:rtype: None, any, or tuple |
|||
:raises: gevent.Timeout |
|||
""" |
|||
result = AsyncResult() |
|||
self.on(event, result) |
|||
return result.get(True, timeout) |
|||
|
|||
def on(self, event, callback=None): |
|||
""" |
|||
Registers a callback for the specified event |
|||
|
|||
:param event: event name |
|||
:param callback: callback function |
|||
|
|||
Can be as function decorator if only event is specified. |
|||
|
|||
.. code:: python |
|||
|
|||
@instaceOfSomeClass.on("some event") |
|||
def handle_event(): |
|||
pass |
|||
|
|||
instaceOfSomeClass.on("some event", handle_event) |
|||
|
|||
To listen for any event, use :py:class:`None` as event identifier. |
|||
""" |
|||
|
|||
if not hasattr(self, '_EventEmitter__callbacks'): |
|||
self.__callbacks = defaultdict(dict) |
|||
|
|||
# when used function |
|||
if callback: |
|||
self.__callbacks[event][callback] = None |
|||
return |
|||
|
|||
# as decorator |
|||
def wrapper(callback): |
|||
self.__callbacks[event][callback] = None |
|||
return callback |
|||
return wrapper |
Loading…
Reference in new issue