Panda3D
 All Classes Functions Variables Enumerations
nodePathComponent.cxx
00001 // Filename: nodePathComponent.cxx
00002 // Created by:  drose (25Feb02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "nodePathComponent.h"
00016 #include "lightMutexHolder.h"
00017 
00018 // We start the key counters off at 1, since 0 is reserved for an
00019 // empty NodePath (and also for an unassigned key).
00020 int NodePathComponent::_next_key = 1;
00021 LightMutex NodePathComponent::_key_lock("NodePathComponent::_key_lock");
00022 TypeHandle NodePathComponent::_type_handle;
00023 TypeHandle NodePathComponent::CData::_type_handle;
00024 
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: NodePathComponent::CData::make_copy
00028 //       Access: Public, Virtual
00029 //  Description:
00030 ////////////////////////////////////////////////////////////////////
00031 CycleData *NodePathComponent::CData::
00032 make_copy() const {
00033   return new CData(*this);
00034 }
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //     Function: NodePathComponent::Constructor
00038 //       Access: Private
00039 //  Description: Constructs a new NodePathComponent from the
00040 //               indicated node.  Don't try to call this directly; ask
00041 //               the PandaNode to do it for you.
00042 ////////////////////////////////////////////////////////////////////
00043 NodePathComponent::
00044 NodePathComponent(PandaNode *node, NodePathComponent *next,
00045                   int pipeline_stage, Thread *current_thread) :
00046   _node(node),
00047   _key(0)
00048 {
00049 #ifdef DO_MEMORY_USAGE
00050   MemoryUsage::update_type(this, get_class_type());
00051 #endif
00052 
00053   for (int pipeline_stage_i = pipeline_stage;
00054        pipeline_stage_i >= 0; 
00055        --pipeline_stage_i) {
00056     CDStageWriter cdata(_cycler, pipeline_stage_i, current_thread);
00057     cdata->_next = next;
00058     
00059     if (next != (NodePathComponent *)NULL) {
00060       cdata->_length = next->get_length(pipeline_stage_i, current_thread) + 1;
00061     }
00062   }
00063 }
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //     Function: NodePathComponent::get_key
00067 //       Access: Public
00068 //  Description: Returns an index number that is guaranteed to be
00069 //               unique for this particular NodePathComponent, and not
00070 //               to be reused for the lifetime of the application
00071 //               (barring integer overflow).
00072 ////////////////////////////////////////////////////////////////////
00073 int NodePathComponent::
00074 get_key() const {
00075   LightMutexHolder holder(_key_lock);
00076   if (_key == 0) {
00077     // The first time someone asks for a particular component's key,
00078     // we make it up on the spot.  This helps keep us from wasting
00079     // index numbers generating a unique number for *every* component
00080     // in the world (we only have 4.2 billion 32-bit integers, after
00081     // all)
00082     ((NodePathComponent *)this)->_key = _next_key++;
00083   }
00084   return _key;
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////
00088 //     Function: NodePathComponent::is_top_node
00089 //       Access: Public
00090 //  Description: Returns true if this component represents the top
00091 //               node in the path.
00092 ////////////////////////////////////////////////////////////////////
00093 bool NodePathComponent::
00094 is_top_node(int pipeline_stage, Thread *current_thread) const {
00095   CDStageReader cdata(_cycler, pipeline_stage, current_thread);
00096   return (cdata->_next == (NodePathComponent *)NULL);
00097 }
00098 
00099 ////////////////////////////////////////////////////////////////////
00100 //     Function: NodePathComponent::get_length
00101 //       Access: Public
00102 //  Description: Returns the length of the path to this node.
00103 ////////////////////////////////////////////////////////////////////
00104 int NodePathComponent::
00105 get_length(int pipeline_stage, Thread *current_thread) const {
00106   CDStageReader cdata(_cycler, pipeline_stage, current_thread);
00107   return cdata->_length;
00108 }
00109 
00110 ////////////////////////////////////////////////////////////////////
00111 //     Function: NodePathComponent::get_next
00112 //       Access: Public
00113 //  Description: Returns the next component in the path.
00114 ////////////////////////////////////////////////////////////////////
00115 NodePathComponent *NodePathComponent::
00116 get_next(int pipeline_stage, Thread *current_thread) const {
00117   CDStageReader cdata(_cycler, pipeline_stage, current_thread);
00118   NodePathComponent *next = cdata->_next;
00119   
00120   return next;
00121 }
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //     Function: NodePathComponent::fix_length
00125 //       Access: Public
00126 //  Description: Checks that the length indicated by the component is
00127 //               one more than the length of its predecessor.  If this
00128 //               is broken, fixes it and returns true indicating the
00129 //               component has been changed; otherwise, returns false.
00130 ////////////////////////////////////////////////////////////////////
00131 bool NodePathComponent::
00132 fix_length(int pipeline_stage, Thread *current_thread) {
00133   CDLockedStageReader cdata(_cycler, pipeline_stage, current_thread);
00134 
00135   int length_should_be = 1;
00136   if (cdata->_next != (NodePathComponent *)NULL) {
00137     length_should_be = cdata->_next->get_length(pipeline_stage, current_thread) + 1;
00138   }
00139 
00140   if (cdata->_length == length_should_be) {
00141     return false;
00142   }
00143 
00144   CDStageWriter cdataw(_cycler, pipeline_stage, cdata);
00145   cdataw->_length = length_should_be;
00146   return true;
00147 }
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 //     Function: NodePathComponent::output
00151 //       Access: Public
00152 //  Description: The recursive implementation of NodePath::output(),
00153 //               this writes the names of each node component in order
00154 //               from beginning to end, by first walking to the end of
00155 //               the linked list and then outputting from there.
00156 ////////////////////////////////////////////////////////////////////
00157 void NodePathComponent::
00158 output(ostream &out) const {
00159   Thread *current_thread = Thread::get_current_thread();
00160   int pipeline_stage = current_thread->get_pipeline_stage();
00161 
00162   PandaNode *node = get_node();
00163   NodePathComponent *next = get_next(pipeline_stage, current_thread);
00164   if (next != (NodePathComponent *)NULL) {
00165     // This is not the head of the list; keep going up.
00166     next->output(out);
00167     out << "/";
00168 
00169     PandaNode *parent_node = next->get_node();
00170     if (parent_node->find_stashed(node) >= 0) {
00171       // The node is stashed.
00172       out << "@@";
00173 
00174     } else if (node->find_parent(parent_node) < 0) {
00175       // Oops, there's an error.  This shouldn't happen.
00176       out << ".../";
00177     }
00178   }
00179 
00180   // Now output this component.
00181   if (node->has_name()) {
00182     out << node->get_name();
00183   } else {
00184     out << "-" << node->get_type();
00185   }
00186   //  out << "[" << this->get_length() << "]";
00187 }
00188 
00189 ////////////////////////////////////////////////////////////////////
00190 //     Function: NodePathComponent::set_next
00191 //       Access: Private
00192 //  Description: Sets the next pointer in the path.
00193 ////////////////////////////////////////////////////////////////////
00194 void NodePathComponent::
00195 set_next(NodePathComponent *next, int pipeline_stage, Thread *current_thread) {
00196   nassertv(next != (NodePathComponent *)NULL);
00197   CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
00198   cdata->_next = next;
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: NodePathComponent::set_top_node
00203 //       Access: Private
00204 //  Description: Severs any connection to the next pointer in the
00205 //               path and makes this component a top node.
00206 ////////////////////////////////////////////////////////////////////
00207 void NodePathComponent::
00208 set_top_node(int pipeline_stage, Thread *current_thread) {
00209   CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
00210   cdata->_next = (NodePathComponent *)NULL;
00211 }
 All Classes Functions Variables Enumerations