OpenGLContext.visitor
index
p:\openglcontext\visitor.py

Traversal objects for Contexts and scenegraphs

 
Modules
            
vrml.node
OpenGLContext.scenegraph.nodepath
vrml.vrml97.nodetypes
sys
traceback
types
 
Classes
            
object
Visitor
_Finder
 
class Visitor(object)
      Extremely basic visitor/traversal object for scenegraphs
 
The "visitor" does not actually follow the classic visitor
pattern (where the nodes dispatch the visitor to their
children).  Instead, it is a traversal mechanism that has
four major points of customisation:
 
        vmethods -- virtual methods which are applied to a node
                during traversal.  Each applicable vmethod (is
                registered as a method for one of the node's
                parent classes) is applied _in turn_, so it is
                possible to have large numbers of vmethods called
                for any given node.  Return values are callable
                tokens which perform any state-resetting required
 
                See: buildVMethods
                
        childrenMethods -- virtual methods registered for a given
                class which are used to determine the children of the
                class.  Only the _first_ encountered method is used,
                with the search order being the class's __mro__.
 
                See: addChildrenMethod
                
        preVisit -- called for _every_ node before visiting, if it
                returns a false value, then the node's vmethods
                and children are _not_ processed.
                
        postVisit -- called for _every_ node where preVisit
                returned a true value as the last customisation point
                before the visitor finished processing the node.
 
Note: For the purposes of the visitor, a Context is just a
node like any other.  There is some special code in the
registered childrenMethod for the Context which handles
determining whether the Render method or a scenegraph should
be the children of the Context.
 
There is a log associated with the visitors which will log the
particular nodes, their vmethods, and any finalisation tokens
being run.  By default this log is set to WARN level.  You can
set it to INFO to see the verbose trace (warning, this will
seriously slow down your rendering on many systems!)  The
logging calls are eliminated (regardless of the logging setting)
under a python -O or python -OO run.
 
   Methods defined here:
__init__(self)
Initialise the visitor object
 
calls buildVMethods() then builds the current
stack.
 
Attributes:
        currentStack -- nodepath describing the current
                processing stack for this visitor
 
        _childrenMethods -- mapping from class/superclass
                to methods for retrieving the set of children
                for that class, see the "children" method,
                (single match)
        _vmethods -- mapping from class/superclass to
                methods to be applied on entry to any instance
                of the class, see the vmethods method,
                (multiple match)
buildVMethods(self)
Customization point: Create application-specific type:method-name mapping
 
Basically this lets you call a named method for each
class/base-class in a node's __mro__.  Override this (calling
the base implementation and modifying the resulting dictionary)
to register your particular virtual methods.
 
Format is:
        class-pointer: string-method-name
 
The dictionary is stored as self._vmethods
children(self, node, types=(<class 'vrml.vrml97.nodetypes.Traversable'>, <class 'vrml.vrml97.nodetypes.Children'>, <class 'vrml.node.PrototypedNode'>, <class 'vrml.vrml97.nodetypes.Rendering'>))
Get children to visit for a node
 
Determine the set of children to be visited for
a given node in the node graph.  See the
childrenMethod method for details.  If no
childrenMethod is reported, an empty tuple
is reported.
visit(self, node)
Visit an individual node, dispatch to methods as necessary
 
The visiting algorithm is fairly involved compared
to the classic computer science Visitor algorithm.
 
First we call preVisit( node ), and if the
result of that is true, we continue processing.
This allows you to use preVisit to do such things
as processing every node in the scenegraph.
 
If we are visiting the node: (preVisit returned true)
 
        * add the node to self.currentStack
        * retrieve the "vmethods" for the node
        * call each vmethod with the node as argument
                o if the vmethod returns a finalization token
                        we store that token for finalization
        * we determine the children to visit for the node
        * for each child, we call visit recursively
        * during finalization (after children are finished
                processing)
                o if we have any finalization tokens, we call
                        those tokens
                o we call postVisit( node )
                o we restore the previous self.currentStack
                
Note: this is the "production" version of visit
which only logs errors, not "info" level traces,
this avoids the 100's of 1000's of calls generated
by the huge number of iterations.
vmethods(self, obj)
Get all relevant "virtual methods" as unbound methods
 
Returns *all* registered vmethods for the classes in the
given object's class's __mro__
 
This version caches the unbound methods in a per-visitor-
class dictionary, which should make it at least a little
faster.

Class methods defined here:
addChildrenMethod(self, type, function) from type
Register function for determining children for a given type
 
XXX
        Methods are stored in the _childrenMethods dictionary,
        which is currently class-static, I would rather this
        were an instance variable, but that makes registration
        something you need to do for every new instance, while
        normally you only want to override for very special
        sub-classes (I haven't yet discovered a case where I
        want to do it).
 
Note:
        This is currently a class method due to the class-
        static nature!

Data and non-method functions defined here:
__dict__ = <dict-proxy object at 0x0736AB58>
__doc__ = 'Extremely basic visitor/traversal object for sce... setting)\n\tunder a python -O or python -OO run.\n\t'
__module__ = 'OpenGLContext.visitor'
__weakref__ = <member '__weakref__' of 'Visitor' objects>
_childrenMethods = {}

Methods inherited from object:
__delattr__(...)
x.__delattr__('name') <==> del x.name
__getattribute__(...)
x.__getattribute__('name') <==> x.name
__hash__(...)
x.__hash__() <==> hash(x)
__reduce__(...)
helper for pickle
__repr__(...)
x.__repr__() <==> repr(x)
__setattr__(...)
x.__setattr__('name', value) <==> x.name = value
__str__(...)
x.__str__() <==> str(x)

Data and non-method functions inherited from object:
__class__ = <type 'type'>
__new__ = <built-in method __new__ of type object at 0x1E0BD978>
T.__new__(S, ...) -> a new object with type S, a subtype of T
 
class _Finder(Visitor)
      Traverse a scenegraph looking for bindable nodes
 
This is a simple implementation of a scenegraph-search
which looks for all nodes which are instances of any of
a given set of classes/types.
 
Attributes:
        result -- the resulting set of node-paths
        desiredTypes -- the node-types being searched for
 
See the find function for the normal usage API
 
  
Method resolution order:
_Finder
Visitor
object

Methods defined here:
__init__(self, desiredTypes=())
Initialize the _Finder object
 
desiredTypes -- sequence of types to be searched for
visit(self, node)
Visit an individual node, search for self.desiredTypes
 
This is a heavily trimmed version of the superclass method

Data and non-method functions defined here:
__doc__ = 'Traverse a scenegraph looking for bindable nodes...\tSee the find function for the normal usage API\n\t'
__module__ = 'OpenGLContext.visitor'

Methods inherited from Visitor:
buildVMethods(self)
Customization point: Create application-specific type:method-name mapping
 
Basically this lets you call a named method for each
class/base-class in a node's __mro__.  Override this (calling
the base implementation and modifying the resulting dictionary)
to register your particular virtual methods.
 
Format is:
        class-pointer: string-method-name
 
The dictionary is stored as self._vmethods
children(self, node, types=(<class 'vrml.vrml97.nodetypes.Traversable'>, <class 'vrml.vrml97.nodetypes.Children'>, <class 'vrml.node.PrototypedNode'>, <class 'vrml.vrml97.nodetypes.Rendering'>))
Get children to visit for a node
 
Determine the set of children to be visited for
a given node in the node graph.  See the
childrenMethod method for details.  If no
childrenMethod is reported, an empty tuple
is reported.
vmethods(self, obj)
Get all relevant "virtual methods" as unbound methods
 
Returns *all* registered vmethods for the classes in the
given object's class's __mro__
 
This version caches the unbound methods in a per-visitor-
class dictionary, which should make it at least a little
faster.

Class methods inherited from Visitor:
addChildrenMethod(self, type, function) from type
Register function for determining children for a given type
 
XXX
        Methods are stored in the _childrenMethods dictionary,
        which is currently class-static, I would rather this
        were an instance variable, but that makes registration
        something you need to do for every new instance, while
        normally you only want to override for very special
        sub-classes (I haven't yet discovered a case where I
        want to do it).
 
Note:
        This is currently a class method due to the class-
        static nature!

Data and non-method functions inherited from Visitor:
__dict__ = <dict-proxy object at 0x072DC768>
__weakref__ = <member '__weakref__' of 'Visitor' objects>
_childrenMethods = {}

Methods inherited from object:
__delattr__(...)
x.__delattr__('name') <==> del x.name
__getattribute__(...)
x.__getattribute__('name') <==> x.name
__hash__(...)
x.__hash__() <==> hash(x)
__reduce__(...)
helper for pickle
__repr__(...)
x.__repr__() <==> repr(x)
__setattr__(...)
x.__setattr__('name', value) <==> x.name = value
__str__(...)
x.__str__() <==> str(x)

Data and non-method functions inherited from object:
__class__ = <type 'type'>
__new__ = <built-in method __new__ of type object at 0x1E0BD978>
T.__new__(S, ...) -> a new object with type S, a subtype of T
 
Functions
            
find(sg, desiredTypes=())
Get list of node-paths to instances of desiredTypes
 
desiredTypes -- sequence of desired base types
 
returns node-paths for each node in the scenegraph
of the given types
 
Note:
        The traversal is the same as that used by the
        rendering procedure, so is quite possible for
        non-rendering nodes to be missed by the search.
parents(c, seen=None)
Python class base-finder
 
Data
             DEBUG = 10
DEBUG_VISIT_METHOD = 0
INFO = 20
TRAVERSAL_TYPES = (<class 'vrml.vrml97.nodetypes.Traversable'>, <class 'vrml.vrml97.nodetypes.Children'>, <class 'vrml.node.PrototypedNode'>, <class 'vrml.vrml97.nodetypes.Rendering'>)
visitor_log = <logging.Logger instance at 0x056F3980>