Created
November 5, 2011 20:08
-
-
Save EntityReborn/1341954 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 | |
class Hook(object): | |
NONEVALUE = object() | |
def __init__(self, doc=None): | |
if doc: | |
self.__doc__ = doc | |
self.hooks = list() | |
self.hooklock = RLock() | |
def attach(self, func, *args, **kwargs): | |
if callable(func): | |
with self.hooklock: | |
self.hooks.append([func, args, kwargs]) | |
def detach(self, func): | |
with self.hooklock: | |
for hookdata in self.hooks: | |
hookfunc = hookdata[0] | |
if func == hookfunc: | |
self.hooks.remove(hookdata) | |
def fire(self, *args): | |
with self.hooklock: | |
for hookdata in self.hooks: | |
func, hargs, hkwargs = hookdata | |
try: | |
retn = func(*(args+hargs), **hkwargs) | |
except Exception: | |
print "----- Exception! -----" | |
traceback.print_exc(5) | |
print "----------------------" | |
__call__ = fire |
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 hooks import Hook | |
from collections import namedtuple | |
def multiInstance(): | |
def fireTests(): | |
def fire(): | |
# Fire off an event | |
def printText(a): | |
print a | |
h = Hook() | |
h.attach(printText) | |
# You can fire hooks by 'calling' them | |
h("'fire' Test Pass.") | |
def multiFire(): | |
# Fire off an event to multiple subscribers | |
def printText1(a): | |
print a % "A" | |
def printText2(a): | |
print a % "B" | |
h = Hook() | |
h.attach(printText1) | |
h.attach(printText2) | |
# You can fire hooks by calling their .fire method. | |
h.fire("'multifire' Test %s Pass.") | |
fire() | |
multiFire() | |
def argTests(): | |
def argument(): | |
# Pass arguments to callbacks | |
def printText(text): | |
print text | |
h = Hook() | |
h.attach(printText) | |
h("'argument' Test Pass.") | |
def multiArgs(): | |
# Pass more than one | |
def printText(text, moretext): | |
print text, moretext | |
h = Hook() | |
h.attach(printText) | |
h("'multiargs' Test", "Pass.") | |
argument() | |
multiArgs() | |
def callbackArgTests(): | |
def callbackArgs(): | |
# Each hook callback can specify data specific to that callback. | |
def printText1(text, arg): | |
print text % arg | |
def printText2(text): | |
print text % "B Pass" | |
h = Hook() | |
h.attach(printText1, "A Pass") | |
h.attach(printText2) | |
h("'callbackargs' Test %s.") | |
callbackArgs() | |
def manipTests(): | |
def stateManip(): | |
# As with any object, a state object can be used as an argument. | |
# This can be a manner of "return values" from a subscriber. | |
def printText1(text, arg): | |
arg.msg = "Pass" | |
def printText2(text, arg): | |
print "%s %s." % (text, arg.msg) | |
h = Hook() | |
h.attach(printText1) | |
h.attach(printText2) | |
arg = namedtuple("arg", "msg") | |
arg.msg = "Fail" | |
h("'statemanip' Test", arg) | |
stateManip() | |
def docTests(): | |
# Specifying a 'doc' argument will allow hooks to have their own | |
# doc attributes. | |
h1 = Hook(doc="Generic Hook 1") | |
h2 = Hook(doc="Generic Hook 2") | |
if h1.__doc__ == "Generic Hook 1": | |
print "'doctest' A Pass." | |
if h2.__doc__ == "Generic Hook 2": | |
print "'doctest' B Pass." | |
def detachTests(): | |
# You can detach subscribers. | |
def printText(): | |
print "'detach' Test Fail." | |
h = Hook() | |
h.attach(printText) | |
h.detach(printText) | |
if not h.hooks: | |
print "'detach' Test Pass." | |
else: | |
h() | |
fireTests() | |
argTests() | |
callbackArgTests() | |
manipTests() | |
docTests() | |
detachTests() | |
multiInstance() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment