Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/express/typeRegistryNode.cxx

Go to the documentation of this file.
00001 // Filename: typeRegistryNode.cxx
00002 // Created by:  drose (06Aug01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "typeRegistryNode.h"
00020 
00021 #include <algorithm>
00022 
00023 bool TypeRegistryNode::_paranoid_inheritance;
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: TypeRegistryNode::Constructor
00027 //       Access: Public
00028 //  Description:
00029 ////////////////////////////////////////////////////////////////////
00030 TypeRegistryNode::
00031 TypeRegistryNode(TypeHandle handle, const string &name, TypeHandle &ref) :
00032   _handle(handle), _name(name), _ref(ref) 
00033 {
00034   clear_subtree();
00035 }
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: TypeRegistryNode::is_derived_from
00039 //       Access: Public, Static
00040 //  Description: Returns true if the child RegistryNode represents a
00041 //               class that inherits directly or indirectly from the
00042 //               class represented by the base RegistryNode.
00043 ////////////////////////////////////////////////////////////////////
00044 bool TypeRegistryNode::
00045 is_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base) {
00046   // This function is the basis for TypedObject::is_of_type(), which
00047   // gets used quite frequently within Panda, often in inner-loop
00048   // code.  Therefore, we go through some pains to make this function
00049   // as efficient as possible.
00050 
00051   // (Actually, it appears that the function is not called as often as
00052   // I'd first thought, and it wasn't really all that expensive to
00053   // begin with.  So much of this complexity is of limited usefulness.
00054   // Oh well.)
00055 
00056   // First, compare the subtree tops.  If they are the same, then this
00057   // node and the base node are within the same single-inheritance
00058   // subtree, and we can use our bitmask trick to determine the
00059   // relationship with no additional work.  (See r_build_subtrees()).
00060 
00061   if (child->_inherit._top == base->_inherit._top) {
00062     nassertr(child->_inherit._top != (TypeRegistryNode *)NULL, false);
00063 
00064     bool derives = 
00065       Inherit::is_derived_from(child->_inherit, base->_inherit);
00066 
00067 #ifndef NDEBUG
00068     if (_paranoid_inheritance) {
00069       bool paranoid_derives = check_derived_from(child, base);
00070       if (derives != paranoid_derives) {
00071         express_cat.error()
00072           << "Inheritance test for " << child->_name 
00073           << " from " << base->_name << " failed!\n"
00074           << "Result: " << derives << " should have been: "
00075           << paranoid_derives << "\n"
00076           << "Classes are in the same single inheritance subtree, children of "
00077           << child->_inherit._top->_name << "\n"
00078           << hex
00079           << child->_name << " has mask " << child->_inherit._mask
00080           << " and bits " << child->_inherit._bits << "\n"
00081           << base->_name << " has mask " << base->_inherit._mask
00082         << " and bits " << base->_inherit._bits << "\n"
00083           << dec;
00084         return paranoid_derives;
00085       }
00086     }
00087 #endif
00088 
00089     /*
00090     cerr << "trivial: " << child->_name << " vs. " << base->_name
00091          << " (" << child->_inherit._top->_name << ") = " << derives << "\n";
00092     */
00093 
00094     return derives;
00095   }
00096 
00097   // The two nodes are not within the same single-inheritance subtree.
00098   // This complicates things a bit.
00099 
00100   // First, we should check whether the subtree tops of the two nodes
00101   // inherit from each other.
00102   TypeRegistryNode *child_top = child->_inherit._top;
00103   TypeRegistryNode *base_top = base->_inherit._top;
00104 
00105   bool derives = false;
00106 
00107   // If child_top does not inherit from base_top, it follows that
00108   // child does not inherit from base.
00109   TopInheritance::const_iterator ti = 
00110     lower_bound(child_top->_top_inheritance.begin(), 
00111                 child_top->_top_inheritance.end(),
00112                 Inherit(base_top, 0, 0));
00113 
00114   while (ti != child_top->_top_inheritance.end() && 
00115          (*ti)._top == base_top &&
00116          !derives) {
00117     // If child_top *does* inherit from base_top, then child may or
00118     // may not inherit from base.  This depends on the exact path of
00119     // inheritance.  Since there might be multiple paths from
00120     // child_top to base_top, we have to examine all of them.
00121     const Inherit &connection = (*ti);
00122 
00123     // Here is one inheritance from child_top to base_top.  If the
00124     // connecting node inherits from base, then child also inherits
00125     // from base.  If the connecting node does not inherit from base,
00126     // we must keep looking.
00127     derives = Inherit::is_derived_from(connection, base->_inherit);
00128 
00129     ++ti;
00130   }
00131 
00132 #ifndef NDEBUG
00133   if (_paranoid_inheritance) {
00134     bool paranoid_derives = check_derived_from(child, base);
00135     if (derives != paranoid_derives) {
00136       express_cat.error()
00137         << "Inheritance test for " << child->_name 
00138         << " from " << base->_name << " failed!\n"
00139         << "Result: " << derives << " should have been: "
00140         << paranoid_derives << "\n"
00141         << child->_name << " is a descendent of "
00142         << child_top->_name << "\n"
00143         << base->_name << " is a descendent of "
00144       << base_top->_name << "\n";
00145       return paranoid_derives;
00146     }
00147   }
00148 #endif
00149 
00150   /*
00151   cerr << "complex: " << child->_name << " (" << child->_inherit._top->_name
00152        << ") vs. " << base->_name << " (" << base->_inherit._top->_name
00153        << ") = " << derives << "\n";
00154   */
00155   return derives;
00156 }
00157 
00158 ////////////////////////////////////////////////////////////////////
00159 //     Function: TypeRegistryNode::get_parent_towards
00160 //       Access: Public, Static
00161 //  Description: Returns the first parent class of child that is a
00162 //               descendant of the indicated base class.
00163 ////////////////////////////////////////////////////////////////////
00164 TypeHandle TypeRegistryNode::
00165 get_parent_towards(const TypeRegistryNode *child,
00166                    const TypeRegistryNode *base) {
00167   if (child == base) {
00168     return child->_handle;
00169   }
00170 
00171   Classes::const_iterator ni;
00172   for (ni = child->_parent_classes.begin(); 
00173        ni != child->_parent_classes.end(); ++ni) {
00174     if (is_derived_from((*ni), base)) {
00175       return (*ni)->_handle;
00176     }
00177   }
00178 
00179   return TypeHandle::none();
00180 }
00181 
00182 
00183 ////////////////////////////////////////////////////////////////////
00184 //     Function: TypeRegistryNode::clear_subtree
00185 //       Access: Public
00186 //  Description: Removes any subtree definition previously set up via
00187 //               define_subtree(), in preparation for rebuilding the
00188 //               subtree data.
00189 ////////////////////////////////////////////////////////////////////
00190 void TypeRegistryNode::
00191 clear_subtree() {
00192   _inherit = Inherit();
00193   _top_inheritance.clear();
00194   _visit_count = 0;
00195 }
00196 
00197 ////////////////////////////////////////////////////////////////////
00198 //     Function: TypeRegistryNode::define_subtree
00199 //       Access: Public
00200 //  Description: Indicates that this TypeRegistryNode is the top of a
00201 //               subtree within the inheritance graph (typically, this
00202 //               indicates a multiple-inheritance node).  Builds all
00203 //               the subtree_mask etc. flags for nodes at this level
00204 //               and below.
00205 ////////////////////////////////////////////////////////////////////
00206 void TypeRegistryNode::
00207 define_subtree() {
00208   //  cerr << "Building subtree for " << _name << ", top inheritance is:\n";
00209 
00210     /*
00211   TopInheritance::const_iterator ti;
00212   for (ti = _top_inheritance.begin(); ti != _top_inheritance.end(); ++ti) {
00213     const Inherit &t = (*ti);
00214     cerr << "  from " << t._top->_name << " via "
00215          << hex << t._bits << " / " << t._mask << dec << "\n";
00216   }
00217     */
00218 
00219   r_build_subtrees(this, 0, 0);
00220 }
00221 
00222 ////////////////////////////////////////////////////////////////////
00223 //     Function: TypeRegistryNode::r_build_subtrees
00224 //       Access: Public
00225 //  Description: Recursively builds up all the subtree cache
00226 //               information for this node and the ones below.  This
00227 //               information is used to quickly determine class
00228 //               inheritance.
00229 ////////////////////////////////////////////////////////////////////
00230 void TypeRegistryNode::
00231 r_build_subtrees(TypeRegistryNode *top, int bit_count, 
00232                  TypeRegistryNode::SubtreeMaskType bits) {
00233   // The idea with these bits is to optimize the common case of a
00234   // single-inheritance graph (that is, an inheritance tree), or a
00235   // single-inheritance subgraph of the full multiple-inheritance
00236   // graph (i.e. a subtree of the inheritance graph).
00237 
00238   // When we have just single inheritance, we can define a unique
00239   // number for each node in the inheritance tree that allows us to
00240   // immediately determine the inheritance relationship between any
00241   // two nodes in the tree.  We choose a number such that for a given
00242   // node whose number has n bits, each child node has m + n bits
00243   // where the low-order n bits are the same as the parent node's
00244   // bits, and the high-order m bits are unique among each sibling.
00245   // The node at the top of the tree has zero bits.
00246 
00247   // That way, we can simply compare bitmasks to determine if class A
00248   // inherits from class B.  If the low-order bits are the same, they
00249   // have some ancestry in common.  The highest-order bit that still
00250   // matches corresponds to the lowest node in the tree that they have
00251   // in common; i.e. the node from which they both inherit.
00252 
00253   // To put it more formally, let count(A) be the number of bits in
00254   // A's number, and count(B) be the number of bits in B's number.  A
00255   // inherits from B if and only if count(B) <= count(A), and the
00256   // lower count(B) bits of A's number are the same as those in B's
00257   // number.
00258 
00259   // This algorithm breaks down in the presence of multiple
00260   // inheritance, since we can't make up a single number for each node
00261   // any more.  We still take advantage of the algorithm by
00262   // considering each single-inheritance subgraph separately.
00263 
00264   // To handle multiple inheritance, we reset the numbers to zero
00265   // every time we come across a multiple-inheritance node (this
00266   // begins a new subtree).  There are relatively few of these
00267   // "subtree top" nodes, and we record the explicit inheritance of
00268   // each one from all of its ancestor "subtree top" nodes within the
00269   // node itself.
00270 
00271   if (top != this && _parent_classes.size() != 1) {
00272     nassertv(!_parent_classes.empty());
00273   
00274     // This class multiply inherits; it therefore begins a new subtree.
00275 
00276     // Copy in the inheritance relations from our parent subtree tops.
00277     _top_inheritance.insert(_top_inheritance.end(),
00278                             top->_top_inheritance.begin(), 
00279                             top->_top_inheritance.end());
00280     _top_inheritance.push_back(Inherit(top, bit_count, bits));
00281 
00282     _visit_count++;
00283     if (_visit_count == (int)_parent_classes.size()) {
00284       // This is the last time we'll visit this node, so continue the
00285       // recursion now.
00286       nassertv(_inherit._top == (TypeRegistryNode *)NULL);
00287       sort(_top_inheritance.begin(), _top_inheritance.end());
00288       define_subtree();
00289     }
00290 
00291   } else {
00292     // This class singly inherits, so this had better be the only time
00293     // this function is called on it since clear_subtree().
00294     nassertv(_inherit._top == (TypeRegistryNode *)NULL);
00295 
00296     nassertv(bit_count < (int)(sizeof(SubtreeMaskType) * 8));
00297 
00298     _inherit = Inherit(top, bit_count, bits);
00299 
00300     // Now, how many more bits do we need to encode each of our
00301     // children?
00302     int num_children = _child_classes.size();
00303     int more_bits = 0;
00304     int i = num_children - 1;
00305     while (i > 0) {
00306       more_bits++;
00307       i >>= 1;
00308     }
00309 
00310     // We need at least one bit, even if there is only one child, so
00311     // we can differentiate parent from child.
00312     more_bits = max(more_bits, 1);
00313 
00314     nassertv(more_bits < (int)(sizeof(SubtreeMaskType) * 8));
00315 
00316     if (bit_count + more_bits > (int)(sizeof(SubtreeMaskType) * 8)) {
00317       // Too many bits; we need to start a new subtree right here.
00318       // This node becomes a subtree top node, even though it's not a
00319       // multiple-inheritance node.
00320       nassertv(top != this);
00321       _top_inheritance = top->_top_inheritance;
00322       _top_inheritance.push_back(_inherit);
00323       sort(_top_inheritance.begin(), _top_inheritance.end());
00324       _inherit = Inherit();
00325       define_subtree();
00326 
00327     } else {
00328       // Still plenty of bits, so keep going.
00329       for (i = 0; i < num_children; i++) {
00330         TypeRegistryNode *child = _child_classes[i];
00331         SubtreeMaskType next_bits = ((SubtreeMaskType)i << bit_count);
00332 
00333         child->r_build_subtrees(top, bit_count + more_bits,
00334                                 bits | next_bits);
00335       }
00336     }      
00337   }
00338 }
00339  
00340 ////////////////////////////////////////////////////////////////////
00341 //     Function: TypeRegistryNode::check_derived_from
00342 //       Access: Private, Static
00343 //  Description: A recursive function to double-check the result of
00344 //               is_derived_from().  This is the slow,
00345 //               examine-the-whole-graph approach, as opposed to the
00346 //               clever and optimal algorithm of is_derived_from();
00347 //               it's intended to be used only for debugging said
00348 //               clever algorithm.
00349 ////////////////////////////////////////////////////////////////////
00350 bool TypeRegistryNode::
00351 check_derived_from(const TypeRegistryNode *child, 
00352                    const TypeRegistryNode *base) {
00353   if (child == base) {
00354     return true;
00355   }
00356 
00357   Classes::const_iterator ni;
00358   for (ni = child->_parent_classes.begin(); 
00359        ni != child->_parent_classes.end();
00360        ++ni) {
00361     if (check_derived_from(*ni, base)) {
00362       return true;
00363     }
00364   }
00365 
00366   return false;
00367 }

Generated on Fri May 2 00:38:44 2003 for Panda by doxygen1.3