Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

dtool/src/interrogatedb/interrogateDatabase.cxx

Go to the documentation of this file.
00001 // Filename: interrogateDatabase.cxx
00002 // Created by:  drose (01Aug00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "interrogateDatabase.h"
00020 #include "config_interrogatedb.h"
00021 #include "indexRemapper.h"
00022 #include "interrogate_datafile.h"
00023 
00024 InterrogateDatabase *InterrogateDatabase::_global_ptr = NULL;
00025 int InterrogateDatabase::_file_major_version = 0;
00026 int InterrogateDatabase::_file_minor_version = 0;
00027 int InterrogateDatabase::_current_major_version = 2;
00028 int InterrogateDatabase::_current_minor_version = 2;
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: InterrogateDatabase::Constructor
00032 //       Access: Private
00033 //  Description:
00034 ////////////////////////////////////////////////////////////////////
00035 InterrogateDatabase::
00036 InterrogateDatabase() {
00037   _next_index = 1;
00038   _lookups_fresh = 0;
00039 }
00040 
00041 ////////////////////////////////////////////////////////////////////
00042 //     Function: InterrogateDatabase::get_ptr
00043 //       Access: Private
00044 //  Description: Returns the global pointer to the one
00045 //               InterrogateDatabase.
00046 ////////////////////////////////////////////////////////////////////
00047 InterrogateDatabase *InterrogateDatabase::
00048 get_ptr() {
00049   if (_global_ptr == (InterrogateDatabase *)NULL) {
00050     if (interrogatedb_cat->is_debug()) {
00051       interrogatedb_cat->debug()
00052         << "Creating interrogate database\n";
00053     }
00054     _global_ptr = new InterrogateDatabase;
00055   }
00056   return _global_ptr;
00057 }
00058 
00059 ////////////////////////////////////////////////////////////////////
00060 //     Function: InterrogateDatabase::request_module
00061 //       Access: Public
00062 //  Description: Requests that the interrogate data for the given
00063 //               module be made available.  The function pointers will
00064 //               be made available immediately, while the database
00065 //               file will be read later, the next time someone asks
00066 //               for interrogate data that requires it.
00067 ////////////////////////////////////////////////////////////////////
00068 void InterrogateDatabase::
00069 request_module(InterrogateModuleDef *def) {
00070   if (interrogatedb_cat->is_debug()) {
00071     if (def->library_name == (const char *)NULL) {
00072       interrogatedb_cat->debug()
00073         << "Got interrogate data for anonymous module\n";
00074     } else {
00075       interrogatedb_cat->debug()
00076         << "Got interrogate data for module " << def->library_name << "\n";
00077     }
00078   }
00079 
00080   int num_indices = def->next_index - def->first_index;
00081   if (num_indices > 0) {
00082     // If the module def has any definitions--any index numbers
00083     // used--assign it to its own unique range of index numbers.
00084     def->first_index = _next_index;
00085     _next_index += num_indices;
00086     def->next_index = _next_index;
00087 
00088     // Assign a reference to the module def by index number.  When we
00089     // need to look up a function by its index number, we'll be able
00090     // to use this.
00091     _modules.push_back(def);
00092   }
00093 
00094   if (def->num_unique_names > 0 && def->library_name != (const char *)NULL) {
00095     // Define a lookup by hash for this module, mainly so we can look
00096     // up functions by their unique names.
00097     _modules_by_hash[def->library_hash_name] = def;
00098   }
00099 
00100   if (def->database_filename != (const char *)NULL) {
00101     _requests.push_back(def);
00102   }
00103 }
00104 
00105 ////////////////////////////////////////////////////////////////////
00106 //     Function: InterrogateDatabase::get_num_global_types
00107 //       Access: Public
00108 //  Description: Returns the total number of "global" types known to
00109 //               the interrogate database.  These are types defined at
00110 //               the global level that should be considered for
00111 //               exporting, but not the incidental types (like
00112 //               pointers, etc.) that must be defined to support
00113 //               these.
00114 ////////////////////////////////////////////////////////////////////
00115 int InterrogateDatabase::
00116 get_num_global_types() {
00117   check_latest();
00118   return _global_types.size();
00119 }
00120 
00121 ////////////////////////////////////////////////////////////////////
00122 //     Function: InterrogateDatabase::get_global_type
00123 //       Access: Public
00124 //  Description: Returns the index of the nth global type known to the
00125 //               interrogate database.
00126 ////////////////////////////////////////////////////////////////////
00127 TypeIndex InterrogateDatabase::
00128 get_global_type(int n) {
00129   check_latest();
00130   if (n >= 0 && n < (int)_global_types.size()) {
00131     return _global_types[n];
00132   }
00133   return 0;
00134 }
00135 
00136 ////////////////////////////////////////////////////////////////////
00137 //     Function: InterrogateDatabase::get_num_all_types
00138 //       Access: Public
00139 //  Description: Returns the total number of types known to the
00140 //               interrogate database.  This includes all known types,
00141 //               global as well as incidental.  See also
00142 //               get_num_global_types().
00143 ////////////////////////////////////////////////////////////////////
00144 int InterrogateDatabase::
00145 get_num_all_types() {
00146   check_latest();
00147   return _all_types.size();
00148 }
00149 
00150 ////////////////////////////////////////////////////////////////////
00151 //     Function: InterrogateDatabase::get_all_type
00152 //       Access: Public
00153 //  Description: Returns the index of the nth type known to the
00154 //               interrogate database.
00155 ////////////////////////////////////////////////////////////////////
00156 TypeIndex InterrogateDatabase::
00157 get_all_type(int n) {
00158   check_latest();
00159   if (n >= 0 && n < (int)_all_types.size()) {
00160     return _all_types[n];
00161   }
00162   return 0;
00163 }
00164 
00165 ////////////////////////////////////////////////////////////////////
00166 //     Function: InterrogateDatabase::get_num_global_functions
00167 //       Access: Public
00168 //  Description: Returns the total number of global functions known to
00169 //               the interrogate database.  These are functions
00170 //               defined at the global level, e.g. non-member
00171 //               functions.
00172 ////////////////////////////////////////////////////////////////////
00173 int InterrogateDatabase::
00174 get_num_global_functions() {
00175   check_latest();
00176   return _global_functions.size();
00177 }
00178 
00179 ////////////////////////////////////////////////////////////////////
00180 //     Function: InterrogateDatabase::get_global_function
00181 //       Access: Public
00182 //  Description: Returns the index of the nth global function known to
00183 //               the interrogate database.
00184 ////////////////////////////////////////////////////////////////////
00185 FunctionIndex InterrogateDatabase::
00186 get_global_function(int n) {
00187   check_latest();
00188   if (n >= 0 && n < (int)_global_functions.size()) {
00189     return _global_functions[n];
00190   }
00191   return 0;
00192 }
00193 
00194 ////////////////////////////////////////////////////////////////////
00195 //     Function: InterrogateDatabase::get_num_all_functions
00196 //       Access: Public
00197 //  Description: Returns the total number of functions known to the
00198 //               interrogate database.  This includes all known
00199 //               functions, global, method, or synthesized.  See also
00200 //               get_num_global_functions().
00201 ////////////////////////////////////////////////////////////////////
00202 int InterrogateDatabase::
00203 get_num_all_functions() {
00204   check_latest();
00205   return _all_functions.size();
00206 }
00207 
00208 ////////////////////////////////////////////////////////////////////
00209 //     Function: InterrogateDatabase::get_all_function
00210 //       Access: Public
00211 //  Description: Returns the index of the nth function known to the
00212 //               interrogate database.
00213 ////////////////////////////////////////////////////////////////////
00214 FunctionIndex InterrogateDatabase::
00215 get_all_function(int n) {
00216   check_latest();
00217   if (n >= 0 && n < (int)_all_functions.size()) {
00218     return _all_functions[n];
00219   }
00220   return 0;
00221 }
00222 
00223 ////////////////////////////////////////////////////////////////////
00224 //     Function: InterrogateDatabase::get_num_global_manifests
00225 //       Access: Public
00226 //  Description: Returns the total number of global manifest constants
00227 //               known to the interrogate database.
00228 ////////////////////////////////////////////////////////////////////
00229 int InterrogateDatabase::
00230 get_num_global_manifests() {
00231   check_latest();
00232   return _global_manifests.size();
00233 }
00234 
00235 ////////////////////////////////////////////////////////////////////
00236 //     Function: InterrogateDatabase::get_global_manifest
00237 //       Access: Public
00238 //  Description: Returns the index of the nth global manifest constant
00239 //               known to the interrogate database.
00240 ////////////////////////////////////////////////////////////////////
00241 ManifestIndex InterrogateDatabase::
00242 get_global_manifest(int n) {
00243   check_latest();
00244   if (n >= 0 && n < (int)_global_manifests.size()) {
00245     return _global_manifests[n];
00246   }
00247   return 0;
00248 }
00249 
00250 ////////////////////////////////////////////////////////////////////
00251 //     Function: InterrogateDatabase::get_num_global_elements
00252 //       Access: Public
00253 //  Description: Returns the total number of global data elements
00254 //               known to the interrogate database.
00255 ////////////////////////////////////////////////////////////////////
00256 int InterrogateDatabase::
00257 get_num_global_elements() {
00258   check_latest();
00259   return _global_elements.size();
00260 }
00261 
00262 ////////////////////////////////////////////////////////////////////
00263 //     Function: InterrogateDatabase::get_global_element
00264 //       Access: Public
00265 //  Description: Returns the index of the nth global data element
00266 //               known to the interrogate database.
00267 ////////////////////////////////////////////////////////////////////
00268 ElementIndex InterrogateDatabase::
00269 get_global_element(int n) {
00270   check_latest();
00271   if (n >= 0 && n < (int)_global_elements.size()) {
00272     return _global_elements[n];
00273   }
00274   return 0;
00275 }
00276 
00277 ////////////////////////////////////////////////////////////////////
00278 //     Function: InterrogateDatabase::get_type
00279 //       Access: Public
00280 //  Description: Returns the type associated with the given TypeIndex,
00281 //               if there is one.
00282 ////////////////////////////////////////////////////////////////////
00283 const InterrogateType &InterrogateDatabase::
00284 get_type(TypeIndex type) {
00285   static InterrogateType bogus_type;
00286 
00287   check_latest();
00288   TypeMap::const_iterator ti;
00289   ti = _type_map.find(type);
00290   if (ti == _type_map.end()) {
00291     return bogus_type;
00292   }
00293   return (*ti).second;
00294 }
00295 
00296 ////////////////////////////////////////////////////////////////////
00297 //     Function: InterrogateDatabase::get_function
00298 //       Access: Public
00299 //  Description: Returns the function associated with the given
00300 //               FunctionIndex, if there is one.
00301 ////////////////////////////////////////////////////////////////////
00302 const InterrogateFunction &InterrogateDatabase::
00303 get_function(FunctionIndex function) {
00304   static InterrogateFunction bogus_function;
00305 
00306   check_latest();
00307   FunctionMap::const_iterator fi;
00308   fi = _function_map.find(function);
00309   if (fi == _function_map.end()) {
00310     return bogus_function;
00311   }
00312   return *(*fi).second;
00313 }
00314 
00315 ////////////////////////////////////////////////////////////////////
00316 //     Function: InterrogateDatabase::get_wrapper
00317 //       Access: Public
00318 //  Description: Returns the function wrapper associated with the
00319 //               given FunctionWrapperIndex, if there is one.
00320 ////////////////////////////////////////////////////////////////////
00321 const InterrogateFunctionWrapper &InterrogateDatabase::
00322 get_wrapper(FunctionWrapperIndex wrapper) {
00323   static InterrogateFunctionWrapper bogus_wrapper;
00324 
00325   check_latest();
00326   FunctionWrapperMap::const_iterator wi;
00327   wi = _wrapper_map.find(wrapper);
00328   if (wi == _wrapper_map.end()) {
00329     return bogus_wrapper;
00330   }
00331   return (*wi).second;
00332 }
00333 
00334 ////////////////////////////////////////////////////////////////////
00335 //     Function: InterrogateDatabase::get_manifest
00336 //       Access: Public
00337 //  Description: Returns the manifest constant associated with the
00338 //               given ManifestIndex, if there is one.
00339 ////////////////////////////////////////////////////////////////////
00340 const InterrogateManifest &InterrogateDatabase::
00341 get_manifest(ManifestIndex manifest) {
00342   static InterrogateManifest bogus_manifest;
00343 
00344   check_latest();
00345   ManifestMap::const_iterator mi;
00346   mi = _manifest_map.find(manifest);
00347   if (mi == _manifest_map.end()) {
00348     return bogus_manifest;
00349   }
00350   return (*mi).second;
00351 }
00352 
00353 ////////////////////////////////////////////////////////////////////
00354 //     Function: InterrogateDatabase::get_element
00355 //       Access: Public
00356 //  Description: Returns the data element associated with the
00357 //               given ElementIndex, if there is one.
00358 ////////////////////////////////////////////////////////////////////
00359 const InterrogateElement &InterrogateDatabase::
00360 get_element(ElementIndex element) {
00361   static InterrogateElement bogus_element;
00362 
00363   check_latest();
00364   ElementMap::const_iterator ei;
00365   ei = _element_map.find(element);
00366   if (ei == _element_map.end()) {
00367     return bogus_element;
00368   }
00369   return (*ei).second;
00370 }
00371 
00372 ////////////////////////////////////////////////////////////////////
00373 //     Function: InterrogateDatabase::remove_type
00374 //       Access: Public
00375 //  Description: Erases the type from the database.
00376 ////////////////////////////////////////////////////////////////////
00377 void InterrogateDatabase::
00378 remove_type(TypeIndex type) {
00379   _type_map.erase(type);
00380 }
00381 
00382 ////////////////////////////////////////////////////////////////////
00383 //     Function: InterrogateDatabase::get_fptr
00384 //       Access: Public
00385 //  Description: Returns the function pointer associated with the
00386 //               given function wrapper, if it has a pointer
00387 //               available.  Returns NULL if the pointer is not
00388 //               available.
00389 ////////////////////////////////////////////////////////////////////
00390 void *InterrogateDatabase::
00391 get_fptr(FunctionWrapperIndex wrapper) {
00392   InterrogateModuleDef *def;
00393   int module_index;
00394   if (find_module(wrapper, def, module_index)) {
00395     if (module_index >= 0 && module_index < def->num_fptrs) {
00396       return def->fptrs[module_index];
00397     }
00398   }
00399   return (void *)NULL;
00400 }
00401 
00402 ////////////////////////////////////////////////////////////////////
00403 //     Function: InterrogateDatabase::get_wrapper_by_unique_name
00404 //       Access: Public
00405 //  Description: Looks up the function wrapper corresponding to the
00406 //               given unique name, if available.  Returns the
00407 //               corresponding wrapper index, or 0 if no such
00408 //               wrapper is found.
00409 ////////////////////////////////////////////////////////////////////
00410 FunctionWrapperIndex InterrogateDatabase::
00411 get_wrapper_by_unique_name(const string &unique_name) {
00412   // First, split the unique_name into a library_hash_name and a
00413   // wrapper_hash_name.
00414 
00415   // The first four characters are always the library_name.
00416   string library_hash_name = unique_name.substr(0, 4);
00417   string wrapper_hash_name = unique_name.substr(4);
00418 
00419   // Is the library_name defined?
00420   ModulesByHash::const_iterator mi;
00421   mi = _modules_by_hash.find(library_hash_name);
00422   if (mi == _modules_by_hash.end()) {
00423     return 0;
00424   }
00425 
00426   InterrogateModuleDef *def = (*mi).second;
00427   int index_offset =
00428     binary_search_wrapper_hash(def->unique_names,
00429                                def->unique_names + def->num_unique_names,
00430                                wrapper_hash_name);
00431   if (index_offset >= 0) {
00432     return def->first_index + index_offset;
00433   }
00434 
00435   return 0;
00436 }
00437 
00438 ////////////////////////////////////////////////////////////////////
00439 //     Function: InterrogateDatabase::get_file_major_version
00440 //       Access: Public
00441 //  Description: Returns the major version number of the interrogate
00442 //               database file currently being read.
00443 ////////////////////////////////////////////////////////////////////
00444 int InterrogateDatabase::
00445 get_file_major_version() {
00446   return _file_major_version;
00447 }
00448 
00449 ////////////////////////////////////////////////////////////////////
00450 //     Function: InterrogateDatabase::get_file_minor_version
00451 //       Access: Public
00452 //  Description: Returns the minor version number of the interrogate
00453 //               database file currently being read.
00454 ////////////////////////////////////////////////////////////////////
00455 int InterrogateDatabase::
00456 get_file_minor_version() {
00457   return _file_minor_version;
00458 }
00459 
00460 ////////////////////////////////////////////////////////////////////
00461 //     Function: InterrogateDatabase::get_current_major_version
00462 //       Access: Public
00463 //  Description: Returns the major version number currently expected
00464 //               in interrogate database files generated by this code
00465 //               base.
00466 ////////////////////////////////////////////////////////////////////
00467 int InterrogateDatabase::
00468 get_current_major_version() {
00469   return _current_major_version;
00470 }
00471 
00472 ////////////////////////////////////////////////////////////////////
00473 //     Function: InterrogateDatabase::get_current_minor_version
00474 //       Access: Public
00475 //  Description: Returns the minor version number currently expected
00476 //               in interrogate database files generated by this code
00477 //               base.
00478 ////////////////////////////////////////////////////////////////////
00479 int InterrogateDatabase::
00480 get_current_minor_version() {
00481   return _current_minor_version;
00482 }
00483 
00484 ////////////////////////////////////////////////////////////////////
00485 //     Function: InterrogateDatabase::get_next_index
00486 //       Access: Public
00487 //  Description: Returns a new index number suitable for the next
00488 //               thing, that will not be shared with any other index
00489 //               numbers.
00490 ////////////////////////////////////////////////////////////////////
00491 int InterrogateDatabase::
00492 get_next_index() {
00493   return _next_index++;
00494 }
00495 
00496 ////////////////////////////////////////////////////////////////////
00497 //     Function: InterrogateDatabase::add_type
00498 //       Access: Public
00499 //  Description: Adds the indicated type to the database at the given
00500 //               index number.
00501 ////////////////////////////////////////////////////////////////////
00502 void InterrogateDatabase::
00503 add_type(TypeIndex index, const InterrogateType &type) {
00504   assert(index != 0);
00505   bool inserted =
00506     _type_map.insert(TypeMap::value_type(index, type)).second;
00507 
00508   if (!inserted) {
00509     // If there was already a type at that index, maybe it was a
00510     // forward reference.  If its _fully_defined bit isn't set, then
00511     // it's ok.
00512     InterrogateType &old_type = _type_map[index];
00513     assert(!old_type.is_fully_defined());
00514 
00515     // It was a forward reference.  Merge it with the new one.
00516     old_type.merge_with(type);
00517   }
00518 
00519   if (type.is_global()) {
00520     _global_types.push_back(index);
00521   }
00522   _all_types.push_back(index);
00523 }
00524 
00525 ////////////////////////////////////////////////////////////////////
00526 //     Function: InterrogateDatabase::add_function
00527 //       Access: Public
00528 //  Description: Adds the indicated function to the database at
00529 //               the given index number.
00530 ////////////////////////////////////////////////////////////////////
00531 void InterrogateDatabase::
00532 add_function(FunctionIndex index, InterrogateFunction *function) {
00533   bool inserted =
00534     _function_map.insert(FunctionMap::value_type(index, function)).second;
00535   assert(inserted);
00536 
00537   if (function->is_global()) {
00538     _global_functions.push_back(index);
00539   }
00540   _all_functions.push_back(index);
00541 }
00542 
00543 ////////////////////////////////////////////////////////////////////
00544 //     Function: InterrogateDatabase::add_wrapper
00545 //       Access: Public
00546 //  Description: Adds the indicated function wrapper to the database at
00547 //               the given index number.
00548 ////////////////////////////////////////////////////////////////////
00549 void InterrogateDatabase::
00550 add_wrapper(FunctionWrapperIndex index,
00551             const InterrogateFunctionWrapper &wrapper) {
00552   bool inserted =
00553     _wrapper_map.insert(FunctionWrapperMap::value_type(index, wrapper)).second;
00554   assert(inserted);
00555 }
00556 
00557 ////////////////////////////////////////////////////////////////////
00558 //     Function: InterrogateDatabase::add_manifest
00559 //       Access: Public
00560 //  Description: Adds the indicated manifest constant to the database
00561 //               at the given index number.
00562 ////////////////////////////////////////////////////////////////////
00563 void InterrogateDatabase::
00564 add_manifest(ManifestIndex index, const InterrogateManifest &manifest) {
00565   bool inserted =
00566     _manifest_map.insert(ManifestMap::value_type(index, manifest)).second;
00567   assert(inserted);
00568 
00569   _global_manifests.push_back(index);
00570 }
00571 
00572 ////////////////////////////////////////////////////////////////////
00573 //     Function: InterrogateDatabase::add_element
00574 //       Access: Public
00575 //  Description: Adds the indicated data element to the database
00576 //               at the given index number.
00577 ////////////////////////////////////////////////////////////////////
00578 void InterrogateDatabase::
00579 add_element(ElementIndex index, const InterrogateElement &element) {
00580   bool inserted =
00581     _element_map.insert(ElementMap::value_type(index, element)).second;
00582   assert(inserted);
00583 
00584   if (element.is_global()) {
00585     _global_elements.push_back(index);
00586   }
00587 }
00588 
00589 ////////////////////////////////////////////////////////////////////
00590 //     Function: InterrogateDatabase::update_type
00591 //       Access: Public
00592 //  Description: Returns a non-const reference to the indicated type,
00593 //               allowing the user to update it.
00594 ////////////////////////////////////////////////////////////////////
00595 InterrogateType &InterrogateDatabase::
00596 update_type(TypeIndex type) {
00597   assert(type != 0);
00598   check_latest();
00599   return _type_map[type];
00600 }
00601 
00602 ////////////////////////////////////////////////////////////////////
00603 //     Function: InterrogateDatabase::update_function
00604 //       Access: Public
00605 //  Description: Returns a non-const reference to the indicated
00606 //               function, allowing the user to update it.
00607 ////////////////////////////////////////////////////////////////////
00608 InterrogateFunction &InterrogateDatabase::
00609 update_function(FunctionIndex function) {
00610   check_latest();
00611   return *_function_map[function];
00612 }
00613 
00614 ////////////////////////////////////////////////////////////////////
00615 //     Function: InterrogateDatabase::update_wrapper
00616 //       Access: Public
00617 //  Description: Returns a non-const reference to the indicated
00618 //               function wrapper, allowing the user to update it.
00619 ////////////////////////////////////////////////////////////////////
00620 InterrogateFunctionWrapper &InterrogateDatabase::
00621 update_wrapper(FunctionWrapperIndex wrapper) {
00622   check_latest();
00623   return _wrapper_map[wrapper];
00624 }
00625 
00626 ////////////////////////////////////////////////////////////////////
00627 //     Function: InterrogateDatabase::update_manifest
00628 //       Access: Public
00629 //  Description: Returns a non-const reference to the indicated
00630 //               manifest constant, allowing the user to update it.
00631 ////////////////////////////////////////////////////////////////////
00632 InterrogateManifest &InterrogateDatabase::
00633 update_manifest(ManifestIndex manifest) {
00634   check_latest();
00635   return _manifest_map[manifest];
00636 }
00637 
00638 ////////////////////////////////////////////////////////////////////
00639 //     Function: InterrogateDatabase::update_element
00640 //       Access: Public
00641 //  Description: Returns a non-const reference to the indicated
00642 //               data element, allowing the user to update it.
00643 ////////////////////////////////////////////////////////////////////
00644 InterrogateElement &InterrogateDatabase::
00645 update_element(ElementIndex element) {
00646   check_latest();
00647   return _element_map[element];
00648 }
00649 
00650 ////////////////////////////////////////////////////////////////////
00651 //     Function: InterrogateDatabase::remap_indices
00652 //       Access: Public
00653 //  Description: Resequences all of the various index numbers so that
00654 //               all of the functions start at first_index and
00655 //               increment consecutively from there, and then all of
00656 //               the types follow.  Returns the next available index
00657 //               number.
00658 ////////////////////////////////////////////////////////////////////
00659 int InterrogateDatabase::
00660 remap_indices(int first_index) {
00661   IndexRemapper remap;
00662   return remap_indices(first_index, remap);
00663 }
00664 
00665 ////////////////////////////////////////////////////////////////////
00666 //     Function: InterrogateDatabase::remap_indices
00667 //       Access: Public
00668 //  Description: This flavor of remap_indices() accepts a map that
00669 //               should be empty on initial call, and will be filled
00670 //               with the mapping of old index number to new index
00671 //               number.  This allows the caller to update its own
00672 //               data structures to match the new index numbers.
00673 ////////////////////////////////////////////////////////////////////
00674 int InterrogateDatabase::
00675 remap_indices(int first_index, IndexRemapper &remap) {
00676   remap.clear();
00677 
00678   // First, build up the complete map.
00679 
00680   // Get the wrapper indices first.  This is important, because the
00681   // InterrogateBuilder wants these to be first, and consecutive.
00682   FunctionWrapperMap new_wrapper_map;
00683   FunctionWrapperMap::iterator wi;
00684   for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00685     remap.add_mapping((*wi).first, first_index);
00686     new_wrapper_map[first_index] = (*wi).second;
00687     first_index++;
00688   }
00689 
00690   // Everything else can follow; it doesn't matter so much.
00691   FunctionMap new_function_map;
00692   FunctionMap::iterator fi;
00693   for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00694     remap.add_mapping((*fi).first, first_index);
00695     new_function_map[first_index] = (*fi).second;
00696     first_index++;
00697   }
00698 
00699   TypeMap new_type_map;
00700   TypeMap::iterator ti;
00701   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00702     assert((*ti).first != 0);
00703     remap.add_mapping((*ti).first, first_index);
00704     new_type_map[first_index] = (*ti).second;
00705     first_index++;
00706   }
00707 
00708   ManifestMap new_manifest_map;
00709   ManifestMap::iterator mi;
00710   for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00711     remap.add_mapping((*mi).first, first_index);
00712     new_manifest_map[first_index] = (*mi).second;
00713     first_index++;
00714   }
00715 
00716   ElementMap new_element_map;
00717   ElementMap::iterator ei;
00718   for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00719     remap.add_mapping((*ei).first, first_index);
00720     new_element_map[first_index] = (*ei).second;
00721     first_index++;
00722   }
00723 
00724   _next_index = first_index;
00725 
00726   _wrapper_map.swap(new_wrapper_map);
00727   _function_map.swap(new_function_map);
00728   _type_map.swap(new_type_map);
00729   _manifest_map.swap(new_manifest_map);
00730   _element_map.swap(new_element_map);
00731 
00732   // Then, go back through and update all of the internal references.
00733   for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00734     (*wi).second.remap_indices(remap);
00735   }
00736   for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00737     (*fi).second->remap_indices(remap);
00738   }
00739   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00740     (*ti).second.remap_indices(remap);
00741   }
00742   for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00743     (*mi).second.remap_indices(remap);
00744   }
00745   for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00746     (*ei).second.remap_indices(remap);
00747   }
00748   GlobalFunctions::iterator gfi;
00749   for (gfi = _global_functions.begin(); gfi != _global_functions.end(); ++gfi) {
00750     (*gfi) = remap.map_from(*gfi);
00751   }
00752   for (gfi = _all_functions.begin(); gfi != _all_functions.end(); ++gfi) {
00753     (*gfi) = remap.map_from(*gfi);
00754   }
00755   GlobalTypes::iterator gti;
00756   for (gti = _global_types.begin(); gti != _global_types.end(); ++gti) {
00757     (*gti) = remap.map_from(*gti);
00758   }
00759   for (gti = _all_types.begin(); gti != _all_types.end(); ++gti) {
00760     (*gti) = remap.map_from(*gti);
00761   }
00762   GlobalManifests::iterator gmi;
00763   for (gmi = _global_manifests.begin(); gmi != _global_manifests.end(); ++gmi) {
00764     (*gmi) = remap.map_from(*gmi);
00765   }
00766   GlobalElements::iterator gei;
00767   for (gei = _global_elements.begin(); gei != _global_elements.end(); ++gei) {
00768     (*gei) = remap.map_from(*gei);
00769   }
00770 
00771   return _next_index;
00772 }
00773 
00774 ////////////////////////////////////////////////////////////////////
00775 //     Function: InterrogateDatabase::write
00776 //       Access: Public
00777 //  Description: Writes the database to the indicated stream for later
00778 //               reading.
00779 ////////////////////////////////////////////////////////////////////
00780 void InterrogateDatabase::
00781 write(ostream &out, InterrogateModuleDef *def) const {
00782   // Write out the file header.
00783   out << def->file_identifier << "\n"
00784       << _current_major_version << " " << _current_minor_version << "\n";
00785 
00786   // Write out the module definition.
00787   idf_output_string(out, def->library_name);
00788   idf_output_string(out, def->library_hash_name);
00789   idf_output_string(out, def->module_name);
00790   out << "\n";
00791 
00792   // Now write out the components.
00793 
00794   out << _function_map.size() << "\n";
00795   FunctionMap::const_iterator fi;
00796   for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00797     out << (*fi).first << " " << *(*fi).second << "\n";
00798   }
00799 
00800   out << _wrapper_map.size() << "\n";
00801   FunctionWrapperMap::const_iterator wi;
00802   for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00803     out << (*wi).first << " " << (*wi).second << "\n";
00804   }
00805 
00806   out << _type_map.size() << "\n";
00807   TypeMap::const_iterator ti;
00808   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00809     out << (*ti).first << " " << (*ti).second << "\n";
00810   }
00811 
00812   out << _manifest_map.size() << "\n";
00813   ManifestMap::const_iterator mi;
00814   for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00815     out << (*mi).first << " " << (*mi).second << "\n";
00816   }
00817 
00818   out << _element_map.size() << "\n";
00819   ElementMap::const_iterator ei;
00820   for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00821     out << (*ei).first << " " << (*ei).second << "\n";
00822   }
00823 }
00824 
00825 ////////////////////////////////////////////////////////////////////
00826 //     Function: InterrogateDatabase::read
00827 //       Access: Public
00828 //  Description: Reads a database from the indicated stream,
00829 //               associated with the indicated module definition and
00830 //               merges it with any existing data in the database,
00831 //               according to the expected index numbers specified in
00832 //               the module def.  The header information has already
00833 //               been read.
00834 //
00835 //               Returns true if the file is read successfully, false
00836 //               if there is an error.
00837 ////////////////////////////////////////////////////////////////////
00838 bool InterrogateDatabase::
00839 read(istream &in, InterrogateModuleDef *def) {
00840   InterrogateDatabase temp;
00841   if (!temp.read_new(in, def)) {
00842     return false;
00843   }
00844 
00845   if (def->first_index == 0 && def->next_index == 0) {
00846     _next_index = temp.remap_indices(_next_index);
00847 
00848   } else {
00849     int next = temp.remap_indices(def->first_index);
00850     if (next != def->next_index) {
00851       interrogatedb_cat->error()
00852         << "Module database file " << def->database_filename
00853         << " is out of date.\n";
00854       return false;
00855     }
00856   }
00857 
00858   merge_from(temp);
00859   return true;
00860 }
00861 
00862 ////////////////////////////////////////////////////////////////////
00863 //     Function: InterrogateDatabase::load_latest
00864 //       Access: Private
00865 //  Description: Reads in the latest interrogate data.
00866 ////////////////////////////////////////////////////////////////////
00867 void InterrogateDatabase::
00868 load_latest() {
00869   const DSearchPath &searchpath = get_interrogatedb_path();
00870 
00871   Requests copy_requests;
00872   copy_requests.swap(_requests);
00873 
00874   Requests::const_iterator ri;
00875   for (ri = copy_requests.begin(); ri != copy_requests.end(); ++ri) {
00876     InterrogateModuleDef *def = (*ri);
00877 
00878     if (def->database_filename != (char *)NULL) {
00879       Filename filename = def->database_filename;
00880       Filename pathname = filename;
00881       if (!pathname.empty() && pathname[0] != '/') {
00882         pathname = searchpath.find_file(pathname);
00883       }
00884 
00885       if (pathname.empty()) {
00886         interrogatedb_cat->error()
00887           << "Unable to find " << filename << " on " << searchpath << "\n";
00888       } else {
00889 
00890         ifstream input;
00891         pathname.set_text();
00892         if (!pathname.open_read(input)) {
00893           interrogatedb_cat->error() << "Unable to read " << pathname << ".\n";
00894         } else {
00895           int file_identifier;
00896           input >> file_identifier
00897                 >> _file_major_version >> _file_minor_version;
00898 
00899           if (def->file_identifier != 0 &&
00900               file_identifier != def->file_identifier) {
00901             interrogatedb_cat->warning()
00902               << "Interrogate data in " << pathname
00903               << " is out of sync with the compiled-in data.\n";
00904           }
00905 
00906           if (_file_major_version != _current_major_version ||
00907               _file_minor_version > _current_minor_version) {
00908             interrogatedb_cat->error()
00909               << "Cannot read interrogate data in " << pathname
00910               << "; database is version " << _file_major_version << "."
00911               << _file_minor_version << " while we are expecting "
00912               << _current_major_version << "." << _current_minor_version
00913               << ".\n";
00914           } else {
00915             if (interrogatedb_cat->is_debug()) {
00916               interrogatedb_cat->debug()
00917                 << "Reading " << filename << "\n";
00918             }
00919             if (!read(input, def)) {
00920               interrogatedb_cat->error()
00921                 << "Error reading " << pathname << ".\n";
00922             }
00923           }
00924         }
00925       }
00926     }
00927   }
00928 
00929   _requests.clear();
00930 }
00931 
00932 ////////////////////////////////////////////////////////////////////
00933 //     Function: InterrogateDatabase::read_new
00934 //       Access: Private
00935 //  Description: Reads from the indicated stream (the header
00936 //               information has already been read) into the
00937 //               newly-created database.  It is an error if the
00938 //               database already has some data in it.
00939 ////////////////////////////////////////////////////////////////////
00940 bool InterrogateDatabase::
00941 read_new(istream &in, InterrogateModuleDef *def) {
00942   // We've already read the header.  Read the module definition.
00943   idf_input_string(in, def->library_name);
00944   idf_input_string(in, def->library_hash_name);
00945   idf_input_string(in, def->module_name);
00946 
00947   // Now read all of the components.
00948 
00949   { // Functions.
00950     int num_functions;
00951     in >> num_functions;
00952     if (in.fail()) {
00953       return false;
00954     }
00955 
00956     while (num_functions > 0) {
00957       FunctionIndex index;
00958       InterrogateFunction *function = new InterrogateFunction(def);
00959       in >> index >> *function;
00960       if (in.fail()) {
00961         delete function;
00962         return false;
00963       }
00964 
00965       add_function(index, function);
00966       num_functions--;
00967     }
00968   }
00969 
00970   { // Wrappers.
00971     int num_wrappers;
00972     in >> num_wrappers;
00973     if (in.fail()) {
00974       return false;
00975     }
00976 
00977     while (num_wrappers > 0) {
00978       FunctionWrapperIndex index;
00979       InterrogateFunctionWrapper wrapper(def);
00980       in >> index >> wrapper;
00981       if (in.fail()) {
00982         return false;
00983       }
00984 
00985       add_wrapper(index, wrapper);
00986       num_wrappers--;
00987     }
00988   }
00989 
00990   { // Types.
00991     int num_types;
00992     in >> num_types;
00993     if (in.fail()) {
00994       return false;
00995     }
00996 
00997     while (num_types > 0) {
00998       TypeIndex index;
00999       InterrogateType type(def);
01000       in >> index >> type;
01001       if (in.fail()) {
01002         return false;
01003       }
01004 
01005       add_type(index, type);
01006       num_types--;
01007     }
01008   }
01009 
01010   { // Manifests.
01011     int num_manifests;
01012     in >> num_manifests;
01013     if (in.fail()) {
01014       return false;
01015     }
01016 
01017     while (num_manifests > 0) {
01018       ManifestIndex index;
01019       InterrogateManifest manifest(def);
01020       in >> index >> manifest;
01021       if (in.fail()) {
01022         return false;
01023       }
01024 
01025       add_manifest(index, manifest);
01026       num_manifests--;
01027     }
01028   }
01029 
01030   { // Elements.
01031     int num_elements;
01032     in >> num_elements;
01033     if (in.fail()) {
01034       return false;
01035     }
01036 
01037     while (num_elements > 0) {
01038       ElementIndex index;
01039       InterrogateElement element(def);
01040       in >> index >> element;
01041       if (in.fail()) {
01042         return false;
01043       }
01044 
01045       add_element(index, element);
01046       num_elements--;
01047     }
01048   }
01049 
01050   return true;
01051 }
01052 
01053 ////////////////////////////////////////////////////////////////////
01054 //     Function: InterrogateDatabase::merge_from
01055 //       Access: Private
01056 //  Description: Copies all the data from the indicated database into
01057 //               this one.  It is an error if any index numbers are
01058 //               shared between the two databases.
01059 ////////////////////////////////////////////////////////////////////
01060 void InterrogateDatabase::
01061 merge_from(const InterrogateDatabase &other) {
01062   // We want to collapse shared types together.
01063   IndexRemapper remap;
01064 
01065   // First, we need to build a set of types by name, so we know what
01066   // types we already have.
01067   map<string, TypeIndex> types_by_name;
01068 
01069   TypeMap::const_iterator ti;
01070   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01071     const InterrogateType &type = (*ti).second;
01072     if (type.has_true_name()) {
01073       types_by_name[type.get_true_name()] = (*ti).first;
01074     }
01075   }
01076 
01077   // Now go through the other set of types and determine the mapping
01078   // into this set.
01079   for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
01080     TypeIndex other_type_index = (*ti).first;
01081     const InterrogateType &other_type = (*ti).second;
01082 
01083     if (other_type.has_name()) {
01084       map<string, TypeIndex>::iterator ni;
01085       ni = types_by_name.find(other_type.get_true_name());
01086       if (ni != types_by_name.end()) {
01087         // Here's a type that we seem to have in common!  We'll have
01088         // to merge them.
01089         TypeIndex this_type_index = (*ni).second;
01090         remap.add_mapping(other_type_index, this_type_index);
01091       }
01092     }
01093   }
01094 
01095   // Now that we know the full type-to-type mapping, we can copy the
01096   // new types, one at a time.
01097   for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
01098     TypeIndex other_type_index = (*ti).first;
01099     const InterrogateType &other_type = (*ti).second;
01100 
01101     if (!remap.in_map(other_type_index)) {
01102       // Here's a new type.
01103       add_type(other_type_index, other_type);
01104       update_type(other_type_index).remap_indices(remap);
01105 
01106     } else {
01107       // Here's a type to merge.
01108       TypeIndex this_type_index = remap.map_from(other_type_index);
01109 
01110       InterrogateType &this_type = update_type(this_type_index);
01111       if (!this_type.is_global() && other_type.is_global()) {
01112         // If the type is about to become global, we need to add it
01113         // to our global_types list.
01114         _global_types.push_back(this_type_index);
01115       }
01116 
01117       InterrogateType merge_type = other_type;
01118       merge_type.remap_indices(remap);
01119       this_type.merge_with(merge_type);
01120     }
01121   }
01122 
01123   // And copy all of the functions, wrappers, manifests, and elements.
01124   FunctionMap::const_iterator fi;
01125   for (fi = other._function_map.begin();
01126        fi != other._function_map.end();
01127        ++fi) {
01128     FunctionIndex other_function_index = (*fi).first;
01129     InterrogateFunction *other_function = (*fi).second;
01130     add_function(other_function_index, other_function);
01131     update_function(other_function_index).remap_indices(remap);
01132   }
01133 
01134   FunctionWrapperMap::const_iterator wi;
01135   for (wi = other._wrapper_map.begin();
01136        wi != other._wrapper_map.end();
01137        ++wi) {
01138     FunctionWrapperIndex other_wrapper_index = (*wi).first;
01139     const InterrogateFunctionWrapper &other_wrapper = (*wi).second;
01140     add_wrapper(other_wrapper_index, other_wrapper);
01141     update_wrapper(other_wrapper_index).remap_indices(remap);
01142   }
01143 
01144   ManifestMap::const_iterator mi;
01145   for (mi = other._manifest_map.begin();
01146        mi != other._manifest_map.end();
01147        ++mi) {
01148     ManifestIndex other_manifest_index = (*mi).first;
01149     const InterrogateManifest &other_manifest = (*mi).second;
01150     add_manifest(other_manifest_index, other_manifest);
01151     update_manifest(other_manifest_index).remap_indices(remap);
01152   }
01153 
01154   ElementMap::const_iterator ei;
01155   for (ei = other._element_map.begin();
01156        ei != other._element_map.end();
01157        ++ei) {
01158     ElementIndex other_element_index = (*ei).first;
01159     const InterrogateElement &other_element = (*ei).second;
01160     add_element(other_element_index, other_element);
01161     update_element(other_element_index).remap_indices(remap);
01162   }
01163 
01164   _lookups_fresh = 0;
01165 }
01166 
01167 ////////////////////////////////////////////////////////////////////
01168 //     Function: InterrogateDatabase::find_module
01169 //       Access: Private
01170 //  Description: Looks up the wrapper definition in the set of module
01171 //               defs that are loaded in at runtime and represent the
01172 //               part of the interrogate database that's compiled in.
01173 //
01174 //               If the wrapper definition is not found, returns
01175 //               false.  If it is found, returns true and sets def and
01176 //               module_index to the particular module and the index
01177 //               within the module where the wrapper is defined.
01178 ////////////////////////////////////////////////////////////////////
01179 bool InterrogateDatabase::
01180 find_module(FunctionWrapperIndex wrapper, InterrogateModuleDef *&def,
01181             int &module_index) {
01182   if (_modules.empty()) {
01183     return false;
01184   }
01185 
01186   int mi = binary_search_module(0, _modules.size(), wrapper);
01187   assert(mi >= 0 && mi < (int)_modules.size());
01188   def = _modules[mi];
01189   module_index = wrapper - def->first_index;
01190 
01191   return (wrapper < def->next_index);
01192 }
01193 
01194 ////////////////////////////////////////////////////////////////////
01195 //     Function: InterrogateDatabase::binary_search_module
01196 //       Access: Private
01197 //  Description: Searches for the function module that includes the
01198 //               given function index by binary search.
01199 ////////////////////////////////////////////////////////////////////
01200 int InterrogateDatabase::
01201 binary_search_module(int begin, int end, FunctionIndex function) {
01202   int mid = begin + (end - begin) / 2;
01203   if (mid == begin) {
01204     return mid;
01205   }
01206 
01207   int index = _modules[mid]->first_index;
01208   if (index <= function) {
01209     return binary_search_module(mid, end, function);
01210 
01211   } else {
01212     return binary_search_module(begin, mid, function);
01213   }
01214 }
01215 
01216 ////////////////////////////////////////////////////////////////////
01217 //     Function: InterrogateDatabase::binary_search_wrapper_hash
01218 //       Access: Private
01219 //  Description: Searches for the particular function wrapper's hash
01220 //               name within a given module.  Returns the index number
01221 //               local to the module, or -1 if it is not found.
01222 ////////////////////////////////////////////////////////////////////
01223 int InterrogateDatabase::
01224 binary_search_wrapper_hash(InterrogateUniqueNameDef *begin,
01225                            InterrogateUniqueNameDef *end,
01226                            const string &wrapper_hash_name) {
01227   if (end <= begin) {
01228     return -1;
01229   }
01230 
01231   InterrogateUniqueNameDef *mid = begin + (end - begin) / 2;
01232   string name = mid->name;
01233   if (name < wrapper_hash_name) {
01234     return binary_search_wrapper_hash(mid, end, wrapper_hash_name);
01235 
01236   } else if (wrapper_hash_name < name) {
01237     return binary_search_wrapper_hash(begin, mid, wrapper_hash_name);
01238 
01239   } else {
01240     return mid->index_offset;
01241   }
01242 }
01243 
01244 ////////////////////////////////////////////////////////////////////
01245 //     Function: InterrogateDatabase::freshen_types_by_name
01246 //       Access: Private
01247 //  Description: Builds up the lookup of types by name.
01248 ////////////////////////////////////////////////////////////////////
01249 void InterrogateDatabase::
01250 freshen_types_by_name() {
01251   _types_by_name.clear();
01252   TypeMap::const_iterator ti;
01253   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01254     _types_by_name[(*ti).second.get_name()] = (*ti).first;
01255   }
01256 }
01257 
01258 ////////////////////////////////////////////////////////////////////
01259 //     Function: InterrogateDatabase::freshen_types_by_scoped_name
01260 //       Access: Private
01261 //  Description: Builds up the lookup of types by scoped name.
01262 ////////////////////////////////////////////////////////////////////
01263 void InterrogateDatabase::
01264 freshen_types_by_scoped_name() {
01265   _types_by_scoped_name.clear();
01266   TypeMap::const_iterator ti;
01267   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01268     _types_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
01269   }
01270 }
01271 
01272 ////////////////////////////////////////////////////////////////////
01273 //     Function: InterrogateDatabase::freshen_types_by_true_name
01274 //       Access: Private
01275 //  Description: Builds up the lookup of types by true name.
01276 ////////////////////////////////////////////////////////////////////
01277 void InterrogateDatabase::
01278 freshen_types_by_true_name() {
01279   _types_by_true_name.clear();
01280   TypeMap::const_iterator ti;
01281   for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01282     _types_by_true_name[(*ti).second.get_true_name()] = (*ti).first;
01283   }
01284 }
01285 
01286 ////////////////////////////////////////////////////////////////////
01287 //     Function: InterrogateDatabase::freshen_manifests_by_name
01288 //       Access: Private
01289 //  Description: Builds up the lookup of manifests by name.
01290 ////////////////////////////////////////////////////////////////////
01291 void InterrogateDatabase::
01292 freshen_manifests_by_name() {
01293   _manifests_by_name.clear();
01294   ManifestMap::const_iterator ti;
01295   for (ti = _manifest_map.begin(); ti != _manifest_map.end(); ++ti) {
01296     _manifests_by_name[(*ti).second.get_name()] = (*ti).first;
01297   }
01298 }
01299 
01300 ////////////////////////////////////////////////////////////////////
01301 //     Function: InterrogateDatabase::freshen_elements_by_name
01302 //       Access: Private
01303 //  Description: Builds up the lookup of elements by name.
01304 ////////////////////////////////////////////////////////////////////
01305 void InterrogateDatabase::
01306 freshen_elements_by_name() {
01307   _elements_by_name.clear();
01308   ElementMap::const_iterator ti;
01309   for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
01310     _elements_by_name[(*ti).second.get_name()] = (*ti).first;
01311   }
01312 }
01313 
01314 ////////////////////////////////////////////////////////////////////
01315 //     Function: InterrogateDatabase::freshen_elements_by_scoped_name
01316 //       Access: Private
01317 //  Description: Builds up the lookup of elements by scoped name.
01318 ////////////////////////////////////////////////////////////////////
01319 void InterrogateDatabase::
01320 freshen_elements_by_scoped_name() {
01321   _elements_by_scoped_name.clear();
01322   ElementMap::const_iterator ti;
01323   for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
01324     _elements_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
01325   }
01326 }
01327 
01328 ////////////////////////////////////////////////////////////////////
01329 //     Function: InterrogateDatabase::lookup
01330 //       Access: Private
01331 //  Description: Looks up a type, manifest, or element in the
01332 //               indicated lookup table by name.  This is an internal
01333 //               support function.
01334 ////////////////////////////////////////////////////////////////////
01335 int InterrogateDatabase::
01336 lookup(const string &name, Lookup &lookup, LookupType type,
01337        void (InterrogateDatabase::*freshen)()) {
01338   if ((_lookups_fresh & (int)type) == 0) {
01339     // The lookup table isn't fresh; we need to freshen it.
01340     (this->*freshen)();
01341     _lookups_fresh |= (int)type;
01342   }
01343 
01344   Lookup::const_iterator li;
01345   li = lookup.find(name);
01346   if (li != lookup.end()) {
01347     return (*li).second;
01348   }
01349   return 0;
01350 }

Generated on Thu May 1 22:13:06 2003 for DTool by doxygen1.3