interrogateDatabase.cxx 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385
  1. // Filename: interrogateDatabase.cxx
  2. // Created by: drose (01Aug00)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "interrogateDatabase.h"
  19. #include "config_interrogatedb.h"
  20. #include "indexRemapper.h"
  21. #include "interrogate_datafile.h"
  22. InterrogateDatabase *InterrogateDatabase::_global_ptr = NULL;
  23. int InterrogateDatabase::_file_major_version = 0;
  24. int InterrogateDatabase::_file_minor_version = 0;
  25. int InterrogateDatabase::_current_major_version = 2;
  26. int InterrogateDatabase::_current_minor_version = 2;
  27. ////////////////////////////////////////////////////////////////////
  28. // Function: InterrogateDatabase::Constructor
  29. // Access: Private
  30. // Description:
  31. ////////////////////////////////////////////////////////////////////
  32. InterrogateDatabase::
  33. InterrogateDatabase() {
  34. _error_flag = false;
  35. _next_index = 1;
  36. _lookups_fresh = 0;
  37. }
  38. ////////////////////////////////////////////////////////////////////
  39. // Function: InterrogateDatabase::get_ptr
  40. // Access: Private
  41. // Description: Returns the global pointer to the one
  42. // InterrogateDatabase.
  43. ////////////////////////////////////////////////////////////////////
  44. InterrogateDatabase *InterrogateDatabase::
  45. get_ptr() {
  46. if (_global_ptr == (InterrogateDatabase *)NULL) {
  47. if (interrogatedb_cat->is_debug()) {
  48. interrogatedb_cat->debug()
  49. << "Creating interrogate database\n";
  50. }
  51. _global_ptr = new InterrogateDatabase;
  52. }
  53. return _global_ptr;
  54. }
  55. ////////////////////////////////////////////////////////////////////
  56. // Function: InterrogateDatabase::request_module
  57. // Access: Public
  58. // Description: Requests that the interrogate data for the given
  59. // module be made available. The function pointers will
  60. // be made available immediately, while the database
  61. // file will be read later, the next time someone asks
  62. // for interrogate data that requires it.
  63. ////////////////////////////////////////////////////////////////////
  64. void InterrogateDatabase::
  65. request_module(InterrogateModuleDef *def) {
  66. if (interrogatedb_cat->is_debug()) {
  67. if (def->library_name == (const char *)NULL) {
  68. interrogatedb_cat->debug()
  69. << "Got interrogate data for anonymous module\n";
  70. } else {
  71. interrogatedb_cat->debug()
  72. << "Got interrogate data for module " << def->library_name << "\n";
  73. }
  74. }
  75. int num_indices = def->next_index - def->first_index;
  76. if (num_indices > 0) {
  77. // If the module def has any definitions--any index numbers
  78. // used--assign it to its own unique range of index numbers.
  79. def->first_index = _next_index;
  80. _next_index += num_indices;
  81. def->next_index = _next_index;
  82. // Assign a reference to the module def by index number. When we
  83. // need to look up a function by its index number, we'll be able
  84. // to use this.
  85. _modules.push_back(def);
  86. }
  87. if (def->num_unique_names > 0 && def->library_name != (const char *)NULL) {
  88. // Define a lookup by hash for this module, mainly so we can look
  89. // up functions by their unique names.
  90. _modules_by_hash[def->library_hash_name] = def;
  91. }
  92. if (def->database_filename != (const char *)NULL) {
  93. _requests.push_back(def);
  94. }
  95. }
  96. ////////////////////////////////////////////////////////////////////
  97. // Function: InterrogateDatabase::get_error_flag
  98. // Access: Public
  99. // Description: Returns the global error flag. This will be set true
  100. // if there was some problem importing the database
  101. // (e.g. cannot find an .in file), or false if
  102. // everything is ok.
  103. ////////////////////////////////////////////////////////////////////
  104. bool InterrogateDatabase::
  105. get_error_flag() {
  106. return _error_flag;
  107. }
  108. ////////////////////////////////////////////////////////////////////
  109. // Function: InterrogateDatabase::get_num_global_types
  110. // Access: Public
  111. // Description: Returns the total number of "global" types known to
  112. // the interrogate database. These are types defined at
  113. // the global level that should be considered for
  114. // exporting, but not the incidental types (like
  115. // pointers, etc.) that must be defined to support
  116. // these.
  117. ////////////////////////////////////////////////////////////////////
  118. int InterrogateDatabase::
  119. get_num_global_types() {
  120. check_latest();
  121. return _global_types.size();
  122. }
  123. ////////////////////////////////////////////////////////////////////
  124. // Function: InterrogateDatabase::get_global_type
  125. // Access: Public
  126. // Description: Returns the index of the nth global type known to the
  127. // interrogate database.
  128. ////////////////////////////////////////////////////////////////////
  129. TypeIndex InterrogateDatabase::
  130. get_global_type(int n) {
  131. check_latest();
  132. if (n >= 0 && n < (int)_global_types.size()) {
  133. return _global_types[n];
  134. }
  135. return 0;
  136. }
  137. ////////////////////////////////////////////////////////////////////
  138. // Function: InterrogateDatabase::get_num_all_types
  139. // Access: Public
  140. // Description: Returns the total number of types known to the
  141. // interrogate database. This includes all known types,
  142. // global as well as incidental. See also
  143. // get_num_global_types().
  144. ////////////////////////////////////////////////////////////////////
  145. int InterrogateDatabase::
  146. get_num_all_types() {
  147. check_latest();
  148. return _all_types.size();
  149. }
  150. ////////////////////////////////////////////////////////////////////
  151. // Function: InterrogateDatabase::get_all_type
  152. // Access: Public
  153. // Description: Returns the index of the nth type known to the
  154. // interrogate database.
  155. ////////////////////////////////////////////////////////////////////
  156. TypeIndex InterrogateDatabase::
  157. get_all_type(int n) {
  158. check_latest();
  159. if (n >= 0 && n < (int)_all_types.size()) {
  160. return _all_types[n];
  161. }
  162. return 0;
  163. }
  164. ////////////////////////////////////////////////////////////////////
  165. // Function: InterrogateDatabase::get_num_global_functions
  166. // Access: Public
  167. // Description: Returns the total number of global functions known to
  168. // the interrogate database. These are functions
  169. // defined at the global level, e.g. non-member
  170. // functions.
  171. ////////////////////////////////////////////////////////////////////
  172. int InterrogateDatabase::
  173. get_num_global_functions() {
  174. check_latest();
  175. return _global_functions.size();
  176. }
  177. ////////////////////////////////////////////////////////////////////
  178. // Function: InterrogateDatabase::get_global_function
  179. // Access: Public
  180. // Description: Returns the index of the nth global function known to
  181. // the interrogate database.
  182. ////////////////////////////////////////////////////////////////////
  183. FunctionIndex InterrogateDatabase::
  184. get_global_function(int n) {
  185. check_latest();
  186. if (n >= 0 && n < (int)_global_functions.size()) {
  187. return _global_functions[n];
  188. }
  189. return 0;
  190. }
  191. ////////////////////////////////////////////////////////////////////
  192. // Function: InterrogateDatabase::get_num_all_functions
  193. // Access: Public
  194. // Description: Returns the total number of functions known to the
  195. // interrogate database. This includes all known
  196. // functions, global, method, or synthesized. See also
  197. // get_num_global_functions().
  198. ////////////////////////////////////////////////////////////////////
  199. int InterrogateDatabase::
  200. get_num_all_functions() {
  201. check_latest();
  202. return _all_functions.size();
  203. }
  204. ////////////////////////////////////////////////////////////////////
  205. // Function: InterrogateDatabase::get_all_function
  206. // Access: Public
  207. // Description: Returns the index of the nth function known to the
  208. // interrogate database.
  209. ////////////////////////////////////////////////////////////////////
  210. FunctionIndex InterrogateDatabase::
  211. get_all_function(int n) {
  212. check_latest();
  213. if (n >= 0 && n < (int)_all_functions.size()) {
  214. return _all_functions[n];
  215. }
  216. return 0;
  217. }
  218. ////////////////////////////////////////////////////////////////////
  219. // Function: InterrogateDatabase::get_num_global_manifests
  220. // Access: Public
  221. // Description: Returns the total number of global manifest constants
  222. // known to the interrogate database.
  223. ////////////////////////////////////////////////////////////////////
  224. int InterrogateDatabase::
  225. get_num_global_manifests() {
  226. check_latest();
  227. return _global_manifests.size();
  228. }
  229. ////////////////////////////////////////////////////////////////////
  230. // Function: InterrogateDatabase::get_global_manifest
  231. // Access: Public
  232. // Description: Returns the index of the nth global manifest constant
  233. // known to the interrogate database.
  234. ////////////////////////////////////////////////////////////////////
  235. ManifestIndex InterrogateDatabase::
  236. get_global_manifest(int n) {
  237. check_latest();
  238. if (n >= 0 && n < (int)_global_manifests.size()) {
  239. return _global_manifests[n];
  240. }
  241. return 0;
  242. }
  243. ////////////////////////////////////////////////////////////////////
  244. // Function: InterrogateDatabase::get_num_global_elements
  245. // Access: Public
  246. // Description: Returns the total number of global data elements
  247. // known to the interrogate database.
  248. ////////////////////////////////////////////////////////////////////
  249. int InterrogateDatabase::
  250. get_num_global_elements() {
  251. check_latest();
  252. return _global_elements.size();
  253. }
  254. ////////////////////////////////////////////////////////////////////
  255. // Function: InterrogateDatabase::get_global_element
  256. // Access: Public
  257. // Description: Returns the index of the nth global data element
  258. // known to the interrogate database.
  259. ////////////////////////////////////////////////////////////////////
  260. ElementIndex InterrogateDatabase::
  261. get_global_element(int n) {
  262. check_latest();
  263. if (n >= 0 && n < (int)_global_elements.size()) {
  264. return _global_elements[n];
  265. }
  266. return 0;
  267. }
  268. ////////////////////////////////////////////////////////////////////
  269. // Function: InterrogateDatabase::get_type
  270. // Access: Public
  271. // Description: Returns the type associated with the given TypeIndex,
  272. // if there is one.
  273. ////////////////////////////////////////////////////////////////////
  274. const InterrogateType &InterrogateDatabase::
  275. get_type(TypeIndex type) {
  276. static InterrogateType bogus_type;
  277. check_latest();
  278. TypeMap::const_iterator ti;
  279. ti = _type_map.find(type);
  280. if (ti == _type_map.end()) {
  281. return bogus_type;
  282. }
  283. return (*ti).second;
  284. }
  285. ////////////////////////////////////////////////////////////////////
  286. // Function: InterrogateDatabase::get_function
  287. // Access: Public
  288. // Description: Returns the function associated with the given
  289. // FunctionIndex, if there is one.
  290. ////////////////////////////////////////////////////////////////////
  291. const InterrogateFunction &InterrogateDatabase::
  292. get_function(FunctionIndex function) {
  293. static InterrogateFunction bogus_function;
  294. check_latest();
  295. FunctionMap::const_iterator fi;
  296. fi = _function_map.find(function);
  297. if (fi == _function_map.end()) {
  298. return bogus_function;
  299. }
  300. return *(*fi).second;
  301. }
  302. ////////////////////////////////////////////////////////////////////
  303. // Function: InterrogateDatabase::get_wrapper
  304. // Access: Public
  305. // Description: Returns the function wrapper associated with the
  306. // given FunctionWrapperIndex, if there is one.
  307. ////////////////////////////////////////////////////////////////////
  308. const InterrogateFunctionWrapper &InterrogateDatabase::
  309. get_wrapper(FunctionWrapperIndex wrapper) {
  310. static InterrogateFunctionWrapper bogus_wrapper;
  311. check_latest();
  312. FunctionWrapperMap::const_iterator wi;
  313. wi = _wrapper_map.find(wrapper);
  314. if (wi == _wrapper_map.end()) {
  315. return bogus_wrapper;
  316. }
  317. return (*wi).second;
  318. }
  319. ////////////////////////////////////////////////////////////////////
  320. // Function: InterrogateDatabase::get_manifest
  321. // Access: Public
  322. // Description: Returns the manifest constant associated with the
  323. // given ManifestIndex, if there is one.
  324. ////////////////////////////////////////////////////////////////////
  325. const InterrogateManifest &InterrogateDatabase::
  326. get_manifest(ManifestIndex manifest) {
  327. static InterrogateManifest bogus_manifest;
  328. check_latest();
  329. ManifestMap::const_iterator mi;
  330. mi = _manifest_map.find(manifest);
  331. if (mi == _manifest_map.end()) {
  332. return bogus_manifest;
  333. }
  334. return (*mi).second;
  335. }
  336. ////////////////////////////////////////////////////////////////////
  337. // Function: InterrogateDatabase::get_element
  338. // Access: Public
  339. // Description: Returns the data element associated with the
  340. // given ElementIndex, if there is one.
  341. ////////////////////////////////////////////////////////////////////
  342. const InterrogateElement &InterrogateDatabase::
  343. get_element(ElementIndex element) {
  344. static InterrogateElement bogus_element;
  345. check_latest();
  346. ElementMap::const_iterator ei;
  347. ei = _element_map.find(element);
  348. if (ei == _element_map.end()) {
  349. return bogus_element;
  350. }
  351. return (*ei).second;
  352. }
  353. ////////////////////////////////////////////////////////////////////
  354. // Function: InterrogateDatabase::remove_type
  355. // Access: Public
  356. // Description: Erases the type from the database.
  357. ////////////////////////////////////////////////////////////////////
  358. void InterrogateDatabase::
  359. remove_type(TypeIndex type) {
  360. _type_map.erase(type);
  361. }
  362. ////////////////////////////////////////////////////////////////////
  363. // Function: InterrogateDatabase::get_fptr
  364. // Access: Public
  365. // Description: Returns the function pointer associated with the
  366. // given function wrapper, if it has a pointer
  367. // available. Returns NULL if the pointer is not
  368. // available.
  369. ////////////////////////////////////////////////////////////////////
  370. void *InterrogateDatabase::
  371. get_fptr(FunctionWrapperIndex wrapper) {
  372. InterrogateModuleDef *def;
  373. int module_index;
  374. if (find_module(wrapper, def, module_index)) {
  375. if (module_index >= 0 && module_index < def->num_fptrs) {
  376. return def->fptrs[module_index];
  377. }
  378. }
  379. return (void *)NULL;
  380. }
  381. ////////////////////////////////////////////////////////////////////
  382. // Function: InterrogateDatabase::get_wrapper_by_unique_name
  383. // Access: Public
  384. // Description: Looks up the function wrapper corresponding to the
  385. // given unique name, if available. Returns the
  386. // corresponding wrapper index, or 0 if no such
  387. // wrapper is found.
  388. ////////////////////////////////////////////////////////////////////
  389. FunctionWrapperIndex InterrogateDatabase::
  390. get_wrapper_by_unique_name(const string &unique_name) {
  391. // First, split the unique_name into a library_hash_name and a
  392. // wrapper_hash_name.
  393. // The first four characters are always the library_name.
  394. string library_hash_name = unique_name.substr(0, 4);
  395. string wrapper_hash_name = unique_name.substr(4);
  396. // Is the library_name defined?
  397. ModulesByHash::const_iterator mi;
  398. mi = _modules_by_hash.find(library_hash_name);
  399. if (mi == _modules_by_hash.end()) {
  400. return 0;
  401. }
  402. InterrogateModuleDef *def = (*mi).second;
  403. int index_offset =
  404. binary_search_wrapper_hash(def->unique_names,
  405. def->unique_names + def->num_unique_names,
  406. wrapper_hash_name);
  407. if (index_offset >= 0) {
  408. return def->first_index + index_offset;
  409. }
  410. return 0;
  411. }
  412. ////////////////////////////////////////////////////////////////////
  413. // Function: InterrogateDatabase::get_file_major_version
  414. // Access: Public
  415. // Description: Returns the major version number of the interrogate
  416. // database file currently being read.
  417. ////////////////////////////////////////////////////////////////////
  418. int InterrogateDatabase::
  419. get_file_major_version() {
  420. return _file_major_version;
  421. }
  422. ////////////////////////////////////////////////////////////////////
  423. // Function: InterrogateDatabase::get_file_minor_version
  424. // Access: Public
  425. // Description: Returns the minor version number of the interrogate
  426. // database file currently being read.
  427. ////////////////////////////////////////////////////////////////////
  428. int InterrogateDatabase::
  429. get_file_minor_version() {
  430. return _file_minor_version;
  431. }
  432. ////////////////////////////////////////////////////////////////////
  433. // Function: InterrogateDatabase::get_current_major_version
  434. // Access: Public
  435. // Description: Returns the major version number currently expected
  436. // in interrogate database files generated by this code
  437. // base.
  438. ////////////////////////////////////////////////////////////////////
  439. int InterrogateDatabase::
  440. get_current_major_version() {
  441. return _current_major_version;
  442. }
  443. ////////////////////////////////////////////////////////////////////
  444. // Function: InterrogateDatabase::get_current_minor_version
  445. // Access: Public
  446. // Description: Returns the minor version number currently expected
  447. // in interrogate database files generated by this code
  448. // base.
  449. ////////////////////////////////////////////////////////////////////
  450. int InterrogateDatabase::
  451. get_current_minor_version() {
  452. return _current_minor_version;
  453. }
  454. ////////////////////////////////////////////////////////////////////
  455. // Function: InterrogateDatabase::set_error_flag
  456. // Access: Public
  457. // Description: Sets the global error flag. This should be set true
  458. // if there was some problem importing the database
  459. // (e.g. cannot find an .in file).
  460. ////////////////////////////////////////////////////////////////////
  461. void InterrogateDatabase::
  462. set_error_flag(bool error_flag) {
  463. _error_flag = error_flag;
  464. }
  465. ////////////////////////////////////////////////////////////////////
  466. // Function: InterrogateDatabase::get_next_index
  467. // Access: Public
  468. // Description: Returns a new index number suitable for the next
  469. // thing, that will not be shared with any other index
  470. // numbers.
  471. ////////////////////////////////////////////////////////////////////
  472. int InterrogateDatabase::
  473. get_next_index() {
  474. return _next_index++;
  475. }
  476. ////////////////////////////////////////////////////////////////////
  477. // Function: InterrogateDatabase::add_type
  478. // Access: Public
  479. // Description: Adds the indicated type to the database at the given
  480. // index number.
  481. ////////////////////////////////////////////////////////////////////
  482. void InterrogateDatabase::
  483. add_type(TypeIndex index, const InterrogateType &type) {
  484. assert(index != 0);
  485. bool inserted =
  486. _type_map.insert(TypeMap::value_type(index, type)).second;
  487. if (!inserted) {
  488. // If there was already a type at that index, maybe it was a
  489. // forward reference. If its _fully_defined bit isn't set, then
  490. // it's ok.
  491. InterrogateType &old_type = _type_map[index];
  492. assert(!old_type.is_fully_defined());
  493. // It was a forward reference. Merge it with the new one.
  494. old_type.merge_with(type);
  495. }
  496. if (type.is_global()) {
  497. _global_types.push_back(index);
  498. }
  499. _all_types.push_back(index);
  500. }
  501. ////////////////////////////////////////////////////////////////////
  502. // Function: InterrogateDatabase::add_function
  503. // Access: Public
  504. // Description: Adds the indicated function to the database at
  505. // the given index number.
  506. ////////////////////////////////////////////////////////////////////
  507. void InterrogateDatabase::
  508. add_function(FunctionIndex index, InterrogateFunction *function) {
  509. bool inserted =
  510. _function_map.insert(FunctionMap::value_type(index, function)).second;
  511. assert(inserted);
  512. if (function->is_global()) {
  513. _global_functions.push_back(index);
  514. }
  515. _all_functions.push_back(index);
  516. }
  517. ////////////////////////////////////////////////////////////////////
  518. // Function: InterrogateDatabase::add_wrapper
  519. // Access: Public
  520. // Description: Adds the indicated function wrapper to the database at
  521. // the given index number.
  522. ////////////////////////////////////////////////////////////////////
  523. void InterrogateDatabase::
  524. add_wrapper(FunctionWrapperIndex index,
  525. const InterrogateFunctionWrapper &wrapper) {
  526. bool inserted =
  527. _wrapper_map.insert(FunctionWrapperMap::value_type(index, wrapper)).second;
  528. assert(inserted);
  529. }
  530. ////////////////////////////////////////////////////////////////////
  531. // Function: InterrogateDatabase::add_manifest
  532. // Access: Public
  533. // Description: Adds the indicated manifest constant to the database
  534. // at the given index number.
  535. ////////////////////////////////////////////////////////////////////
  536. void InterrogateDatabase::
  537. add_manifest(ManifestIndex index, const InterrogateManifest &manifest) {
  538. bool inserted =
  539. _manifest_map.insert(ManifestMap::value_type(index, manifest)).second;
  540. assert(inserted);
  541. _global_manifests.push_back(index);
  542. }
  543. ////////////////////////////////////////////////////////////////////
  544. // Function: InterrogateDatabase::add_element
  545. // Access: Public
  546. // Description: Adds the indicated data element to the database
  547. // at the given index number.
  548. ////////////////////////////////////////////////////////////////////
  549. void InterrogateDatabase::
  550. add_element(ElementIndex index, const InterrogateElement &element) {
  551. bool inserted =
  552. _element_map.insert(ElementMap::value_type(index, element)).second;
  553. assert(inserted);
  554. if (element.is_global()) {
  555. _global_elements.push_back(index);
  556. }
  557. }
  558. ////////////////////////////////////////////////////////////////////
  559. // Function: InterrogateDatabase::update_type
  560. // Access: Public
  561. // Description: Returns a non-const reference to the indicated type,
  562. // allowing the user to update it.
  563. ////////////////////////////////////////////////////////////////////
  564. InterrogateType &InterrogateDatabase::
  565. update_type(TypeIndex type) {
  566. assert(type != 0);
  567. check_latest();
  568. return _type_map[type];
  569. }
  570. ////////////////////////////////////////////////////////////////////
  571. // Function: InterrogateDatabase::update_function
  572. // Access: Public
  573. // Description: Returns a non-const reference to the indicated
  574. // function, allowing the user to update it.
  575. ////////////////////////////////////////////////////////////////////
  576. InterrogateFunction &InterrogateDatabase::
  577. update_function(FunctionIndex function) {
  578. check_latest();
  579. return *_function_map[function];
  580. }
  581. ////////////////////////////////////////////////////////////////////
  582. // Function: InterrogateDatabase::update_wrapper
  583. // Access: Public
  584. // Description: Returns a non-const reference to the indicated
  585. // function wrapper, allowing the user to update it.
  586. ////////////////////////////////////////////////////////////////////
  587. InterrogateFunctionWrapper &InterrogateDatabase::
  588. update_wrapper(FunctionWrapperIndex wrapper) {
  589. check_latest();
  590. return _wrapper_map[wrapper];
  591. }
  592. ////////////////////////////////////////////////////////////////////
  593. // Function: InterrogateDatabase::update_manifest
  594. // Access: Public
  595. // Description: Returns a non-const reference to the indicated
  596. // manifest constant, allowing the user to update it.
  597. ////////////////////////////////////////////////////////////////////
  598. InterrogateManifest &InterrogateDatabase::
  599. update_manifest(ManifestIndex manifest) {
  600. check_latest();
  601. return _manifest_map[manifest];
  602. }
  603. ////////////////////////////////////////////////////////////////////
  604. // Function: InterrogateDatabase::update_element
  605. // Access: Public
  606. // Description: Returns a non-const reference to the indicated
  607. // data element, allowing the user to update it.
  608. ////////////////////////////////////////////////////////////////////
  609. InterrogateElement &InterrogateDatabase::
  610. update_element(ElementIndex element) {
  611. check_latest();
  612. return _element_map[element];
  613. }
  614. ////////////////////////////////////////////////////////////////////
  615. // Function: InterrogateDatabase::remap_indices
  616. // Access: Public
  617. // Description: Resequences all of the various index numbers so that
  618. // all of the functions start at first_index and
  619. // increment consecutively from there, and then all of
  620. // the types follow. Returns the next available index
  621. // number.
  622. ////////////////////////////////////////////////////////////////////
  623. int InterrogateDatabase::
  624. remap_indices(int first_index) {
  625. IndexRemapper remap;
  626. return remap_indices(first_index, remap);
  627. }
  628. ////////////////////////////////////////////////////////////////////
  629. // Function: InterrogateDatabase::remap_indices
  630. // Access: Public
  631. // Description: This flavor of remap_indices() accepts a map that
  632. // should be empty on initial call, and will be filled
  633. // with the mapping of old index number to new index
  634. // number. This allows the caller to update its own
  635. // data structures to match the new index numbers.
  636. ////////////////////////////////////////////////////////////////////
  637. int InterrogateDatabase::
  638. remap_indices(int first_index, IndexRemapper &remap) {
  639. remap.clear();
  640. // First, build up the complete map.
  641. // Get the wrapper indices first. This is important, because the
  642. // InterrogateBuilder wants these to be first, and consecutive.
  643. FunctionWrapperMap new_wrapper_map;
  644. FunctionWrapperMap::iterator wi;
  645. for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
  646. remap.add_mapping((*wi).first, first_index);
  647. new_wrapper_map[first_index] = (*wi).second;
  648. first_index++;
  649. }
  650. // Everything else can follow; it doesn't matter so much.
  651. FunctionMap new_function_map;
  652. FunctionMap::iterator fi;
  653. for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
  654. remap.add_mapping((*fi).first, first_index);
  655. new_function_map[first_index] = (*fi).second;
  656. first_index++;
  657. }
  658. TypeMap new_type_map;
  659. TypeMap::iterator ti;
  660. for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
  661. assert((*ti).first != 0);
  662. remap.add_mapping((*ti).first, first_index);
  663. new_type_map[first_index] = (*ti).second;
  664. first_index++;
  665. }
  666. ManifestMap new_manifest_map;
  667. ManifestMap::iterator mi;
  668. for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
  669. remap.add_mapping((*mi).first, first_index);
  670. new_manifest_map[first_index] = (*mi).second;
  671. first_index++;
  672. }
  673. ElementMap new_element_map;
  674. ElementMap::iterator ei;
  675. for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
  676. remap.add_mapping((*ei).first, first_index);
  677. new_element_map[first_index] = (*ei).second;
  678. first_index++;
  679. }
  680. _next_index = first_index;
  681. _wrapper_map.swap(new_wrapper_map);
  682. _function_map.swap(new_function_map);
  683. _type_map.swap(new_type_map);
  684. _manifest_map.swap(new_manifest_map);
  685. _element_map.swap(new_element_map);
  686. // Then, go back through and update all of the internal references.
  687. for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
  688. (*wi).second.remap_indices(remap);
  689. }
  690. for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
  691. (*fi).second->remap_indices(remap);
  692. }
  693. for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
  694. (*ti).second.remap_indices(remap);
  695. }
  696. for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
  697. (*mi).second.remap_indices(remap);
  698. }
  699. for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
  700. (*ei).second.remap_indices(remap);
  701. }
  702. GlobalFunctions::iterator gfi;
  703. for (gfi = _global_functions.begin(); gfi != _global_functions.end(); ++gfi) {
  704. (*gfi) = remap.map_from(*gfi);
  705. }
  706. for (gfi = _all_functions.begin(); gfi != _all_functions.end(); ++gfi) {
  707. (*gfi) = remap.map_from(*gfi);
  708. }
  709. GlobalTypes::iterator gti;
  710. for (gti = _global_types.begin(); gti != _global_types.end(); ++gti) {
  711. (*gti) = remap.map_from(*gti);
  712. }
  713. for (gti = _all_types.begin(); gti != _all_types.end(); ++gti) {
  714. (*gti) = remap.map_from(*gti);
  715. }
  716. GlobalManifests::iterator gmi;
  717. for (gmi = _global_manifests.begin(); gmi != _global_manifests.end(); ++gmi) {
  718. (*gmi) = remap.map_from(*gmi);
  719. }
  720. GlobalElements::iterator gei;
  721. for (gei = _global_elements.begin(); gei != _global_elements.end(); ++gei) {
  722. (*gei) = remap.map_from(*gei);
  723. }
  724. return _next_index;
  725. }
  726. ////////////////////////////////////////////////////////////////////
  727. // Function: InterrogateDatabase::write
  728. // Access: Public
  729. // Description: Writes the database to the indicated stream for later
  730. // reading.
  731. ////////////////////////////////////////////////////////////////////
  732. void InterrogateDatabase::
  733. write(ostream &out, InterrogateModuleDef *def) const {
  734. // Write out the file header.
  735. out << def->file_identifier << "\n"
  736. << _current_major_version << " " << _current_minor_version << "\n";
  737. // Write out the module definition.
  738. idf_output_string(out, def->library_name);
  739. idf_output_string(out, def->library_hash_name);
  740. idf_output_string(out, def->module_name);
  741. out << "\n";
  742. // Now write out the components.
  743. out << _function_map.size() << "\n";
  744. FunctionMap::const_iterator fi;
  745. for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
  746. out << (*fi).first << " " << *(*fi).second << "\n";
  747. }
  748. out << _wrapper_map.size() << "\n";
  749. FunctionWrapperMap::const_iterator wi;
  750. for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
  751. out << (*wi).first << " " << (*wi).second << "\n";
  752. }
  753. out << _type_map.size() << "\n";
  754. TypeMap::const_iterator ti;
  755. for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
  756. out << (*ti).first << " " << (*ti).second << "\n";
  757. }
  758. out << _manifest_map.size() << "\n";
  759. ManifestMap::const_iterator mi;
  760. for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
  761. out << (*mi).first << " " << (*mi).second << "\n";
  762. }
  763. out << _element_map.size() << "\n";
  764. ElementMap::const_iterator ei;
  765. for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
  766. out << (*ei).first << " " << (*ei).second << "\n";
  767. }
  768. }
  769. ////////////////////////////////////////////////////////////////////
  770. // Function: InterrogateDatabase::read
  771. // Access: Public
  772. // Description: Reads a database from the indicated stream,
  773. // associated with the indicated module definition and
  774. // merges it with any existing data in the database,
  775. // according to the expected index numbers specified in
  776. // the module def. The header information has already
  777. // been read.
  778. //
  779. // Returns true if the file is read successfully, false
  780. // if there is an error.
  781. ////////////////////////////////////////////////////////////////////
  782. bool InterrogateDatabase::
  783. read(istream &in, InterrogateModuleDef *def) {
  784. InterrogateDatabase temp;
  785. if (!temp.read_new(in, def)) {
  786. return false;
  787. }
  788. if (def->first_index == 0 && def->next_index == 0) {
  789. _next_index = temp.remap_indices(_next_index);
  790. } else {
  791. int next = temp.remap_indices(def->first_index);
  792. if (next != def->next_index) {
  793. interrogatedb_cat->error()
  794. << "Module database file " << def->database_filename
  795. << " is out of date.\n";
  796. return false;
  797. }
  798. }
  799. merge_from(temp);
  800. return true;
  801. }
  802. ////////////////////////////////////////////////////////////////////
  803. // Function: InterrogateDatabase::load_latest
  804. // Access: Private
  805. // Description: Reads in the latest interrogate data.
  806. ////////////////////////////////////////////////////////////////////
  807. void InterrogateDatabase::
  808. load_latest() {
  809. const DSearchPath &searchpath = interrogatedb_path;
  810. Requests copy_requests;
  811. copy_requests.swap(_requests);
  812. Requests::const_iterator ri;
  813. for (ri = copy_requests.begin(); ri != copy_requests.end(); ++ri) {
  814. InterrogateModuleDef *def = (*ri);
  815. if (def->database_filename != (char *)NULL) {
  816. Filename filename = def->database_filename;
  817. Filename pathname = filename;
  818. if (!pathname.empty() && pathname[0] != '/') {
  819. pathname = searchpath.find_file(pathname);
  820. }
  821. if (pathname.empty()) {
  822. interrogatedb_cat->error()
  823. << "Unable to find " << filename << " on " << searchpath << "\n";
  824. set_error_flag(true);
  825. } else {
  826. ifstream input;
  827. pathname.set_text();
  828. if (!pathname.open_read(input)) {
  829. interrogatedb_cat->error() << "Unable to read " << pathname << ".\n";
  830. set_error_flag(true);
  831. } else {
  832. int file_identifier;
  833. input >> file_identifier
  834. >> _file_major_version >> _file_minor_version;
  835. if (def->file_identifier != 0 &&
  836. file_identifier != def->file_identifier) {
  837. interrogatedb_cat->warning()
  838. << "Interrogate data in " << pathname
  839. << " is out of sync with the compiled-in data"
  840. << " (" << file_identifier << " != " << def->file_identifier << ").\n";
  841. set_error_flag(true);
  842. }
  843. if (_file_major_version != _current_major_version ||
  844. _file_minor_version > _current_minor_version) {
  845. interrogatedb_cat->error()
  846. << "Cannot read interrogate data in " << pathname
  847. << "; database is version " << _file_major_version << "."
  848. << _file_minor_version << " while we are expecting "
  849. << _current_major_version << "." << _current_minor_version
  850. << ".\n";
  851. set_error_flag(true);
  852. } else {
  853. if (interrogatedb_cat->is_debug()) {
  854. interrogatedb_cat->debug()
  855. << "Reading " << filename << "\n";
  856. }
  857. if (!read(input, def)) {
  858. interrogatedb_cat->error()
  859. << "Error reading " << pathname << ".\n";
  860. set_error_flag(true);
  861. }
  862. }
  863. }
  864. }
  865. }
  866. }
  867. _requests.clear();
  868. }
  869. ////////////////////////////////////////////////////////////////////
  870. // Function: InterrogateDatabase::read_new
  871. // Access: Private
  872. // Description: Reads from the indicated stream (the header
  873. // information has already been read) into the
  874. // newly-created database. It is an error if the
  875. // database already has some data in it.
  876. ////////////////////////////////////////////////////////////////////
  877. bool InterrogateDatabase::
  878. read_new(istream &in, InterrogateModuleDef *def) {
  879. // We've already read the header. Read the module definition.
  880. idf_input_string(in, def->library_name);
  881. idf_input_string(in, def->library_hash_name);
  882. idf_input_string(in, def->module_name);
  883. // Now read all of the components.
  884. { // Functions.
  885. int num_functions;
  886. in >> num_functions;
  887. if (in.fail()) {
  888. return false;
  889. }
  890. while (num_functions > 0) {
  891. FunctionIndex index;
  892. InterrogateFunction *function = new InterrogateFunction(def);
  893. in >> index >> *function;
  894. if (in.fail()) {
  895. delete function;
  896. return false;
  897. }
  898. add_function(index, function);
  899. num_functions--;
  900. }
  901. }
  902. { // Wrappers.
  903. int num_wrappers;
  904. in >> num_wrappers;
  905. if (in.fail()) {
  906. return false;
  907. }
  908. while (num_wrappers > 0) {
  909. FunctionWrapperIndex index;
  910. InterrogateFunctionWrapper wrapper(def);
  911. in >> index >> wrapper;
  912. if (in.fail()) {
  913. return false;
  914. }
  915. add_wrapper(index, wrapper);
  916. num_wrappers--;
  917. }
  918. }
  919. { // Types.
  920. int num_types;
  921. in >> num_types;
  922. if (in.fail()) {
  923. return false;
  924. }
  925. while (num_types > 0) {
  926. TypeIndex index;
  927. InterrogateType type(def);
  928. in >> index >> type;
  929. if (in.fail()) {
  930. return false;
  931. }
  932. add_type(index, type);
  933. num_types--;
  934. }
  935. }
  936. { // Manifests.
  937. int num_manifests;
  938. in >> num_manifests;
  939. if (in.fail()) {
  940. return false;
  941. }
  942. while (num_manifests > 0) {
  943. ManifestIndex index;
  944. InterrogateManifest manifest(def);
  945. in >> index >> manifest;
  946. if (in.fail()) {
  947. return false;
  948. }
  949. add_manifest(index, manifest);
  950. num_manifests--;
  951. }
  952. }
  953. { // Elements.
  954. int num_elements;
  955. in >> num_elements;
  956. if (in.fail()) {
  957. return false;
  958. }
  959. while (num_elements > 0) {
  960. ElementIndex index;
  961. InterrogateElement element(def);
  962. in >> index >> element;
  963. if (in.fail()) {
  964. return false;
  965. }
  966. add_element(index, element);
  967. num_elements--;
  968. }
  969. }
  970. return true;
  971. }
  972. ////////////////////////////////////////////////////////////////////
  973. // Function: InterrogateDatabase::merge_from
  974. // Access: Private
  975. // Description: Copies all the data from the indicated database into
  976. // this one. It is an error if any index numbers are
  977. // shared between the two databases.
  978. ////////////////////////////////////////////////////////////////////
  979. void InterrogateDatabase::
  980. merge_from(const InterrogateDatabase &other) {
  981. // We want to collapse shared types together.
  982. IndexRemapper remap;
  983. // First, we need to build a set of types by name, so we know what
  984. // types we already have.
  985. map<string, TypeIndex> types_by_name;
  986. TypeMap::const_iterator ti;
  987. for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
  988. const InterrogateType &type = (*ti).second;
  989. if (type.has_true_name()) {
  990. types_by_name[type.get_true_name()] = (*ti).first;
  991. }
  992. }
  993. // Now go through the other set of types and determine the mapping
  994. // into this set.
  995. for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
  996. TypeIndex other_type_index = (*ti).first;
  997. const InterrogateType &other_type = (*ti).second;
  998. if (other_type.has_name()) {
  999. map<string, TypeIndex>::iterator ni;
  1000. ni = types_by_name.find(other_type.get_true_name());
  1001. if (ni != types_by_name.end()) {
  1002. // Here's a type that we seem to have in common! We'll have
  1003. // to merge them.
  1004. TypeIndex this_type_index = (*ni).second;
  1005. remap.add_mapping(other_type_index, this_type_index);
  1006. }
  1007. }
  1008. }
  1009. // Now that we know the full type-to-type mapping, we can copy the
  1010. // new types, one at a time.
  1011. for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
  1012. TypeIndex other_type_index = (*ti).first;
  1013. const InterrogateType &other_type = (*ti).second;
  1014. if (!remap.in_map(other_type_index)) {
  1015. // Here's a new type.
  1016. add_type(other_type_index, other_type);
  1017. update_type(other_type_index).remap_indices(remap);
  1018. } else {
  1019. // Here's a type to merge.
  1020. TypeIndex this_type_index = remap.map_from(other_type_index);
  1021. InterrogateType &this_type = update_type(this_type_index);
  1022. if (!this_type.is_global() && other_type.is_global()) {
  1023. // If the type is about to become global, we need to add it
  1024. // to our global_types list.
  1025. _global_types.push_back(this_type_index);
  1026. }
  1027. InterrogateType merge_type = other_type;
  1028. merge_type.remap_indices(remap);
  1029. this_type.merge_with(merge_type);
  1030. }
  1031. }
  1032. // And copy all of the functions, wrappers, manifests, and elements.
  1033. FunctionMap::const_iterator fi;
  1034. for (fi = other._function_map.begin();
  1035. fi != other._function_map.end();
  1036. ++fi) {
  1037. FunctionIndex other_function_index = (*fi).first;
  1038. InterrogateFunction *other_function = (*fi).second;
  1039. add_function(other_function_index, other_function);
  1040. update_function(other_function_index).remap_indices(remap);
  1041. }
  1042. FunctionWrapperMap::const_iterator wi;
  1043. for (wi = other._wrapper_map.begin();
  1044. wi != other._wrapper_map.end();
  1045. ++wi) {
  1046. FunctionWrapperIndex other_wrapper_index = (*wi).first;
  1047. const InterrogateFunctionWrapper &other_wrapper = (*wi).second;
  1048. add_wrapper(other_wrapper_index, other_wrapper);
  1049. update_wrapper(other_wrapper_index).remap_indices(remap);
  1050. }
  1051. ManifestMap::const_iterator mi;
  1052. for (mi = other._manifest_map.begin();
  1053. mi != other._manifest_map.end();
  1054. ++mi) {
  1055. ManifestIndex other_manifest_index = (*mi).first;
  1056. const InterrogateManifest &other_manifest = (*mi).second;
  1057. add_manifest(other_manifest_index, other_manifest);
  1058. update_manifest(other_manifest_index).remap_indices(remap);
  1059. }
  1060. ElementMap::const_iterator ei;
  1061. for (ei = other._element_map.begin();
  1062. ei != other._element_map.end();
  1063. ++ei) {
  1064. ElementIndex other_element_index = (*ei).first;
  1065. const InterrogateElement &other_element = (*ei).second;
  1066. add_element(other_element_index, other_element);
  1067. update_element(other_element_index).remap_indices(remap);
  1068. }
  1069. _lookups_fresh = 0;
  1070. }
  1071. ////////////////////////////////////////////////////////////////////
  1072. // Function: InterrogateDatabase::find_module
  1073. // Access: Private
  1074. // Description: Looks up the wrapper definition in the set of module
  1075. // defs that are loaded in at runtime and represent the
  1076. // part of the interrogate database that's compiled in.
  1077. //
  1078. // If the wrapper definition is not found, returns
  1079. // false. If it is found, returns true and sets def and
  1080. // module_index to the particular module and the index
  1081. // within the module where the wrapper is defined.
  1082. ////////////////////////////////////////////////////////////////////
  1083. bool InterrogateDatabase::
  1084. find_module(FunctionWrapperIndex wrapper, InterrogateModuleDef *&def,
  1085. int &module_index) {
  1086. if (_modules.empty()) {
  1087. return false;
  1088. }
  1089. int mi = binary_search_module(0, _modules.size(), wrapper);
  1090. assert(mi >= 0 && mi < (int)_modules.size());
  1091. def = _modules[mi];
  1092. module_index = wrapper - def->first_index;
  1093. return (wrapper < def->next_index);
  1094. }
  1095. ////////////////////////////////////////////////////////////////////
  1096. // Function: InterrogateDatabase::binary_search_module
  1097. // Access: Private
  1098. // Description: Searches for the function module that includes the
  1099. // given function index by binary search.
  1100. ////////////////////////////////////////////////////////////////////
  1101. int InterrogateDatabase::
  1102. binary_search_module(int begin, int end, FunctionIndex function) {
  1103. int mid = begin + (end - begin) / 2;
  1104. if (mid == begin) {
  1105. return mid;
  1106. }
  1107. int index = _modules[mid]->first_index;
  1108. if (index <= function) {
  1109. return binary_search_module(mid, end, function);
  1110. } else {
  1111. return binary_search_module(begin, mid, function);
  1112. }
  1113. }
  1114. ////////////////////////////////////////////////////////////////////
  1115. // Function: InterrogateDatabase::binary_search_wrapper_hash
  1116. // Access: Private
  1117. // Description: Searches for the particular function wrapper's hash
  1118. // name within a given module. Returns the index number
  1119. // local to the module, or -1 if it is not found.
  1120. ////////////////////////////////////////////////////////////////////
  1121. int InterrogateDatabase::
  1122. binary_search_wrapper_hash(InterrogateUniqueNameDef *begin,
  1123. InterrogateUniqueNameDef *end,
  1124. const string &wrapper_hash_name) {
  1125. if (end <= begin) {
  1126. return -1;
  1127. }
  1128. InterrogateUniqueNameDef *mid = begin + (end - begin) / 2;
  1129. string name = mid->name;
  1130. if (name < wrapper_hash_name) {
  1131. return binary_search_wrapper_hash(mid, end, wrapper_hash_name);
  1132. } else if (wrapper_hash_name < name) {
  1133. return binary_search_wrapper_hash(begin, mid, wrapper_hash_name);
  1134. } else {
  1135. return mid->index_offset;
  1136. }
  1137. }
  1138. ////////////////////////////////////////////////////////////////////
  1139. // Function: InterrogateDatabase::freshen_types_by_name
  1140. // Access: Private
  1141. // Description: Builds up the lookup of types by name.
  1142. ////////////////////////////////////////////////////////////////////
  1143. void InterrogateDatabase::
  1144. freshen_types_by_name() {
  1145. _types_by_name.clear();
  1146. TypeMap::const_iterator ti;
  1147. for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
  1148. _types_by_name[(*ti).second.get_name()] = (*ti).first;
  1149. }
  1150. }
  1151. ////////////////////////////////////////////////////////////////////
  1152. // Function: InterrogateDatabase::freshen_types_by_scoped_name
  1153. // Access: Private
  1154. // Description: Builds up the lookup of types by scoped name.
  1155. ////////////////////////////////////////////////////////////////////
  1156. void InterrogateDatabase::
  1157. freshen_types_by_scoped_name() {
  1158. _types_by_scoped_name.clear();
  1159. TypeMap::const_iterator ti;
  1160. for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
  1161. _types_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
  1162. }
  1163. }
  1164. ////////////////////////////////////////////////////////////////////
  1165. // Function: InterrogateDatabase::freshen_types_by_true_name
  1166. // Access: Private
  1167. // Description: Builds up the lookup of types by true name.
  1168. ////////////////////////////////////////////////////////////////////
  1169. void InterrogateDatabase::
  1170. freshen_types_by_true_name() {
  1171. _types_by_true_name.clear();
  1172. TypeMap::const_iterator ti;
  1173. for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
  1174. _types_by_true_name[(*ti).second.get_true_name()] = (*ti).first;
  1175. }
  1176. }
  1177. ////////////////////////////////////////////////////////////////////
  1178. // Function: InterrogateDatabase::freshen_manifests_by_name
  1179. // Access: Private
  1180. // Description: Builds up the lookup of manifests by name.
  1181. ////////////////////////////////////////////////////////////////////
  1182. void InterrogateDatabase::
  1183. freshen_manifests_by_name() {
  1184. _manifests_by_name.clear();
  1185. ManifestMap::const_iterator ti;
  1186. for (ti = _manifest_map.begin(); ti != _manifest_map.end(); ++ti) {
  1187. _manifests_by_name[(*ti).second.get_name()] = (*ti).first;
  1188. }
  1189. }
  1190. ////////////////////////////////////////////////////////////////////
  1191. // Function: InterrogateDatabase::freshen_elements_by_name
  1192. // Access: Private
  1193. // Description: Builds up the lookup of elements by name.
  1194. ////////////////////////////////////////////////////////////////////
  1195. void InterrogateDatabase::
  1196. freshen_elements_by_name() {
  1197. _elements_by_name.clear();
  1198. ElementMap::const_iterator ti;
  1199. for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
  1200. _elements_by_name[(*ti).second.get_name()] = (*ti).first;
  1201. }
  1202. }
  1203. ////////////////////////////////////////////////////////////////////
  1204. // Function: InterrogateDatabase::freshen_elements_by_scoped_name
  1205. // Access: Private
  1206. // Description: Builds up the lookup of elements by scoped name.
  1207. ////////////////////////////////////////////////////////////////////
  1208. void InterrogateDatabase::
  1209. freshen_elements_by_scoped_name() {
  1210. _elements_by_scoped_name.clear();
  1211. ElementMap::const_iterator ti;
  1212. for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
  1213. _elements_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
  1214. }
  1215. }
  1216. ////////////////////////////////////////////////////////////////////
  1217. // Function: InterrogateDatabase::lookup
  1218. // Access: Private
  1219. // Description: Looks up a type, manifest, or element in the
  1220. // indicated lookup table by name. This is an internal
  1221. // support function.
  1222. ////////////////////////////////////////////////////////////////////
  1223. int InterrogateDatabase::
  1224. lookup(const string &name, Lookup &lookup, LookupType type,
  1225. void (InterrogateDatabase::*freshen)()) {
  1226. if ((_lookups_fresh & (int)type) == 0) {
  1227. // The lookup table isn't fresh; we need to freshen it.
  1228. (this->*freshen)();
  1229. _lookups_fresh |= (int)type;
  1230. }
  1231. Lookup::const_iterator li;
  1232. li = lookup.find(name);
  1233. if (li != lookup.end()) {
  1234. return (*li).second;
  1235. }
  1236. return 0;
  1237. }