diff --git a/modules/extensions_framework/__init__.py b/modules/extensions_framework/__init__.py index 7fcc98d92e917f9a8907f77e10e19d0779ba397e..78c6e25a79ad27f1d76ab51f1c1cae27a82f5110 100644 --- a/modules/extensions_framework/__init__.py +++ b/modules/extensions_framework/__init__.py @@ -115,71 +115,6 @@ def init_properties(obj, props, cache=True): # Silently skip invalid entries in props continue -def ef_initialise_properties(cls): - """This is a function that should be called on - sub-classes of declarative_property_group in order - to ensure that they are initialised when the addon - is loaded. - the init_properties is called without caching here, - as it is assumed that any addon calling this function - will also call ef_remove_properties when it is - unregistered. - - """ - - if not cls.ef_initialised: - for property_group_parent in cls.ef_attach_to: - if property_group_parent is not None: - prototype = getattr(bpy.types, property_group_parent) - if not hasattr(prototype, cls.__name__): - init_properties(prototype, [{ - 'type': 'pointer', - 'attr': cls.__name__, - 'ptype': cls, - 'name': cls.__name__, - 'description': cls.__name__ - }], cache=False) - - init_properties(cls, cls.properties, cache=False) - cls.ef_initialised = True - - return cls - -def ef_register_initialise_properties(cls): - """As ef_initialise_properties, but also registers the - class with RNA. Note that this isn't a great idea - because it's non-trivial to unregister the class, unless - you keep track of it yourself. - """ - - bpy.utils.register_class(cls) - ef_initialise_properties(cls) - return cls - -def ef_remove_properties(cls): - """This is a function that should be called on - sub-classes of declarative_property_group in order - to ensure that they are un-initialised when the addon - is unloaded. - - """ - - if cls.ef_initialised: - prototype = getattr(bpy.types, cls.__name__) - for prop in cls.properties: - if hasattr(prototype, prop['attr']): - delattr(prototype, prop['attr']) - - for property_group_parent in cls.ef_attach_to: - if property_group_parent is not None: - prototype = getattr(bpy.types, property_group_parent) - if hasattr(prototype, cls.__name__): - delattr(prototype, cls.__name__) - - cls.ef_initialised = False - - return cls - class declarative_property_group(bpy.types.IDPropertyGroup): """A declarative_property_group describes a set of logically related properties, using a declarative style to list each @@ -210,6 +145,75 @@ class declarative_property_group(bpy.types.IDPropertyGroup): """ ef_attach_to = [] + @classmethod + def initialise_properties(cls): + """This is a function that should be called on + sub-classes of declarative_property_group in order + to ensure that they are initialised when the addon + is loaded. + the init_properties is called without caching here, + as it is assumed that any addon calling this function + will also call ef_remove_properties when it is + unregistered. + + """ + + if not cls.ef_initialised: + for property_group_parent in cls.ef_attach_to: + if property_group_parent is not None: + prototype = getattr(bpy.types, property_group_parent) + if not hasattr(prototype, cls.__name__): + init_properties(prototype, [{ + 'type': 'pointer', + 'attr': cls.__name__, + 'ptype': cls, + 'name': cls.__name__, + 'description': cls.__name__ + }], cache=False) + + init_properties(cls, cls.properties, cache=False) + cls.ef_initialised = True + + return cls + + @classmethod + def register_initialise_properties(cls): + """As ef_initialise_properties, but also registers the + class with RNA. Note that this isn't a great idea + because it's non-trivial to unregister the class, unless + you keep track of it yourself. + """ + + bpy.utils.register_class(cls) + cls.initialise_properties() + return cls + + @classmethod + def remove_properties(cls): + """This is a function that should be called on + sub-classes of declarative_property_group in order + to ensure that they are un-initialised when the addon + is unloaded. + + """ + + if cls.ef_initialised: + prototype = getattr(bpy.types, cls.__name__) + for prop in cls.properties: + if hasattr(prototype, prop['attr']): + delattr(prototype, prop['attr']) + + for property_group_parent in cls.ef_attach_to: + if property_group_parent is not None: + prototype = getattr(bpy.types, property_group_parent) + if hasattr(prototype, cls.__name__): + delattr(prototype, cls.__name__) + + cls.ef_initialised = False + + return cls + + """This list controls the order of property layout when rendered by a property_group_renderer. This can be a nested list, where each list becomes a row in the panel layout. Nesting may be to any depth. @@ -266,3 +270,46 @@ class declarative_property_group(bpy.types.IDPropertyGroup): if 'save_in_preset' in prop.keys() and prop['save_in_preset']: out.append(prop) return out + +class Addon(object): + """A list of classes registered by this addon""" + addon_classes = [] + + def addon_register_class(self, cls): + """This method is designed to be used as a decorator on RNA-registerable + classes defined by the addon. By using this decorator, this class will + keep track of classes registered by this addon so that they can be + unregistered later in the correct order. + + """ + self.addon_classes.append(cls) + return cls + + def register(self): + """This is the register function that should be exposed in the addon's + __init__. + + """ + for cls in self.addon_classes: + bpy.utils.register_class(cls) + if hasattr(cls, 'ef_attach_to'): cls.initialise_properties() + + def unregister(self): + """This is the unregister function that should be exposed in the addon's + __init__. + + """ + for cls in self.addon_classes[::-1]: # unregister in reverse order + if hasattr(cls, 'ef_attach_to'): cls.remove_properties() + bpy.utils.unregister_class(cls) + + def init_functions(self): + """Returns references to the three functions that this addon needs + for successful class registration management. In the addon's __init__ + you would use like this: + + addon_register_class, register, unregister = Addon().init_functions() + + """ + + return self.addon_register_class, self.register, self.unregister diff --git a/modules/extensions_framework/engine.py b/modules/extensions_framework/engine.py deleted file mode 100644 index 0a6fecb034a77255694178c2e26d2dc861d9ec25..0000000000000000000000000000000000000000 --- a/modules/extensions_framework/engine.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf8 -*- -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# -------------------------------------------------------------------------- -# Blender 2.5 Extensions Framework -# -------------------------------------------------------------------------- -# -# Authors: -# Doug Hammond -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see <http://www.gnu.org/licenses/>. -# -# ***** END GPL LICENCE BLOCK ***** -# -from extensions_framework.plugin import plugin - -class engine_base(plugin): - """Render Engine plugin base class - - TODO: Remove, this class hasn't grown to be useful - - """ - - bl_label = 'Abstract Render Engine Base Class' - - def render(self, scene): - pass diff --git a/modules/extensions_framework/plugin.py b/modules/extensions_framework/plugin.py deleted file mode 100644 index b08efdd55f5eaa680f2269858eecc9a441b80535..0000000000000000000000000000000000000000 --- a/modules/extensions_framework/plugin.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf8 -*- -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# -------------------------------------------------------------------------- -# Blender 2.5 Extensions Framework -# -------------------------------------------------------------------------- -# -# Authors: -# Doug Hammond -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see <http://www.gnu.org/licenses/>. -# -# ***** END GPL LICENCE BLOCK ***** -# -import bpy - -from extensions_framework import init_properties -from extensions_framework import log - -class plugin(object): - """Base class for plugins which wish to make use of utilities - provided in extensions_framework. Using the property_groups - attribute and the install() and uninstall() methods, a large number - of custom scene properties can be easily defined, displayed and - managed. - - TODO: Rename, 'extension' would be more appropriate than 'plugin' - - """ - - @classmethod - def install(r_class): - """Initialise this plugin. So far, all this does is to create - custom property groups specified in the property_groups - attribute. - - """ - for property_group_parent, property_group in r_class.property_groups: - bpy.utils.register_class(property_group) - call_init = False - if property_group_parent is not None: - prototype = getattr(bpy.types, property_group_parent) - if not hasattr(prototype, property_group.__name__): - init_properties(prototype, [{ - 'type': 'pointer', - 'attr': property_group.__name__, - 'ptype': property_group, - 'name': property_group.__name__, - 'description': property_group.__name__ - }]) - call_init = True - else: - call_init = True - - if call_init: - init_properties(property_group, property_group.properties) - - log('Extension "%s" initialised' % r_class.__name__) - - @classmethod - def uninstall(r_class): - """TODO: make this work again""" - return - - """Unregister property groups in reverse order""" - reverse_property_groups = [p for p in r_class.property_groups] - reverse_property_groups.reverse() - for property_group_parent, property_group in reverse_property_groups: - if hasattr(bpy.types, property_group_parent): - prototype = getattr(bpy.types, property_group_parent) - prototype.RemoveProperty(property_group.__name__)