Skip to content

Instantly share code, notes, and snippets.

@EntityReborn
Created November 4, 2011 18:42
Show Gist options
  • Save EntityReborn/1340127 to your computer and use it in GitHub Desktop.
Save EntityReborn/1340127 to your computer and use it in GitHub Desktop.
Hookable events
from threading import RLock
from collections import defaultdict
import traceback
class Hookable(object):
NONEVALUE = object()
def __init__(self):
self.hooks = defaultdict(list)
self.hooklock = RLock()
def addHook(self, name, func, *args, **kwargs):
name = name.upper()
if callable(func):
with self.hooklock:
self.hooks[name].append([func, args, kwargs])
def delHook(self, name, func):
name = name.upper()
with self.hooklock:
if func in self.hooks[name]:
self.hooks[name].remove(func)
def fireHook(self, name, *args):
name = name.upper()
with self.hooklock:
if name in self.hooks:
for hookdata in self.hooks[name]:
hook, hargs, hkwargs = hookdata
try:
retn = hook(*(args+hargs), **hkwargs)
except Exception:
print "----- Exception! -----"
traceback.print_exc(5)
print "----------------------"
for hookdata in self.hooks["*"]:
hook, hargs, hkwargs = hookdata
try:
hook(name, *(args+hargs), **hkwargs)
except Exception:
traceback.print_exc(5)
from hooks import Hookable
h = Hookable()
# Basic hook and fire
def fireTests():
def fire():
# Hook up a callback to a hookpoint.
def printText():
print "'fire' Test Pass."
h.addHook("fire", printText)
h.fireHook("fire")
def multiFire():
# Hook up multiple callbacks and they will be called
# in the order they were added.
def printText1():
print "'multifire' Test A Pass."
def printText2():
print "'multifire' Test B Pass."
h.addHook("multifire", printText1)
h.addHook("multifire", printText2)
h.fireHook("multifire")
fire()
multiFire()
def argTests():
def argument():
# Pass arguments to callbacks
def printText(text):
print text
h.addHook("argument", printText)
h.fireHook("argument", "'argument' Test Pass.")
def multiArgs():
# Pass more than one
def printText(text, moretext):
print text, moretext
h.addHook("multiargs", printText)
h.fireHook("multiargs", "'multiargs' Test", "Pass.")
argument()
multiArgs()
def callbackArgTests():
def callbackArgs():
# Each hook callback can specify data specific to that callback.
def printText(text, arg):
print text % arg
h.addHook("callbackargs", printText, "Pass")
h.fireHook("callbackargs", "'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 hook call.
def printText1(text, arg):
arg["msg"] = "Pass"
def printText2(text, arg):
print "%s %s." % (text, arg["msg"])
h.addHook("statemanip", printText1)
h.addHook("statemanip", printText2)
arg = {"msg": "Fail"}
h.fireHook("statemanip", "'statemanip' Test", arg)
stateManip()
fireTests()
argTests()
callbackArgTests()
manipTests()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment