I wrote this prototype after reading the Wikipedia article on hooking. I didn't bother to read any of the code examples listed there because, well, I just didn't. I don't have a good excuse.
The documentation in this file should tell you enough about its purpose and intended usage. I'm looking for a confirmation of whether I even understand what hooks are and how they should be used. I'm also curious about any sort of preferred method of implementation or any way that I could improve these two objects (
"""Implement hooks with a simple interface using decorators. The Hook class creates a function that can be placed in code as an anchoring point for as yet undetermined functionality, while the OnHook function creates the interface to that functionality. To create a hook, use the @Hook decorator on an empty function of your chosen name. The function's __call__ method will be generated by the decorator. Then, create a function that accepts a function as an argument and adds it to the targets callback by using @OnHook. OnHook expects the target hook as an argument. Example: @Hook # decorator, no args def my_hook(): pass # empty func, no params @OnHook(my_hook) # decorator, hook as arg def on_my_hook(func): pass # empty func, func as param To add a callback to the new hook, use: on_my_hook(my_callback) When the hook is executed, your callback will be executed along with any other callbacks that have been registered. Written 2014-02-02 by Jack Stout. """ class Hook: """Decorator to create a hook.""" def __init__(self, func): self.callbacks =  def __call__(self): for callback in self.callbacks: callback() def OnHook(target): """Decorator to create an interface to a hook. Requires a target hook as only argument. """ def decorator(func): def add_callback(func): target.callbacks.append(func) return add_callback return decorator # Here I've created two hooks with interfaces which would be used # immediately before and after a hypothetical initiative() function. @Hook def pre_initiative(): pass @OnHook(pre_initiative) def on_pre_initiative(func): pass @Hook def post_initiative(): pass @OnHook(post_initiative) def on_post_initiative(func): pass # Two dummy functions are created and are added to the hooks' callback lists. def dummy_func_1(): print("Inside pre_initiative!") on_pre_initiative(dummy_func_1) def dummy_func_2(): print("Inside post_initiative!") on_post_initiative(dummy_func_2) # These print functions reveal what has been registered in the hook. print(pre_initiative.callbacks) # This function call is what we would see in production code. pre_initiative() print(post_initiative.callbacks) post_initiative()
Less important but related:
This is a prototype but I'm working on a game project that could benefit from this method of quickly attaching function pointers to upcoming state changes. While working on this file, I was imagining the first phase in a tabletop combat encounter where the players and game master roll initiatives and determine the combat order. If a character were to gain a power that allowed them to adjust their initiative roll after everyone has rolled, it would require only a call to
post_initiative() would fire and execute
Before getting any feedback, if I were to revisit this code I would add the ability to include arguments to be used with the callback, i.e.