00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00048
00049
00050
00051 InternalName::
00052 InternalName(InternalName *parent, const string &basename) :
00053 _parent(parent),
00054 _basename(basename)
00055 {
00056 }
00057
00058
00059
00060
00061
00062
00063 InternalName::
00064 ~InternalName() {
00065 #ifndef NDEBUG
00066 if (_parent != (const InternalName *)NULL) {
00067
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
00077
00078
00079
00080
00081
00082 bool InternalName::
00083 unref() const {
00084 if (_parent == (const InternalName *)NULL) {
00085
00086
00087
00088 return TypedWritableReferenceCount::unref();
00089 }
00090
00091 LightMutexHolder holder(_parent->_name_table_lock);
00092
00093 if (ReferenceCount::unref()) {
00094 return true;
00095 }
00096
00097
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
00107
00108
00109
00110
00111
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
00140
00141
00142
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
00159
00160
00161
00162
00163
00164
00165
00166
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
00187
00188
00189
00190
00191
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
00210
00211
00212
00213
00214
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
00228
00229
00230
00231
00232
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
00252
00253
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
00271
00272
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
00282
00283
00284
00285
00286
00287 void InternalName::
00288 finalize(BamReader *) {
00289
00290 unref();
00291
00292
00293
00294
00295
00296
00297 nassertv(get_ref_count() != 0);
00298 }
00299
00300
00301
00302
00303
00304
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
00315
00316
00317
00318
00319
00320
00321 TypedWritable *InternalName::
00322 make_from_bam(const FactoryParams ¶ms) {
00323
00324
00325
00326
00327 DatagramIterator scan;
00328 BamReader *manager;
00329
00330 parse_params(params, scan, manager);
00331
00332
00333 string name = scan.get_string();
00334
00335
00336
00337 PT(InternalName) me = make(name);
00338
00339
00340
00341
00342
00343
00344 me->ref();
00345 manager->register_finalize(me);
00346
00347 return me.p();
00348 }
00349
00350
00351
00352
00353
00354
00355
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
00379
00380
00381
00382
00383 void InternalName::
00384 write_datagram(BamWriter *manager, Datagram &me) {
00385 me.add_string(get_name());
00386 }
00387