Created
November 6, 2011 23:02
-
-
Save EntityReborn/1343746 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from threading import RLock | |
import traceback, inspect | |
class BadArgLength(AttributeError): pass | |
class Subscriber(object): | |
def __init__(self, func, subscriberargs): | |
self.func = func | |
self.args = subscriberargs | |
def fire(self, args): | |
allargs = args + self.args | |
self.func(*allargs) | |
__call__ = fire | |
class Hook(object): | |
def __init__(self, numargs, doc=None): | |
self._numargs = numargs | |
if doc: | |
self.__doc__ = doc | |
self.subscribers = list() | |
self._lock = RLock() | |
def attach(self, func, *customargs): | |
if callable(func): | |
# Lets make sure that the function's signature has the | |
# right amount of arguments! | |
arglength = len(inspect.getargspec(func).args) | |
reqlength = self._numargs + len(customargs) | |
if reqlength == arglength: | |
s = Subscriber(func, customargs) | |
with self._lock: | |
self.subscribers.append(s) | |
return s | |
# Incorrect number of arguments! | |
raise BadArgLength( | |
"%s needs to support %d native and %d custom args, but has %d!" % | |
(func, self._numargs, len(customargs), arglength)) | |
# Purposely raise an error, as at this point, it's not callable. | |
raise TypeError("%s is not callable!" % func) | |
def detach(self, func): | |
with self._lock: | |
for subscriber in self.subscribers: | |
if subscriber.func == func: | |
self.subscribers.remove(subscriber) | |
def fire(self, *args): | |
with self._lock: | |
subscribers = self.subscribers[:] | |
for subscriber in subscribers: | |
try: | |
subscriber(args) | |
except Exception: | |
print "----- Exception! -----" | |
traceback.print_exc(5) | |
print "----------------------" | |
__call__ = fire |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment