Panda3D

dcFile.cxx

00001 // Filename: dcFile.cxx
00002 // Created by:  drose (05Oct00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "dcFile.h"
00016 #include "dcClass.h"
00017 #include "dcSwitch.h"
00018 #include "dcParserDefs.h"
00019 #include "dcLexerDefs.h"
00020 #include "dcTypedef.h"
00021 #include "dcKeyword.h"
00022 #include "hashGenerator.h"
00023 
00024 #ifdef WITHIN_PANDA
00025 #include "filename.h"
00026 #include "config_express.h"
00027 #include "virtualFileSystem.h"
00028 #include "executionEnvironment.h"
00029 #include "configVariableList.h"
00030 #endif
00031 
00032 
00033 ////////////////////////////////////////////////////////////////////
00034 //     Function: DCFile::Constructor
00035 //       Access: Published
00036 //  Description:
00037 ////////////////////////////////////////////////////////////////////
00038 DCFile::
00039 DCFile() {
00040   _all_objects_valid = true;
00041   _inherited_fields_stale = false;
00042 
00043   setup_default_keywords();
00044 }
00045 
00046 ////////////////////////////////////////////////////////////////////
00047 //     Function: DCFile::Destructor
00048 //       Access: Published
00049 //  Description:
00050 ////////////////////////////////////////////////////////////////////
00051 DCFile::
00052 ~DCFile() {
00053   clear();
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: DCFile::clear
00058 //       Access: Published
00059 //  Description: Removes all of the classes defined within the DCFile
00060 //               and prepares it for reading a new file.
00061 ////////////////////////////////////////////////////////////////////
00062 void DCFile::
00063 clear() {
00064   Declarations::iterator di;
00065   for (di = _declarations.begin(); di != _declarations.end(); ++di) {
00066     delete (*di);
00067   }
00068   for (di = _things_to_delete.begin(); di != _things_to_delete.end(); ++di) {
00069     delete (*di);
00070   }
00071   
00072   _classes.clear();
00073   _imports.clear();
00074   _things_by_name.clear();
00075   _typedefs.clear();
00076   _typedefs_by_name.clear();
00077   _keywords.clear_keywords();
00078   _declarations.clear();
00079   _things_to_delete.clear();
00080   setup_default_keywords();
00081 
00082   _all_objects_valid = true;
00083   _inherited_fields_stale = false;
00084 }
00085 
00086 #ifdef WITHIN_PANDA
00087 
00088 ////////////////////////////////////////////////////////////////////
00089 //     Function: DCFile::read_all
00090 //       Access: Published
00091 //  Description: This special method reads all of the .dc files named
00092 //               by the "dc-file" config.prc variable, and loads them
00093 //               into the DCFile namespace.
00094 ////////////////////////////////////////////////////////////////////
00095 bool DCFile::
00096 read_all() {
00097   static ConfigVariableList dc_files
00098     ("dc-file", PRC_DESC("The list of dc files to load."));
00099 
00100   if (dc_files.size() == 0) {
00101     cerr << "No files specified via dc-file Config.prc variable!\n";
00102     return false;
00103   }
00104 
00105   int size = dc_files.size();
00106 
00107   // Load the DC files in opposite order, because we want to load the
00108   // least-important (most fundamental) files first.
00109   for (int i = size - 1; i >= 0; --i) {
00110     string dc_file = ExecutionEnvironment::expand_string(dc_files[i]);
00111     Filename filename = Filename::from_os_specific(dc_file);
00112     if (!read(filename)) {
00113       return false;
00114     }
00115   }
00116 
00117   return true;
00118 }
00119 
00120 #endif  // WITHIN_PANDA
00121 
00122 ////////////////////////////////////////////////////////////////////
00123 //     Function: DCFile::read
00124 //       Access: Published
00125 //  Description: Opens and reads the indicated .dc file by name.  The
00126 //               distributed classes defined in the file will be
00127 //               appended to the set of distributed classes already
00128 //               recorded, if any.
00129 //
00130 //               Returns true if the file is successfully read, false
00131 //               if there was an error (in which case the file might
00132 //               have been partially read).
00133 ////////////////////////////////////////////////////////////////////
00134 bool DCFile::
00135 read(Filename filename) {
00136 #ifdef WITHIN_PANDA
00137   filename.set_text();
00138   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00139   istream *in = vfs->open_read_file(filename, true);
00140   if (in == (istream *)NULL) {
00141     cerr << "Cannot open " << filename << " for reading.\n";
00142     return false;
00143   }
00144   bool okflag = read(*in, filename);
00145   
00146   // For some reason--compiler bug in gcc 3.2?--explicitly deleting
00147   // the in pointer does not call the appropriate global delete
00148   // function; instead apparently calling the system delete
00149   // function.  So we call the delete function by hand instead.
00150   vfs->close_read_file(in);
00151   
00152   return okflag;
00153 
00154 #else  // WITHIN_PANDA
00155 
00156   pifstream in;
00157   in.open(filename.c_str());
00158 
00159   if (!in) {
00160     cerr << "Cannot open " << filename << " for reading.\n";
00161     return false;
00162   }
00163 
00164   return read(in, filename);
00165 
00166 #endif  // WITHIN_PANDA
00167 }
00168 
00169 ////////////////////////////////////////////////////////////////////
00170 //     Function: DCFile::read
00171 //       Access: Published
00172 //  Description: Parses the already-opened input stream for
00173 //               distributed class descriptions.  The filename
00174 //               parameter is optional and is only used when reporting
00175 //               errors.
00176 //
00177 //               The distributed classes defined in the file will be
00178 //               appended to the set of distributed classes already
00179 //               recorded, if any.
00180 //
00181 //               Returns true if the file is successfully read, false
00182 //               if there was an error (in which case the file might
00183 //               have been partially read).
00184 ////////////////////////////////////////////////////////////////////
00185 bool DCFile::
00186 read(istream &in, const string &filename) {
00187   cerr << "DCFile::read of " << filename << "\n";
00188   dc_init_parser(in, filename, *this);
00189   dcyyparse();
00190   dc_cleanup_parser();
00191 
00192   return (dc_error_count() == 0);
00193 }
00194 
00195 ////////////////////////////////////////////////////////////////////
00196 //     Function: DCFile::write
00197 //       Access: Published
00198 //  Description: Opens the indicated filename for output and writes a
00199 //               parseable description of all the known distributed
00200 //               classes to the file.
00201 //
00202 //               Returns true if the description is successfully
00203 //               written, false otherwise.
00204 ////////////////////////////////////////////////////////////////////
00205 bool DCFile::
00206 write(Filename filename, bool brief) const {
00207   pofstream out;
00208 
00209 #ifdef WITHIN_PANDA
00210   filename.set_text();
00211   filename.open_write(out);
00212 #else
00213   out.open(filename.c_str());
00214 #endif
00215 
00216   if (!out) {
00217     cerr << "Can't open " << filename << " for output.\n";
00218     return false;
00219   }
00220   return write(out, brief);
00221 }
00222 
00223 ////////////////////////////////////////////////////////////////////
00224 //     Function: DCFile::write
00225 //       Access: Published
00226 //  Description: Writes a parseable description of all the known
00227 //               distributed classes to the stream.
00228 //
00229 //               Returns true if the description is successfully
00230 //               written, false otherwise.
00231 ////////////////////////////////////////////////////////////////////
00232 bool DCFile::
00233 write(ostream &out, bool brief) const {
00234   if (!_imports.empty()) {
00235     Imports::const_iterator ii;
00236     for (ii = _imports.begin(); ii != _imports.end(); ++ii) {
00237       const Import &import = (*ii);
00238       if (import._symbols.empty()) {
00239         out << "import " << import._module << "\n";
00240       } else {
00241         out << "from " << import._module << " import ";
00242         ImportSymbols::const_iterator si = import._symbols.begin();
00243         out << *si;
00244         ++si;
00245         while (si != import._symbols.end()) {
00246           out << ", " << *si;
00247         ++si;
00248         }
00249         out << "\n";
00250       }
00251     }
00252     out << "\n";
00253   }
00254 
00255   Declarations::const_iterator di;
00256   for (di = _declarations.begin(); di != _declarations.end(); ++di) {
00257     (*di)->write(out, brief, 0);
00258     out << "\n";
00259   }
00260 
00261   return !out.fail();
00262 }
00263 
00264 ////////////////////////////////////////////////////////////////////
00265 //     Function: DCFile::get_num_classes
00266 //       Access: Published
00267 //  Description: Returns the number of classes read from the .dc
00268 //               file(s).
00269 ////////////////////////////////////////////////////////////////////
00270 int DCFile::
00271 get_num_classes() const {
00272   return _classes.size();
00273 }
00274 
00275 ////////////////////////////////////////////////////////////////////
00276 //     Function: DCFile::get_class
00277 //       Access: Published
00278 //  Description: Returns the nth class read from the .dc file(s).
00279 ////////////////////////////////////////////////////////////////////
00280 DCClass *DCFile::
00281 get_class(int n) const {
00282   nassertr(n >= 0 && n < (int)_classes.size(), NULL);
00283   return _classes[n];
00284 }
00285 
00286 ////////////////////////////////////////////////////////////////////
00287 //     Function: DCFile::get_class_by_name
00288 //       Access: Published
00289 //  Description: Returns the class that has the indicated name, or
00290 //               NULL if there is no such class.
00291 ////////////////////////////////////////////////////////////////////
00292 DCClass *DCFile::
00293 get_class_by_name(const string &name) const {
00294   ThingsByName::const_iterator ni;
00295   ni = _things_by_name.find(name);
00296   if (ni != _things_by_name.end()) {
00297     return (*ni).second->as_class();
00298   }
00299 
00300   return (DCClass *)NULL;
00301 }
00302 
00303 ////////////////////////////////////////////////////////////////////
00304 //     Function: DCFile::get_switch_by_name
00305 //       Access: Published
00306 //  Description: Returns the switch that has the indicated name, or
00307 //               NULL if there is no such switch.
00308 ////////////////////////////////////////////////////////////////////
00309 DCSwitch *DCFile::
00310 get_switch_by_name(const string &name) const {
00311   ThingsByName::const_iterator ni;
00312   ni = _things_by_name.find(name);
00313   if (ni != _things_by_name.end()) {
00314     return (*ni).second->as_switch();
00315   }
00316 
00317   return (DCSwitch *)NULL;
00318 }
00319 
00320 ////////////////////////////////////////////////////////////////////
00321 //     Function: DCFile::get_field_by_index
00322 //       Access: Published, Static
00323 //  Description: Returns a pointer to the one DCField that has the
00324 //               indicated index number, of all the DCFields across
00325 //               all classes in the file.
00326 //
00327 //               This method is only valid if dc-multiple-inheritance
00328 //               is set true in the Config.prc file.  Without this
00329 //               setting, different DCFields may share the same index
00330 //               number, so this global lookup is not possible.
00331 ////////////////////////////////////////////////////////////////////
00332 DCField *DCFile::
00333 get_field_by_index(int index_number) const {
00334   nassertr(dc_multiple_inheritance, NULL);
00335 
00336   if (index_number >= 0 && index_number < (int)_fields_by_index.size()) {
00337     return _fields_by_index[index_number];
00338   }
00339   
00340   return NULL;
00341 }
00342 
00343 ////////////////////////////////////////////////////////////////////
00344 //     Function: DCFile::get_num_import_modules
00345 //       Access: Published
00346 //  Description: Returns the number of import lines read from the .dc
00347 //               file(s).
00348 ////////////////////////////////////////////////////////////////////
00349 int DCFile::
00350 get_num_import_modules() const {
00351   return _imports.size();
00352 }
00353 
00354 ////////////////////////////////////////////////////////////////////
00355 //     Function: DCFile::get_import_module
00356 //       Access: Published
00357 //  Description: Returns the module named by the nth import line read
00358 //               from the .dc file(s).
00359 ////////////////////////////////////////////////////////////////////
00360 string DCFile::
00361 get_import_module(int n) const {
00362   nassertr(n >= 0 && n < (int)_imports.size(), string());
00363   return _imports[n]._module;
00364 }
00365 
00366 ////////////////////////////////////////////////////////////////////
00367 //     Function: DCFile::get_num_import_symbols
00368 //       Access: Published
00369 //  Description: Returns the number of symbols explicitly imported by
00370 //               the nth import line.  If this is 0, the line is
00371 //               "import modulename"; if it is more than 0, the line
00372 //               is "from modulename import symbol, symbol ... ".
00373 ////////////////////////////////////////////////////////////////////
00374 int DCFile::
00375 get_num_import_symbols(int n) const {
00376   nassertr(n >= 0 && n < (int)_imports.size(), 0);
00377   return _imports[n]._symbols.size();
00378 }
00379 
00380 ////////////////////////////////////////////////////////////////////
00381 //     Function: DCFile::get_import_symbol
00382 //       Access: Published
00383 //  Description: Returns the ith symbol named by the nth import line
00384 //               read from the .dc file(s).
00385 ////////////////////////////////////////////////////////////////////
00386 string DCFile::
00387 get_import_symbol(int n, int i) const {
00388   nassertr(n >= 0 && n < (int)_imports.size(), string());
00389   nassertr(i >= 0 && i < (int)_imports[n]._symbols.size(), string());
00390   return _imports[n]._symbols[i];
00391 }
00392 
00393 ////////////////////////////////////////////////////////////////////
00394 //     Function: DCFile::get_num_typedefs
00395 //       Access: Published
00396 //  Description: Returns the number of typedefs read from the .dc
00397 //               file(s).
00398 ////////////////////////////////////////////////////////////////////
00399 int DCFile::
00400 get_num_typedefs() const {
00401   return _typedefs.size();
00402 }
00403 
00404 ////////////////////////////////////////////////////////////////////
00405 //     Function: DCFile::get_typedef
00406 //       Access: Published
00407 //  Description: Returns the nth typedef read from the .dc file(s).
00408 ////////////////////////////////////////////////////////////////////
00409 DCTypedef *DCFile::
00410 get_typedef(int n) const {
00411   nassertr(n >= 0 && n < (int)_typedefs.size(), NULL);
00412   return _typedefs[n];
00413 }
00414 
00415 ////////////////////////////////////////////////////////////////////
00416 //     Function: DCFile::get_typedef_by_name
00417 //       Access: Published
00418 //  Description: Returns the typedef that has the indicated name, or
00419 //               NULL if there is no such typedef name.
00420 ////////////////////////////////////////////////////////////////////
00421 DCTypedef *DCFile::
00422 get_typedef_by_name(const string &name) const {
00423   TypedefsByName::const_iterator ni;
00424   ni = _typedefs_by_name.find(name);
00425   if (ni != _typedefs_by_name.end()) {
00426     return (*ni).second;
00427   }
00428 
00429   return NULL;
00430 }
00431 
00432 ////////////////////////////////////////////////////////////////////
00433 //     Function: DCFile::get_num_keywords
00434 //       Access: Published
00435 //  Description: Returns the number of keywords read from the .dc
00436 //               file(s).
00437 ////////////////////////////////////////////////////////////////////
00438 int DCFile::
00439 get_num_keywords() const {
00440   return _keywords.get_num_keywords();
00441 }
00442 
00443 ////////////////////////////////////////////////////////////////////
00444 //     Function: DCFile::get_keyword
00445 //       Access: Published
00446 //  Description: Returns the nth keyword read from the .dc file(s).
00447 ////////////////////////////////////////////////////////////////////
00448 const DCKeyword *DCFile::
00449 get_keyword(int n) const {
00450   return _keywords.get_keyword(n);
00451 }
00452 
00453 ////////////////////////////////////////////////////////////////////
00454 //     Function: DCFile::get_keyword_by_name
00455 //       Access: Published
00456 //  Description: Returns the keyword that has the indicated name, or
00457 //               NULL if there is no such keyword name.
00458 ////////////////////////////////////////////////////////////////////
00459 const DCKeyword *DCFile::
00460 get_keyword_by_name(const string &name) const {
00461   const DCKeyword *keyword = _keywords.get_keyword_by_name(name);
00462   if (keyword == (const DCKeyword *)NULL) {
00463     keyword = _default_keywords.get_keyword_by_name(name);
00464     if (keyword != (const DCKeyword *)NULL) {
00465       // One of the historical default keywords was used, but wasn't
00466       // defined.  Define it implicitly right now.
00467       ((DCFile *)this)->_keywords.add_keyword(keyword);
00468     }
00469   }
00470 
00471   return keyword;
00472 }
00473 
00474 ////////////////////////////////////////////////////////////////////
00475 //     Function: DCFile::get_hash
00476 //       Access: Published
00477 //  Description: Returns a 32-bit hash index associated with this
00478 //               file.  This number is guaranteed to be consistent if
00479 //               the contents of the file have not changed, and it is
00480 //               very likely to be different if the contents of the
00481 //               file do change.
00482 ////////////////////////////////////////////////////////////////////
00483 unsigned long DCFile::
00484 get_hash() const {
00485   HashGenerator hashgen;
00486   generate_hash(hashgen);
00487   return hashgen.get_hash();
00488 }
00489 
00490 ////////////////////////////////////////////////////////////////////
00491 //     Function: DCFile::generate_hash
00492 //       Access: Public, Virtual
00493 //  Description: Accumulates the properties of this file into the
00494 //               hash.
00495 ////////////////////////////////////////////////////////////////////
00496 void DCFile::
00497 generate_hash(HashGenerator &hashgen) const {
00498   if (dc_virtual_inheritance) {
00499     // Just to make the hash number change in this case.
00500     if (dc_sort_inheritance_by_file) {
00501       hashgen.add_int(1);
00502     } else {
00503       hashgen.add_int(2);
00504     }
00505   }
00506 
00507   hashgen.add_int(_classes.size());
00508   Classes::const_iterator ci;
00509   for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
00510     (*ci)->generate_hash(hashgen);
00511   }
00512 }
00513 
00514 ////////////////////////////////////////////////////////////////////
00515 //     Function: DCFile::add_class
00516 //       Access: Public
00517 //  Description: Adds the newly-allocated distributed class definition
00518 //               to the file.  The DCFile becomes the owner of the
00519 //               pointer and will delete it when it destructs.
00520 //               Returns true if the class is successfully added, or
00521 //               false if there was a name conflict.
00522 ////////////////////////////////////////////////////////////////////
00523 bool DCFile::
00524 add_class(DCClass *dclass) {
00525   if (!dclass->get_name().empty()) {
00526     bool inserted = _things_by_name.insert
00527       (ThingsByName::value_type(dclass->get_name(), dclass)).second;
00528     
00529     if (!inserted) {
00530       return false;
00531     }
00532   }
00533 
00534   if (!dclass->is_struct()) {
00535     dclass->set_number(get_num_classes());
00536   }
00537   _classes.push_back(dclass);
00538 
00539   if (dclass->is_bogus_class()) {
00540     _all_objects_valid = false;
00541   }
00542 
00543   if (!dclass->is_bogus_class()) {
00544     _declarations.push_back(dclass);
00545   } else {
00546     _things_to_delete.push_back(dclass);
00547   }
00548 
00549   return true;
00550 }
00551 
00552 ////////////////////////////////////////////////////////////////////
00553 //     Function: DCFile::add_switch
00554 //       Access: Public
00555 //  Description: Adds the newly-allocated switch definition
00556 //               to the file.  The DCFile becomes the owner of the
00557 //               pointer and will delete it when it destructs.
00558 //               Returns true if the switch is successfully added, or
00559 //               false if there was a name conflict.
00560 ////////////////////////////////////////////////////////////////////
00561 bool DCFile::
00562 add_switch(DCSwitch *dswitch) {
00563   if (!dswitch->get_name().empty()) {
00564     bool inserted = _things_by_name.insert
00565       (ThingsByName::value_type(dswitch->get_name(), dswitch)).second;
00566     
00567     if (!inserted) {
00568       return false;
00569     }
00570   }
00571 
00572   _declarations.push_back(dswitch);
00573 
00574   return true;
00575 }
00576 
00577 ////////////////////////////////////////////////////////////////////
00578 //     Function: DCFile::add_import_module
00579 //       Access: Public
00580 //  Description: Adds a new name to the list of names of Python
00581 //               modules that are to be imported by the client or AI
00582 //               to define the code that is associated with the class
00583 //               interfaces named within the .dc file.
00584 ////////////////////////////////////////////////////////////////////
00585 void DCFile::
00586 add_import_module(const string &import_module) {
00587   Import import;
00588   import._module = import_module;
00589   _imports.push_back(import);
00590 }
00591 
00592 ////////////////////////////////////////////////////////////////////
00593 //     Function: DCFile::add_import_symbol
00594 //       Access: Public
00595 //  Description: Adds a new name to the list of symbols that are to be
00596 //               explicitly imported from the most-recently added
00597 //               module, e.g. "from module_name import symbol".  If
00598 //               the list of symbols is empty, the syntax is taken to
00599 //               be "import module_name".
00600 ////////////////////////////////////////////////////////////////////
00601 void DCFile::
00602 add_import_symbol(const string &import_symbol) {
00603   nassertv(!_imports.empty());
00604   _imports.back()._symbols.push_back(import_symbol);
00605 }
00606 
00607 ////////////////////////////////////////////////////////////////////
00608 //     Function: DCFile::add_typedef
00609 //       Access: Public
00610 //  Description: Adds the newly-allocated distributed typedef definition
00611 //               to the file.  The DCFile becomes the owner of the
00612 //               pointer and will delete it when it destructs.
00613 //               Returns true if the typedef is successfully added, or
00614 //               false if there was a name conflict.
00615 ////////////////////////////////////////////////////////////////////
00616 bool DCFile::
00617 add_typedef(DCTypedef *dtypedef) {
00618   bool inserted = _typedefs_by_name.insert
00619     (TypedefsByName::value_type(dtypedef->get_name(), dtypedef)).second;
00620 
00621   if (!inserted) {
00622     return false;
00623   }
00624 
00625   dtypedef->set_number(get_num_typedefs());
00626   _typedefs.push_back(dtypedef);
00627 
00628   if (dtypedef->is_bogus_typedef()) {
00629     _all_objects_valid = false;
00630   }
00631 
00632   if (!dtypedef->is_bogus_typedef() && !dtypedef->is_implicit_typedef()) {
00633     _declarations.push_back(dtypedef);
00634   } else {
00635     _things_to_delete.push_back(dtypedef);
00636   }
00637 
00638   return true;
00639 }
00640 
00641 ////////////////////////////////////////////////////////////////////
00642 //     Function: DCFile::add_keyword
00643 //       Access: Public
00644 //  Description: Adds the indicated keyword string to the list of
00645 //               keywords known to the DCFile.  These keywords may
00646 //               then be added to DCFields.  It is not an error to add
00647 //               a particular keyword more than once.
00648 ////////////////////////////////////////////////////////////////////
00649 bool DCFile::
00650 add_keyword(const string &name) {
00651   DCKeyword *keyword = new DCKeyword(name);
00652   bool added = _keywords.add_keyword(keyword);
00653 
00654   if (added) {
00655     _declarations.push_back(keyword);
00656   } else {
00657     delete keyword;
00658   }
00659 
00660   return added;
00661 }
00662 
00663 ////////////////////////////////////////////////////////////////////
00664 //     Function: DCFile::add_thing_to_delete
00665 //       Access: Public
00666 //  Description: Adds the indicated declaration to the list of
00667 //               declarations that are not reported with the file, but
00668 //               will be deleted when the DCFile object destructs.
00669 //               That is, transfers ownership of the indicated pointer
00670 //               to the DCFile.
00671 ////////////////////////////////////////////////////////////////////
00672 void DCFile::
00673 add_thing_to_delete(DCDeclaration *decl) {
00674   _things_to_delete.push_back(decl);
00675 }
00676 
00677 ////////////////////////////////////////////////////////////////////
00678 //     Function: DCFile::set_new_index_number
00679 //       Access: Public
00680 //  Description: Sets the next sequential available index number on
00681 //               the indicated field.  This is only meant to be called
00682 //               by DCClass::add_field(), while the dc file is being
00683 //               parsed.
00684 ////////////////////////////////////////////////////////////////////
00685 void DCFile::
00686 set_new_index_number(DCField *field) {
00687   field->set_number((int)_fields_by_index.size());
00688   _fields_by_index.push_back(field);
00689 }
00690 
00691 ////////////////////////////////////////////////////////////////////
00692 //     Function: DCFile::setup_default_keywords
00693 //       Access: Private
00694 //  Description: Adds an entry for each of the default keywords that
00695 //               are defined for every DCFile for legacy reasons.
00696 ////////////////////////////////////////////////////////////////////
00697 void DCFile::
00698 setup_default_keywords() {
00699   struct KeywordDef {
00700     const char *name;
00701     int flag;
00702   };
00703   static KeywordDef default_keywords[] = {
00704     { "required", 0x0001 },
00705     { "broadcast", 0x0002 },
00706     { "ownrecv", 0x0004 },
00707     { "ram", 0x0008 },
00708     { "db", 0x0010 },
00709     { "clsend", 0x0020 },
00710     { "clrecv", 0x0040 },
00711     { "ownsend", 0x0080 },
00712     { "airecv", 0x0100 },
00713     { NULL, 0 }
00714   };
00715 
00716   _default_keywords.clear_keywords();
00717   for (int i = 0; default_keywords[i].name != NULL; ++i) {
00718     DCKeyword *keyword = 
00719       new DCKeyword(default_keywords[i].name, 
00720                     default_keywords[i].flag);
00721     
00722     _default_keywords.add_keyword(keyword);
00723     _things_to_delete.push_back(keyword);
00724   }
00725 }
00726 
00727 ////////////////////////////////////////////////////////////////////
00728 //     Function: DCFile::rebuild_inherited_fields
00729 //       Access: Private
00730 //  Description: Reconstructs the inherited fields table of all
00731 //               classes.
00732 ////////////////////////////////////////////////////////////////////
00733 void DCFile::
00734 rebuild_inherited_fields() {
00735   _inherited_fields_stale = false;
00736 
00737   Classes::iterator ci;
00738   for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
00739     (*ci)->clear_inherited_fields();
00740   }
00741   for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
00742     (*ci)->rebuild_inherited_fields();
00743   }
00744 }
 All Classes Functions Variables Enumerations