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

panda/src/pgraph/nodePathComponent.cxx

Go to the documentation of this file.
00001 // Filename: nodePathComponent.cxx
00002 // Created by:  drose (25Feb02)
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 "nodePathComponent.h"
00020 
00021 
00022 // We start the key counters off at 1, since 0 is reserved for an
00023 // empty NodePath (and also for an unassigned key).
00024 int NodePathComponent::_next_key = 1;
00025 TypeHandle NodePathComponent::_type_handle;
00026 
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: NodePathComponent::CData::make_copy
00030 //       Access: Public, Virtual
00031 //  Description:
00032 ////////////////////////////////////////////////////////////////////
00033 CycleData *NodePathComponent::CData::
00034 make_copy() const {
00035   return new CData(*this);
00036 }
00037 
00038 ////////////////////////////////////////////////////////////////////
00039 //     Function: NodePathComponent::get_key
00040 //       Access: Public
00041 //  Description: Returns an index number that is guaranteed to be
00042 //               unique for this particular NodePathComponent, and not
00043 //               to be reused for the lifetime of the application
00044 //               (barring integer overflow).
00045 ////////////////////////////////////////////////////////////////////
00046 int NodePathComponent::
00047 get_key() const {
00048   if (is_collapsed()) {
00049     return get_collapsed()->get_key();
00050   }
00051   if (_key == 0) {
00052     // The first time someone asks for a particular component's key,
00053     // we make it up on the spot.  This helps keep us from wasting
00054     // index numbers generating a unique number for *every* component
00055     // in the world (we only have 4.2 billion 32-bit integers, after
00056     // all)
00057     ((NodePathComponent *)this)->_key = _next_key++;
00058   }
00059   return _key;
00060 }
00061 
00062 ////////////////////////////////////////////////////////////////////
00063 //     Function: NodePathComponent::is_top_node
00064 //       Access: Public
00065 //  Description: Returns true if this component represents the top
00066 //               node in the path.
00067 ////////////////////////////////////////////////////////////////////
00068 bool NodePathComponent::
00069 is_top_node() const {
00070   if (is_collapsed()) {
00071     return get_collapsed()->is_top_node();
00072   }
00073   CDReader cdata(_cycler);
00074   return (cdata->_next == (NodePathComponent *)NULL);
00075 }
00076 
00077 ////////////////////////////////////////////////////////////////////
00078 //     Function: NodePathComponent::get_length
00079 //       Access: Public
00080 //  Description: Returns the length of the path to this node.
00081 ////////////////////////////////////////////////////////////////////
00082 int NodePathComponent::
00083 get_length() const {
00084   if (is_collapsed()) {
00085     return get_collapsed()->get_length();
00086   }
00087   CDReader cdata(_cycler);
00088   return cdata->_length;
00089 }
00090 
00091 ////////////////////////////////////////////////////////////////////
00092 //     Function: NodePathComponent::get_next
00093 //       Access: Public
00094 //  Description: Returns the next component in the path.
00095 ////////////////////////////////////////////////////////////////////
00096 NodePathComponent *NodePathComponent::
00097 get_next() const {
00098   if (is_collapsed()) {
00099     return get_collapsed()->get_next();
00100   }
00101 
00102   CDReader cdata(_cycler);
00103   NodePathComponent *next = cdata->_next;
00104   
00105   // If the next component has been collapsed, transparently update
00106   // the pointer to get the actual node, and store the new pointer,
00107   // before we return.  Collapsing can happen at any time to any
00108   // component in the path and we have to deal with it.
00109   if (next != (NodePathComponent *)NULL && next->is_collapsed()) {
00110     next = next->uncollapse();
00111 
00112     CDWriter cdata_w(((NodePathComponent *)this)->_cycler, cdata);
00113     cdata_w->_next = next;
00114   }
00115   
00116   return next;
00117 }
00118 
00119 ////////////////////////////////////////////////////////////////////
00120 //     Function: NodePathComponent::fix_length
00121 //       Access: Public
00122 //  Description: Checks that the length indicated by the component is
00123 //               one more than the length of its predecessor.  If this
00124 //               is broken, fixes it and returns true indicating the
00125 //               component has been changed; otherwise, returns false.
00126 ////////////////////////////////////////////////////////////////////
00127 bool NodePathComponent::
00128 fix_length() {
00129   int length_should_be = 1;
00130   if (!is_top_node()) {
00131     length_should_be = get_next()->get_length() + 1;
00132   }
00133   if (get_length() == length_should_be) {
00134     return false;
00135   }
00136 
00137   CDWriter cdata(_cycler);
00138   cdata->_length = length_should_be;
00139   return true;
00140 }
00141 
00142 ////////////////////////////////////////////////////////////////////
00143 //     Function: NodePathComponent::uncollapse
00144 //       Access: Public
00145 //  Description: Returns this component pointer if the component is
00146 //               not collapsed; or if it has been collapsed, returns
00147 //               the pointer it has been collapsed into.
00148 //
00149 //               Collapsing can happen at any time to any component in
00150 //               the path and we have to deal with it.  It happens
00151 //               when a node is removed further up the path that
00152 //               results in two instances becoming the same thing.
00153 ////////////////////////////////////////////////////////////////////
00154 NodePathComponent *NodePathComponent::
00155 uncollapse() {
00156   NodePathComponent *comp = this;
00157 
00158   while (comp->is_collapsed()) {
00159     comp = comp->get_collapsed();
00160   }
00161 
00162   return comp;
00163 }
00164 
00165 ////////////////////////////////////////////////////////////////////
00166 //     Function: NodePathComponent::output
00167 //       Access: Public
00168 //  Description: The recursive implementation of NodePath::output(),
00169 //               this writes the names of each node component in order
00170 //               from beginning to end, by first walking to the end of
00171 //               the linked list and then outputting from there.
00172 ////////////////////////////////////////////////////////////////////
00173 void NodePathComponent::
00174 output(ostream &out) const {
00175   PandaNode *node = this->get_node();
00176   NodePathComponent *next = this->get_next();
00177   if (next != (NodePathComponent *)NULL) {
00178     // This is not the head of the list; keep going up.
00179     next->output(out);
00180     out << "/";
00181 
00182     PandaNode *parent_node = next->get_node();
00183     if (parent_node->find_stashed(node) >= 0) {
00184       // The node is stashed.
00185       out << "@@";
00186 
00187     } else if (node->find_parent(parent_node) < 0) {
00188       // Oops, there's an error.  This shouldn't happen.
00189       out << ".../";
00190     }
00191   }
00192 
00193   // Now output this component.
00194   if (node->has_name()) {
00195     out << node->get_name();
00196   } else {
00197     out << "-" << node->get_type();
00198   }
00199   //  out << "[" << this->get_length() << "]";
00200 }
00201 
00202 ////////////////////////////////////////////////////////////////////
00203 //     Function: NodePathComponent::set_next
00204 //       Access: Private
00205 //  Description: Sets the next pointer in the path.
00206 ////////////////////////////////////////////////////////////////////
00207 void NodePathComponent::
00208 set_next(NodePathComponent *next) {
00209   if (is_collapsed()) {
00210     get_collapsed()->set_next(next);
00211   } else {
00212     nassertv(next != (NodePathComponent *)NULL);
00213     CDWriter cdata(_cycler);
00214     cdata->_next = next;
00215   }
00216 }
00217 
00218 ////////////////////////////////////////////////////////////////////
00219 //     Function: NodePathComponent::set_top_node
00220 //       Access: Private
00221 //  Description: Severs any connection to the next pointer in the
00222 //               path and makes this component a top node.
00223 ////////////////////////////////////////////////////////////////////
00224 void NodePathComponent::
00225 set_top_node() {
00226   if (is_collapsed()) {
00227     get_collapsed()->set_top_node();
00228   } else {
00229     CDWriter cdata(_cycler);
00230     cdata->_next = (NodePathComponent *)NULL;
00231   }
00232 }
00233 
00234 ////////////////////////////////////////////////////////////////////
00235 //     Function: NodePathComponent::collapse_with
00236 //       Access: Private
00237 //  Description: Indicates that this component pointer is no longer
00238 //               valid, and that the indicated component should be
00239 //               used instead.  This is done whenever two
00240 //               NodePathComponents have been collapsed together due
00241 //               to an instance being removed higher up in the graph.
00242 ////////////////////////////////////////////////////////////////////
00243 void NodePathComponent::
00244 collapse_with(NodePathComponent *next) {
00245   nassertv(!is_collapsed());
00246   nassertv(next != (NodePathComponent *)NULL);
00247   CDWriter cdata(_cycler);
00248 
00249   // We indicate a component has been collapsed by setting its length
00250   // to zero.
00251   cdata->_next = next;
00252   cdata->_length = 0;
00253 
00254   if (_key != 0 && next->_key == 0) {
00255     // If we had a key set and the other one didn't, it inherits our
00256     // key.  Otherwise, we inherit the other's key.
00257     next->_key = _key;
00258   }
00259 }

Generated on Fri May 2 00:41:59 2003 for Panda by doxygen1.3