Panda3D
|
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 }