Skip to content

Instantly share code, notes, and snippets.

@Cobertos
Created January 27, 2018 03:55
Show Gist options
  • Save Cobertos/d12cf596b1e2802c6c3d300d6a38db57 to your computer and use it in GitHub Desktop.
Save Cobertos/d12cf596b1e2802c6c3d300d6a38db57 to your computer and use it in GitHub Desktop.
"""
Utility that allow a system of registering and unregistering of different modules
within a framework/add-on to be loaded into Blender
A module imported with this can have a bl_register and a bl_unregister at the
top level to add what it needs to Blender upon add-on load and unload
Note that this will handle recursively reloading of child modules, so module loops
will definitely cause headaches. Be wary of how you use this
"""
import importlib
import sys
from types import ModuleType
def rreload(module):
'''Recursively reload modules.'''
importlib.reload(module)
for childModule in [v for v in module.__dict__.values() if v is ModuleType]:
rreload(childModule)
class BLModuleLoader:
'''
A module loader that plays nice with Blenders reloading system
'''
def __init__(self):
self._registeredModules = {}
def _register(self, name):
'''
Imports and registers a single module where name is the "."
separated list for the package, absolute or relative
'''
importEquivalentStr = "import " + name
try:
if name in sys.modules:
print("Reloading import \"" + importEquivalentStr + "\"")
rreload(sys.modules[name])
else:
print("Importing for first time \"" + importEquivalentStr + "\"")
sys.modules[name] = importlib.import_module(name)
imported = sys.modules[name]
except ImportError as e:
print("Importing error " + name + ": " + str(e))
return None
if "bl_register" in dir(imported) and name not in self._registeredModules:
try:
imported.bl_register()
except ValueError as e:
print("Registration error " + name + ": " + str(e))
return None
self._registeredModules[name] = imported
return imported
def _unregister(self, name):
'''
Unregisters a previously registered module
'''
module = self._registeredModules[name]
if "bl_unregister" in dir(module):
try:
module.bl_unregister()
except ValueError as e:
print("Unregistration error " + name + ": " + str(e))
return None
del self._registeredModules[name]
def bl_register(self, moduleNames):
'''
Registers all the passed modules, returning a dict of all
the loaded modules, key'd by their passed names
'''
return { k : self._register(k) for k in moduleNames }
def bl_unregister(self):
'''
Unregisters all the modules that were previously imported
'''
for name in list(self._registeredModules.keys()):
self._unregister(name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment