Skip to content

Instantly share code, notes, and snippets.

@EntityReborn
Created November 5, 2011 20:08
Show Gist options
  • Save EntityReborn/1341954 to your computer and use it in GitHub Desktop.
Save EntityReborn/1341954 to your computer and use it in GitHub Desktop.
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
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