Files
blender/intern/python/modules/mcf/utils/hierobj.py
Michel Selten c95d631b83 Removed references to modules that do not exist. The python interface is
broken, but it should give 0 errors when building.

Michel
2003-01-06 17:27:43 +00:00

135 lines
4.1 KiB
Python

'''
Generic Hierarchic Objects Module
Hierobj's store their children (which can be anything) in their
__childlist__ attribute, and provide methods for walking the
hierarchy, either collecting results or not.
The index function returns an index of the objects (effectively a
flattened copy of the hierarchy)
97-03-17 Added ability to pass arguments to hier_rapply and hier_rreturn.
97-10-31 Removed dependencies on mcf.store
'''
#import copy,types
import types
import singletonlist, hier_rx
class Hierobj:
'''
An abstract class which handles hierarchic functions and information
# remade as a DAG 97-04-02, also reduced memory overhead for
hier-r* functions by using while-del-IndexError construct versus
for loop (probably makes it slower though)
If you require a true hierarchy, use the TrueHierobj class below...
'''
def __init__(self, parent=None, childlist=None):
if parent is None: # passed no parents
self.__dict__['__parent__'] = []
elif type(parent) == types.ListType: # passed a list of parents
self.__dict__['__parent__'] = parent
else: # passed a single parent
self.__dict__['__parent__'] = [parent]
self.__dict__['__childlist__'] = childlist or []
for child in self.__childlist__:
try:
child.__parent__.append(self)
except:
pass
# import simple hierarchic processing methods
hier_rapply = hier_rx.hier_rapply
hier_rreturn = hier_rx.hier_rreturn
hier_rgetattr = hier_rx.hier_rgetattr
hier_rmethod = hier_rx.hier_rmethod
def hier_addchild(self, child):
'''
Add a single child to the childlist
'''
self.__childlist__.append(child)
try:
# Hierobj-aware child
child.__parent__.append(self) # raises error if not hier_obj aware
except (TypeError, AttributeError):
# Non Hierobj-aware child
pass
append = hier_addchild
def hier_remchild(self, child):
'''
Breaks the child relationship with child, including the
reciprocal parent relationship
'''
try:
self.__childlist__.remove(child)
try:
child.hier_remparent(self) # if this fails, no problem
except AttributeError: pass
except (AttributeError,ValueError):
return 0 # didn't manage to remove the child
return 1 # succeeded
def hier_remparent(self, parent):
'''
Normally only called by hier_remchild of the parent,
just removes the parent from the child's parent list,
but leaves child in parent's childlist
'''
try:
self.__parent__.remove(parent)
except (AttributeError,ValueError):
return 0
return 1
def hier_replacewith(self,newel):
'''
As far as the hierarchy is concerned, the new element
is exactly the same as the old element, it has all
the same children, all the same parents. The old
element becomes completely disconnected from the hierarchy,
but it still retains all of its references
For every parent, replace this as a child
For every child, replace this as the parent
'''
for parent in self.__parent__:
try:
parent.hier_replacechild(self, newel)
except AttributeError:
pass
for child in self.__childlist__:
try:
child.hier_replaceparent(self,parent)
except AttributeError:
pass
def hier_replaceparent(self, oldparent, newparent):
ind = self.__parent__.index(oldparent)
self.__parent__[ind] = newparent
def hier_replacechild(self, oldchild, newchild):
ind = self.__childlist__.index(oldchild)
self.__childlist__[ind] = newchild
class TrueHierobj(Hierobj):
'''
An inefficient implementation of an Hierobj which limits the
__parent__ attribute to a single element. This will likely be
_slower_ than an equivalent Hierobj. That will have to be fixed
eventually.
'''
def __init__(self, parent=None, childlist=[]):
if parent is None: # passed no parents
self.__dict__['__parent__'] = singletonlist.SingletonList()
else: # passed a single parent
self.__dict__['__parent__'] = singletonlist.SingletonList(parent)
self.__dict__['__childlist__'] = copy.copy(childlist)
for child in self.__childlist__:
try:
child.__parent__.append(self)
except:
pass
def index(grove):
'''
Returns a flattened version of the grove
'''
return grove.hier_rreturn(lambda x: x)