48 lines
1.4 KiB
Python
48 lines
1.4 KiB
Python
|
from functools import wraps
|
||
|
|
||
|
|
||
|
class _PluginManager(object):
|
||
|
def __init__(self):
|
||
|
self._registered_plugins = []
|
||
|
self._cached_base_callbacks = {}
|
||
|
self._built_functions = {}
|
||
|
|
||
|
def register(self, *plugins):
|
||
|
"""
|
||
|
Makes it possible to register your plugin.
|
||
|
"""
|
||
|
self._registered_plugins.extend(plugins)
|
||
|
self._build_functions()
|
||
|
|
||
|
def decorate(self, name=None):
|
||
|
def decorator(callback):
|
||
|
@wraps(callback)
|
||
|
def wrapper(*args, **kwargs):
|
||
|
return built_functions[public_name](*args, **kwargs)
|
||
|
|
||
|
public_name = name or callback.__name__
|
||
|
|
||
|
assert public_name not in self._built_functions
|
||
|
built_functions = self._built_functions
|
||
|
built_functions[public_name] = callback
|
||
|
self._cached_base_callbacks[public_name] = callback
|
||
|
|
||
|
return wrapper
|
||
|
|
||
|
return decorator
|
||
|
|
||
|
def _build_functions(self):
|
||
|
for name, callback in self._cached_base_callbacks.items():
|
||
|
for plugin in reversed(self._registered_plugins):
|
||
|
# Need to reverse so the first plugin is run first.
|
||
|
try:
|
||
|
func = getattr(plugin, name)
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
else:
|
||
|
callback = func(callback)
|
||
|
self._built_functions[name] = callback
|
||
|
|
||
|
|
||
|
plugin_manager = _PluginManager()
|