Skip to content
Snippets Groups Projects
Commit 1468e5c8 authored by Doug Hammond's avatar Doug Hammond
Browse files

extensions_framework: Removed old and empty classes, added a more useful Addon...

extensions_framework: Removed old and empty classes, added a more useful Addon class for register/unregister management
parent b43dfa99
No related branches found
No related tags found
No related merge requests found
...@@ -115,71 +115,6 @@ def init_properties(obj, props, cache=True): ...@@ -115,71 +115,6 @@ def init_properties(obj, props, cache=True):
# Silently skip invalid entries in props # Silently skip invalid entries in props
continue 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): class declarative_property_group(bpy.types.IDPropertyGroup):
"""A declarative_property_group describes a set of logically """A declarative_property_group describes a set of logically
related properties, using a declarative style to list each related properties, using a declarative style to list each
...@@ -210,6 +145,75 @@ class declarative_property_group(bpy.types.IDPropertyGroup): ...@@ -210,6 +145,75 @@ class declarative_property_group(bpy.types.IDPropertyGroup):
""" """
ef_attach_to = [] 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 """This list controls the order of property layout when rendered
by a property_group_renderer. This can be a nested list, where each 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. 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): ...@@ -266,3 +270,46 @@ class declarative_property_group(bpy.types.IDPropertyGroup):
if 'save_in_preset' in prop.keys() and prop['save_in_preset']: if 'save_in_preset' in prop.keys() and prop['save_in_preset']:
out.append(prop) out.append(prop)
return out 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
# -*- 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
# -*- 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__)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment