00001 // Filename: internalName.cxx 00002 // Created by: masad (15Jul04) 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 "pandabase.h" 00016 #include "internalName.h" 00017 #include "datagram.h" 00018 #include "datagramIterator.h" 00019 #include "bamReader.h" 00020 #include "preparedGraphicsObjects.h" 00021 00022 PT(InternalName) InternalName::_root; 00023 PT(InternalName) InternalName::_error; 00024 PT(InternalName) InternalName::_default; 00025 PT(InternalName) InternalName::_vertex; 00026 PT(InternalName) InternalName::_normal; 00027 PT(InternalName) InternalName::_tangent; 00028 PT(InternalName) InternalName::_binormal; 00029 PT(InternalName) InternalName::_texcoord; 00030 PT(InternalName) InternalName::_color; 00031 PT(InternalName) InternalName::_rotate; 00032 PT(InternalName) InternalName::_size; 00033 PT(InternalName) InternalName::_aspect_ratio; 00034 PT(InternalName) InternalName::_transform_blend; 00035 PT(InternalName) InternalName::_transform_weight; 00036 PT(InternalName) InternalName::_transform_index; 00037 PT(InternalName) InternalName::_index; 00038 PT(InternalName) InternalName::_world; 00039 PT(InternalName) InternalName::_camera; 00040 PT(InternalName) InternalName::_model; 00041 PT(InternalName) InternalName::_view; 00042 00043 TypeHandle InternalName::_type_handle; 00044 TypeHandle InternalName::_texcoord_type_handle; 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Function: InternalName::Constructor 00048 // Access: Private 00049 // Description: Use make() to make a new InternalName instance. 00050 //////////////////////////////////////////////////////////////////// 00051 InternalName:: 00052 InternalName(InternalName *parent, const string &basename) : 00053 _parent(parent), 00054 _basename(basename) 00055 { 00056 } 00057 00058 //////////////////////////////////////////////////////////////////// 00059 // Function: InternalName::Destructor 00060 // Access: Published, Virtual 00061 // Description: 00062 //////////////////////////////////////////////////////////////////// 00063 InternalName:: 00064 ~InternalName() { 00065 #ifndef NDEBUG 00066 if (_parent != (const InternalName *)NULL) { 00067 // unref() should have removed us from our parent's table already. 00068 LightMutexHolder holder(_parent->_name_table_lock); 00069 NameTable::iterator ni = _parent->_name_table.find(_basename); 00070 nassertv(ni == _parent->_name_table.end()); 00071 } 00072 #endif 00073 } 00074 00075 //////////////////////////////////////////////////////////////////// 00076 // Function: InternalName::unref 00077 // Access: Published, Virtual 00078 // Description: This method overrides ReferenceCount::unref() to 00079 // clear the pointer from its parent's table when 00080 // its reference count goes to zero. 00081 //////////////////////////////////////////////////////////////////// 00082 bool InternalName:: 00083 unref() const { 00084 if (_parent == (const InternalName *)NULL) { 00085 // No parent; no problem. This is the root InternalName. 00086 // Actually, this probably shouldn't be destructing, but I guess 00087 // it might at application shutdown. 00088 return TypedWritableReferenceCount::unref(); 00089 } 00090 00091 LightMutexHolder holder(_parent->_name_table_lock); 00092 00093 if (ReferenceCount::unref()) { 00094 return true; 00095 } 00096 00097 // The reference count has just reached zero. 00098 NameTable::iterator ni = _parent->_name_table.find(_basename); 00099 nassertr(ni != _parent->_name_table.end(), false); 00100 _parent->_name_table.erase(ni); 00101 00102 return false; 00103 } 00104 00105 //////////////////////////////////////////////////////////////////// 00106 // Function: InternalName::append 00107 // Access: Published 00108 // Description: Constructs a new InternalName based on this name, 00109 // with the indicated string following it. This is a 00110 // cheaper way to construct a hierarchical name than 00111 // InternalName::make(parent->get_name() + ".basename"). 00112 //////////////////////////////////////////////////////////////////// 00113 PT(InternalName) InternalName:: 00114 append(const string &name) { 00115 test_ref_count_integrity(); 00116 00117 if (name.empty()) { 00118 return this; 00119 } 00120 00121 size_t dot = name.rfind('.'); 00122 if (dot != string::npos) { 00123 return append(name.substr(0, dot))->append(name.substr(dot + 1)); 00124 } 00125 00126 LightMutexHolder holder(_name_table_lock); 00127 00128 NameTable::iterator ni = _name_table.find(name); 00129 if (ni != _name_table.end()) { 00130 return (*ni).second; 00131 } 00132 00133 InternalName *internal_name = new InternalName(this, name); 00134 _name_table[name] = internal_name; 00135 return internal_name; 00136 } 00137 00138 //////////////////////////////////////////////////////////////////// 00139 // Function: InternalName::get_name 00140 // Access: Published 00141 // Description: Returns the complete name represented by the 00142 // InternalName and all of its parents. 00143 //////////////////////////////////////////////////////////////////// 00144 string InternalName:: 00145 get_name() const { 00146 if (_parent == get_root()) { 00147 return _basename; 00148 00149 } else if (_parent == (InternalName *)NULL) { 00150 return string(); 00151 00152 } else { 00153 return _parent->get_name() + "." + _basename; 00154 } 00155 } 00156 00157 //////////////////////////////////////////////////////////////////// 00158 // Function: InternalName::find_ancestor 00159 // Access: Published 00160 // Description: Returns the index of the ancestor with the indicated 00161 // basename, or -1 if no ancestor has that basename. 00162 // Returns 0 if this name has the basename. 00163 // 00164 // This index value may be passed to get_ancestor() or 00165 // get_net_basename() to retrieve more information about 00166 // the indicated name. 00167 //////////////////////////////////////////////////////////////////// 00168 int InternalName:: 00169 find_ancestor(const string &basename) const { 00170 test_ref_count_integrity(); 00171 00172 if (_basename == basename) { 00173 return 0; 00174 00175 } else if (_parent != (InternalName *)NULL) { 00176 int index = _parent->find_ancestor(basename); 00177 if (index >= 0) { 00178 return index + 1; 00179 } 00180 } 00181 00182 return -1; 00183 } 00184 00185 //////////////////////////////////////////////////////////////////// 00186 // Function: InternalName::get_ancestor 00187 // Access: Published 00188 // Description: Returns the ancestor with the indicated index number. 00189 // 0 is this name itself, 1 is the name's parent, 2 is 00190 // the parent's parent, and so on. If there are not 00191 // enough ancestors, returns the root InternalName. 00192 //////////////////////////////////////////////////////////////////// 00193 const InternalName *InternalName:: 00194 get_ancestor(int n) const { 00195 test_ref_count_integrity(); 00196 00197 if (n == 0) { 00198 return this; 00199 00200 } else if (_parent != (InternalName *)NULL) { 00201 return _parent->get_ancestor(n - 1); 00202 00203 } else { 00204 return get_root(); 00205 } 00206 } 00207 00208 //////////////////////////////////////////////////////////////////// 00209 // Function: InternalName::get_top 00210 // Access: Published 00211 // Description: Returns the oldest ancestor in the InternalName's 00212 // chain, not counting the root. This will be the first 00213 // name in the string, e.g. "texcoord.foo.bar" will 00214 // return the InternalName "texcoord". 00215 //////////////////////////////////////////////////////////////////// 00216 const InternalName *InternalName:: 00217 get_top() const { 00218 test_ref_count_integrity(); 00219 00220 if (_parent != (InternalName *)NULL && _parent != get_root()) { 00221 return _parent->get_top(); 00222 } 00223 return this; 00224 } 00225 00226 //////////////////////////////////////////////////////////////////// 00227 // Function: InternalName::get_net_basename 00228 // Access: Published 00229 // Description: Returns the basename of this name prefixed by the 00230 // indicated number of ancestors. 0 is this name's 00231 // basename, 1 is parent.basename, 2 is 00232 // grandparent.parent.basename, and so on. 00233 //////////////////////////////////////////////////////////////////// 00234 string InternalName:: 00235 get_net_basename(int n) const { 00236 if (n < 0) { 00237 return ""; 00238 00239 } else if (n == 0) { 00240 return _basename; 00241 00242 } else if (_parent != (InternalName *)NULL && _parent != get_root()) { 00243 return _parent->get_net_basename(n - 1) + "." + _basename; 00244 00245 } else { 00246 return _basename; 00247 } 00248 } 00249 00250 //////////////////////////////////////////////////////////////////// 00251 // Function: InternalName::output 00252 // Access: Published 00253 // Description: 00254 //////////////////////////////////////////////////////////////////// 00255 void InternalName:: 00256 output(ostream &out) const { 00257 if (_parent == get_root()) { 00258 out << _basename; 00259 00260 } else if (_parent == (InternalName *)NULL) { 00261 out << "(root)"; 00262 00263 } else { 00264 _parent->output(out); 00265 out << '.' << _basename; 00266 } 00267 } 00268 00269 //////////////////////////////////////////////////////////////////// 00270 // Function: InternalName::register_with_read_factory 00271 // Access: Public, Static 00272 // Description: Factory method to generate a InternalName object 00273 //////////////////////////////////////////////////////////////////// 00274 void InternalName:: 00275 register_with_read_factory() { 00276 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00277 BamReader::get_factory()->register_factory(_texcoord_type_handle, make_texcoord_from_bam); 00278 } 00279 00280 //////////////////////////////////////////////////////////////////// 00281 // Function: InternalName::finalize 00282 // Access: Public, Virtual 00283 // Description: Called by the BamReader to perform any final actions 00284 // needed for setting up the object after all objects 00285 // have been read and all pointers have been completed. 00286 //////////////////////////////////////////////////////////////////// 00287 void InternalName:: 00288 finalize(BamReader *) { 00289 // Unref the pointer that we explicitly reffed in make_from_bam(). 00290 unref(); 00291 00292 // We should never get back to zero after unreffing our own count, 00293 // because we expect to have been stored in a pointer somewhere. If 00294 // we do get to zero, it's a memory leak; the way to avoid this is 00295 // to call unref_delete() above instead of unref(), but this is 00296 // dangerous to do from within a virtual function. 00297 nassertv(get_ref_count() != 0); 00298 } 00299 00300 //////////////////////////////////////////////////////////////////// 00301 // Function: InternalName::make 00302 // Access: Published, Static 00303 // Description: Make using a string and an integer. Concatenates 00304 // the two. 00305 //////////////////////////////////////////////////////////////////// 00306 PT(InternalName) InternalName:: 00307 make(const string &name, int index) { 00308 std::ostringstream full; 00309 full << name << index; 00310 return make(full.str()); 00311 } 00312 00313 //////////////////////////////////////////////////////////////////// 00314 // Function: InternalName::make_from_bam 00315 // Access: Protected, Static 00316 // Description: This function is called by the BamReader's factory 00317 // when a new object of type InternalName is encountered 00318 // in the Bam file. It should create the InternalName 00319 // and extract its information from the file. 00320 //////////////////////////////////////////////////////////////////// 00321 TypedWritable *InternalName:: 00322 make_from_bam(const FactoryParams ¶ms) { 00323 // The process of making a InternalName is slightly 00324 // different than making other Writable objects. 00325 // That is because all creation of InternalNames should 00326 // be done through the make() constructor. 00327 DatagramIterator scan; 00328 BamReader *manager; 00329 00330 parse_params(params, scan, manager); 00331 00332 // The name is the only thing written to the data stream. 00333 string name = scan.get_string(); 00334 00335 // Make a new InternalName with that name (or get the previous one 00336 // if there is one already). 00337 PT(InternalName) me = make(name); 00338 00339 // But now we have a problem, since we have to hold the reference 00340 // count and there's no way to return a TypedWritable while still 00341 // holding the reference count! We work around this by explicitly 00342 // upping the count, and also setting a finalize() callback to down 00343 // it later. 00344 me->ref(); 00345 manager->register_finalize(me); 00346 00347 return me.p(); 00348 } 00349 00350 //////////////////////////////////////////////////////////////////// 00351 // Function: InternalName::make_texcoord_from_bam 00352 // Access: Protected, Static 00353 // Description: This is a temporary method; it exists only to support 00354 // old bam files (4.11 through 4.17) generated before we 00355 // renamed this class from TexCoordName to InternalName. 00356 //////////////////////////////////////////////////////////////////// 00357 TypedWritable *InternalName:: 00358 make_texcoord_from_bam(const FactoryParams ¶ms) { 00359 DatagramIterator scan; 00360 BamReader *manager; 00361 parse_params(params, scan, manager); 00362 00363 string name = scan.get_string(); 00364 PT(InternalName) me; 00365 if (name == "default") { 00366 me = get_texcoord(); 00367 } else { 00368 me = get_texcoord_name(name); 00369 } 00370 00371 me->ref(); 00372 manager->register_finalize(me); 00373 00374 return me.p(); 00375 } 00376 00377 //////////////////////////////////////////////////////////////////// 00378 // Function: InternalName::write_datagram 00379 // Access: Public 00380 // Description: Function to write the important information in 00381 // the particular object to a Datagram 00382 //////////////////////////////////////////////////////////////////// 00383 void InternalName:: 00384 write_datagram(BamWriter *manager, Datagram &me) { 00385 me.add_string(get_name()); 00386 } 00387