00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "typeRegistry.h"
00016 #include "typeRegistryNode.h"
00017 #include "typeHandle.h"
00018 #include "typedObject.h"
00019 #include "indent.h"
00020 #include "numeric_types.h"
00021
00022 #include <algorithm>
00023
00024 MutexImpl *TypeRegistry::_lock = NULL;
00025 TypeRegistry *TypeRegistry::_global_pointer = NULL;
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 bool TypeRegistry::
00039 register_type(TypeHandle &type_handle, const string &name) {
00040 _lock->acquire();
00041
00042 if (type_handle != TypeHandle::none()) {
00043
00044
00045 TypeRegistryNode *rnode = look_up(type_handle, NULL);
00046 if (&type_handle == &rnode->_ref) {
00047
00048 _lock->release();
00049 assert(rnode->_name == name);
00050 return false;
00051 }
00052 }
00053
00054 NameRegistry::iterator ri;
00055 ri = _name_registry.find(name);
00056
00057 if (ri == _name_registry.end()) {
00058
00059
00060
00061 TypeHandle new_handle;
00062 new_handle._index = _handle_registry.size();
00063
00064 TypeRegistryNode *rnode = new TypeRegistryNode(new_handle, name, type_handle);
00065 _handle_registry.push_back(rnode);
00066 _name_registry[name] = rnode;
00067 _derivations_fresh = false;
00068
00069 type_handle = new_handle;
00070 _lock->release();
00071 return true;
00072 }
00073 TypeRegistryNode *rnode = (*ri).second;
00074 assert(rnode->_name == (*ri).first);
00075 assert(rnode->_handle._index >= 0 &&
00076 rnode->_handle._index < (int)_handle_registry.size());
00077 assert(_handle_registry[rnode->_handle._index] == rnode);
00078 assert(rnode->_handle._index != 0);
00079
00080
00081 if (&type_handle == &rnode->_ref) {
00082
00083
00084 if (type_handle == rnode->_handle) {
00085
00086 _lock->release();
00087 return false;
00088 }
00089
00090
00091
00092
00093
00094 cerr << "Reregistering " << name << "\n";
00095 type_handle == rnode->_handle;
00096 _lock->release();
00097 return false;
00098 }
00099
00100 if (type_handle != rnode->_handle) {
00101
00102 cerr
00103 << "Attempt to register type " << name << " more than once!\n";
00104
00105
00106
00107
00108
00109
00110 type_handle = rnode->_handle;
00111 }
00112 _lock->release();
00113 return false;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 TypeHandle TypeRegistry::
00126 register_dynamic_type(const string &name) {
00127 _lock->acquire();
00128
00129 NameRegistry::iterator ri;
00130 ri = _name_registry.find(name);
00131
00132 if (ri == _name_registry.end()) {
00133
00134
00135
00136
00137
00138
00139 TypeHandle *new_handle = new TypeHandle;
00140 new_handle->_index = _handle_registry.size();
00141
00142 TypeRegistryNode *rnode = new TypeRegistryNode(*new_handle, name, *new_handle);
00143 _handle_registry.push_back(rnode);
00144 _name_registry[name] = rnode;
00145 _derivations_fresh = false;
00146
00147 _lock->release();
00148 return *new_handle;
00149 }
00150
00151
00152 TypeRegistryNode *rnode = (*ri).second;
00153 TypeHandle handle = rnode->_handle;
00154 _lock->release();
00155 return handle;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 void TypeRegistry::
00167 record_derivation(TypeHandle child, TypeHandle parent) {
00168 _lock->acquire();
00169
00170 TypeRegistryNode *cnode = look_up(child, NULL);
00171 assert(cnode != (TypeRegistryNode *)NULL);
00172 TypeRegistryNode *pnode = look_up(parent, NULL);
00173 assert(pnode != (TypeRegistryNode *)NULL);
00174
00175
00176
00177 TypeRegistryNode::Classes::iterator ni;
00178 ni = find(cnode->_parent_classes.begin(), cnode->_parent_classes.end(),
00179 pnode);
00180
00181 if (ni == cnode->_parent_classes.end()) {
00182 cnode->_parent_classes.push_back(pnode);
00183 pnode->_child_classes.push_back(cnode);
00184 _derivations_fresh = false;
00185 }
00186
00187 _lock->release();
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 void TypeRegistry::
00200 record_alternate_name(TypeHandle type, const string &name) {
00201 _lock->acquire();
00202
00203 TypeRegistryNode *rnode = look_up(type, (TypedObject *)NULL);
00204 if (rnode != (TypeRegistryNode *)NULL) {
00205 NameRegistry::iterator ri =
00206 _name_registry.insert(NameRegistry::value_type(name, rnode)).first;
00207 if ((*ri).second != rnode) {
00208 cerr
00209 << "Name " << name << " already assigned to TypeHandle "
00210 << rnode->_name << "; cannot reassign to " << type << "\n";
00211 }
00212 }
00213
00214 _lock->release();
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224 TypeHandle TypeRegistry::
00225 find_type(const string &name) const {
00226 _lock->acquire();
00227
00228 TypeHandle handle = TypeHandle::none();
00229 NameRegistry::const_iterator ri;
00230 ri = _name_registry.find(name);
00231 if (ri != _name_registry.end()) {
00232 handle = (*ri).second->_handle;
00233 }
00234 _lock->release();
00235
00236 return handle;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 TypeHandle TypeRegistry::
00248 find_type_by_id(int id) const {
00249 if (id < 0 ||id >= (int)_handle_registry.size()) {
00250 cerr
00251 << "Invalid TypeHandle index " << id
00252 << "! Is memory corrupt?\n";
00253 return TypeHandle::none();
00254 }
00255
00256 return _handle_registry[id]->_handle;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 string TypeRegistry::
00271 get_name(TypeHandle type, TypedObject *object) const {
00272 _lock->acquire();
00273 TypeRegistryNode *rnode = look_up(type, object);
00274 assert(rnode != (TypeRegistryNode *)NULL);
00275 string name = rnode->_name;
00276 _lock->release();
00277
00278 return name;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 bool TypeRegistry::
00300 is_derived_from(TypeHandle child, TypeHandle base,
00301 TypedObject *child_object) {
00302 _lock->acquire();
00303
00304 const TypeRegistryNode *child_node = look_up(child, child_object);
00305 const TypeRegistryNode *base_node = look_up(base, (TypedObject *)NULL);
00306 assert(child_node != (TypeRegistryNode *)NULL &&
00307 base_node != (TypeRegistryNode *)NULL);
00308 freshen_derivations();
00309
00310 bool result = TypeRegistryNode::is_derived_from(child_node, base_node);
00311 _lock->release();
00312 return result;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321 int TypeRegistry::
00322 get_num_typehandles() {
00323 _lock->acquire();
00324 int num_types = (int)_handle_registry.size();
00325 _lock->release();
00326 return num_types;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335 TypeHandle TypeRegistry::
00336 get_typehandle(int n) {
00337 _lock->acquire();
00338 TypeRegistryNode *rnode = NULL;
00339 if (n >= 0 && n < (int)_handle_registry.size()) {
00340 rnode = _handle_registry[n];
00341 }
00342 _lock->release();
00343
00344 if (rnode != (TypeRegistryNode *)NULL) {
00345 return rnode->_handle;
00346 }
00347
00348 return TypeHandle::none();
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358 int TypeRegistry::
00359 get_num_root_classes() {
00360 _lock->acquire();
00361 freshen_derivations();
00362 int num_roots = _root_classes.size();
00363 _lock->release();
00364 return num_roots;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 TypeHandle TypeRegistry::
00374 get_root_class(int n) {
00375 _lock->acquire();
00376 freshen_derivations();
00377 TypeHandle handle;
00378 if (n >= 0 && n < (int)_root_classes.size()) {
00379 handle = _root_classes[n]->_handle;
00380 }
00381 _lock->release();
00382
00383 return handle;
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 int TypeRegistry::
00403 get_num_parent_classes(TypeHandle child, TypedObject *child_object) const {
00404 _lock->acquire();
00405 TypeRegistryNode *rnode = look_up(child, child_object);
00406 assert(rnode != (TypeRegistryNode *)NULL);
00407 int num_parents = rnode->_parent_classes.size();
00408 _lock->release();
00409 return num_parents;
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419 TypeHandle TypeRegistry::
00420 get_parent_class(TypeHandle child, int index) const {
00421 _lock->acquire();
00422 TypeHandle handle;
00423 TypeRegistryNode *rnode = look_up(child, (TypedObject *)NULL);
00424 assert(rnode != (TypeRegistryNode *)NULL);
00425 if (index >= 0 && index < (int)rnode->_parent_classes.size()) {
00426 handle = rnode->_parent_classes[index]->_handle;
00427 }
00428 _lock->release();
00429 return handle;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 int TypeRegistry::
00445 get_num_child_classes(TypeHandle child, TypedObject *child_object) const {
00446 _lock->acquire();
00447 TypeRegistryNode *rnode = look_up(child, child_object);
00448 assert(rnode != (TypeRegistryNode *)NULL);
00449 int num_children = rnode->_child_classes.size();
00450 _lock->release();
00451 return num_children;
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461 TypeHandle TypeRegistry::
00462 get_child_class(TypeHandle child, int index) const {
00463 _lock->acquire();
00464 TypeHandle handle;
00465 TypeRegistryNode *rnode = look_up(child, (TypedObject *)NULL);
00466 assert(rnode != (TypeRegistryNode *)NULL);
00467 if (index >= 0 && index < (int)rnode->_child_classes.size()) {
00468 handle = rnode->_child_classes[index]->_handle;
00469 }
00470 _lock->release();
00471 return handle;
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 TypeHandle TypeRegistry::
00489 get_parent_towards(TypeHandle child, TypeHandle base,
00490 TypedObject *child_object) {
00491 _lock->acquire();
00492 TypeHandle handle;
00493 const TypeRegistryNode *child_node = look_up(child, child_object);
00494 const TypeRegistryNode *base_node = look_up(base, NULL);
00495 assert(child_node != (TypeRegistryNode *)NULL &&
00496 base_node != (TypeRegistryNode *)NULL);
00497 freshen_derivations();
00498 handle = TypeRegistryNode::get_parent_towards(child_node, base_node);
00499 _lock->release();
00500 return handle;
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 void TypeRegistry::
00516 reregister_types() {
00517 init_lock();
00518 _lock->acquire();
00519 HandleRegistry::iterator ri;
00520 TypeRegistry *reg = ptr();
00521 for (ri = reg->_handle_registry.begin();
00522 ri != reg->_handle_registry.end();
00523 ++ri) {
00524 TypeRegistryNode *rnode = (*ri);
00525 if (rnode != NULL && rnode->_handle != rnode->_ref) {
00526 cerr << "Reregistering " << rnode->_name << "\n";
00527 }
00528 }
00529 _lock->release();
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 void TypeRegistry::
00541 write(ostream &out) const {
00542 _lock->acquire();
00543 do_write(out);
00544 _lock->release();
00545 }
00546
00547
00548
00549
00550
00551
00552
00553 TypeRegistry *TypeRegistry::
00554 ptr() {
00555 init_lock();
00556 _lock->acquire();
00557 if (_global_pointer == NULL) {
00558 init_global_pointer();
00559 }
00560 _lock->release();
00561 return _global_pointer;
00562 }
00563
00564
00565
00566
00567
00568
00569 TypeRegistry::
00570 TypeRegistry() {
00571
00572
00573
00574 _handle_registry.push_back(NULL);
00575
00576 _derivations_fresh = false;
00577
00578
00579
00580
00581
00582 assert(sizeof(PN_uint8) == 1 && sizeof(PN_int8) == 1);
00583 assert(sizeof(PN_uint16) == 2 && sizeof(PN_int16) == 2);
00584 assert(sizeof(PN_uint32) == 4 && sizeof(PN_int32) == 4);
00585 assert(sizeof(PN_uint64) == 8 && sizeof(PN_int64) == 8);
00586
00587 assert(sizeof(PN_float32) == 4);
00588 assert(sizeof(PN_float64) == 8);
00589 }
00590
00591
00592
00593
00594
00595
00596
00597 void TypeRegistry::
00598 init_global_pointer() {
00599 init_memory_hook();
00600 _global_pointer = new TypeRegistry;
00601 }
00602
00603
00604
00605
00606
00607
00608
00609
00610 void TypeRegistry::
00611 rebuild_derivations() {
00612
00613
00614 _root_classes.clear();
00615
00616 HandleRegistry::iterator hi;
00617 for (hi = _handle_registry.begin();
00618 hi != _handle_registry.end();
00619 ++hi) {
00620 TypeRegistryNode *node = *hi;
00621 if (node != (TypeRegistryNode *)NULL) {
00622 node->clear_subtree();
00623 }
00624 }
00625
00626
00627
00628 for (hi = _handle_registry.begin();
00629 hi != _handle_registry.end();
00630 ++hi) {
00631 TypeRegistryNode *node = *hi;
00632 if (node != NULL && node->_parent_classes.empty()) {
00633 _root_classes.push_back(node);
00634
00635
00636 node->define_subtree();
00637 }
00638 }
00639 }
00640
00641
00642
00643
00644
00645
00646
00647 void TypeRegistry::
00648 do_write(ostream &out) const {
00649
00650
00651 HandleRegistry::const_iterator hi;
00652 for (hi = _handle_registry.begin();
00653 hi != _handle_registry.end();
00654 ++hi) {
00655 const TypeRegistryNode *root = *hi;
00656 if (root != NULL && root->_parent_classes.empty()) {
00657 write_node(out, 2, root);
00658 }
00659 }
00660 }
00661
00662
00663
00664
00665
00666
00667
00668 void TypeRegistry::
00669 write_node(ostream &out, int indent_level, const TypeRegistryNode *node) const {
00670 indent(out, indent_level) << node->_handle.get_index() << " " << node->_name;
00671 if (!node->_parent_classes.empty()) {
00672 out << " : " << node->_parent_classes[0]->_name;
00673 for (int pi = 1; pi < (int)node->_parent_classes.size(); pi++) {
00674 out << ", " << node->_parent_classes[pi]->_name;
00675 }
00676 }
00677 out << "\n";
00678
00679 for (int i = 0; i < (int)node->_child_classes.size(); i++) {
00680 write_node(out, indent_level + 2, node->_child_classes[i]);
00681 }
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 TypeRegistryNode *TypeRegistry::
00700 look_up(TypeHandle handle, TypedObject *object) const {
00701 #ifndef NDEBUG
00702 if (handle._index == 0) {
00703
00704
00705 if (object != NULL) {
00706
00707
00708
00709 _lock->release();
00710 handle = object->force_init_type();
00711 _lock->acquire();
00712 if (handle._index == 0) {
00713
00714 cerr
00715 << "Unable to force_init_type() on unregistered TypeHandle.\n";
00716 return NULL;
00717 }
00718 if (handle == object->get_type()) {
00719
00720 cerr
00721 << "Type " << handle << " was unregistered!\n";
00722 } else {
00723
00724
00725
00726 cerr
00727 << "Attempt to reference unregistered TypeHandle. Type is of some\n"
00728 << "class derived from " << handle << " that doesn't define a good\n"
00729 << "force_init_type() method.\n";
00730 return NULL;
00731 }
00732
00733 } else {
00734
00735
00736 cerr
00737 << "Attempt to reference unregistered TypeHandle!\n"
00738 << "Registered TypeHandles are:\n";
00739 write(cerr);
00740 return NULL;
00741 }
00742 }
00743
00744 if (handle._index < 0 ||
00745 handle._index >= (int)_handle_registry.size()) {
00746 cerr
00747 << "Invalid TypeHandle index " << handle._index
00748 << "! Is memory corrupt?\n";
00749 return NULL;
00750 }
00751 #endif // NDEBUG
00752
00753 return _handle_registry[handle._index];
00754 }
00755
00756
00757
00758
00759
00760 extern "C" int
00761 get_best_parent_from_Set(int id, const std::set<int> &this_set) {
00762
00763 if (this_set.find(id) != this_set.end()) {
00764 return id;
00765 }
00766
00767 TypeHandle th = TypeRegistry::ptr()->find_type_by_id(id);
00768 if (th == TypeHandle::none()) {
00769 return -1;
00770 }
00771
00772 return th.get_best_parent_from_Set(this_set);
00773 }
00774