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

direct/src/dcparser/dcClass.cxx

Go to the documentation of this file.
00001 // Filename: dcClass.cxx
00002 // Created by:  drose (05Oct00)
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 "dcClass.h"
00020 #include "hashGenerator.h"
00021 #include "dcindent.h"
00022 
00023 ////////////////////////////////////////////////////////////////////
00024 //     Function: DCClass::get_number
00025 //       Access: Public
00026 //  Description: Returns a unique index number associated with this
00027 //               class.  This is defined implicitly when the .dc
00028 //               file(s) are read.
00029 ////////////////////////////////////////////////////////////////////
00030 int DCClass::
00031 get_number() const {
00032   return _number;
00033 }
00034 
00035 ////////////////////////////////////////////////////////////////////
00036 //     Function: DCClass::get_name
00037 //       Access: Public
00038 //  Description: Returns the name of this class.
00039 ////////////////////////////////////////////////////////////////////
00040 string DCClass::
00041 get_name() const {
00042   return _name;
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: DCClass::has_parent
00047 //       Access: Public
00048 //  Description: Returns true if this class inherits from some other
00049 //               class, false if it does not.
00050 ////////////////////////////////////////////////////////////////////
00051 bool DCClass::
00052 has_parent() const {
00053   return !_parents.empty();
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: DCClass::get_parent
00058 //       Access: Public
00059 //  Description: Returns the parent class this class inherits from, if
00060 //               any.  It is an error to call this unless has_parent()
00061 //               returned true.
00062 ////////////////////////////////////////////////////////////////////
00063 DCClass *DCClass::
00064 get_parent() const {
00065   nassertr(has_parent(), NULL);
00066   return _parents.front();
00067 }
00068 
00069 ////////////////////////////////////////////////////////////////////
00070 //     Function: DCClass::get_num_fields
00071 //       Access: Public
00072 //  Description: Returns the number of fields defined directly in this
00073 //               class, ignoring inheritance.
00074 ////////////////////////////////////////////////////////////////////
00075 int DCClass::
00076 get_num_fields() {
00077   return _fields.size();
00078 }
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //     Function: DCClass::get_field
00082 //       Access: Public
00083 //  Description: Returns the nth field in the class.  This is not
00084 //               necessarily the field with index n; this is the nth
00085 //               field defined in the class directly, ignoring
00086 //               inheritance.
00087 ////////////////////////////////////////////////////////////////////
00088 DCField *DCClass::
00089 get_field(int n) {
00090   nassertr(n >= 0 && n < (int)_fields.size(), NULL);
00091   return _fields[n];
00092 }
00093 
00094 ////////////////////////////////////////////////////////////////////
00095 //     Function: DCClass::get_field_by_name
00096 //       Access: Public
00097 //  Description: Returns a pointer to the DCField that shares the
00098 //               indicated name.  If the named field is not found in
00099 //               the current class, the parent classes will be
00100 //               searched, so the value returned may not actually be a
00101 //               field within this class.  Returns NULL if there is no
00102 //               such field defined.
00103 ////////////////////////////////////////////////////////////////////
00104 DCField *DCClass::
00105 get_field_by_name(const string &name) {
00106   FieldsByName::const_iterator ni;
00107   ni = _fields_by_name.find(name);
00108   if (ni != _fields_by_name.end()) {
00109     return (*ni).second;
00110   }
00111 
00112   // We didn't have such a field, so check our parents.
00113   Parents::iterator pi;
00114   for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
00115     DCField *result = (*pi)->get_field_by_name(name);
00116     if (result != (DCField *)NULL) {
00117       return result;
00118     }
00119   }
00120 
00121   // Nobody knew what this field is.
00122   return (DCField *)NULL;
00123 }
00124 
00125 ////////////////////////////////////////////////////////////////////
00126 //     Function: DCClass::get_num_inherited_fields
00127 //       Access: Public
00128 //  Description: Returns the total number of field fields defined in
00129 //               this class and all ancestor classes.
00130 ////////////////////////////////////////////////////////////////////
00131 int DCClass::
00132 get_num_inherited_fields() {
00133   if (!_parents.empty()) {
00134     // This won't work for multiple dclass inheritance.
00135     return _parents.front()->get_num_inherited_fields() + get_num_fields();
00136   }
00137   return get_num_fields();
00138 }
00139 
00140 ////////////////////////////////////////////////////////////////////
00141 //     Function: DCClass::get_inherited_field
00142 //       Access: Public
00143 //  Description: Returns the nth field field in the class and all of
00144 //               its ancestors.  This *is* the field corresponding to
00145 //               the given index number, since the fields are ordered
00146 //               consecutively beginning at the earliest inherited
00147 //               fields.
00148 ////////////////////////////////////////////////////////////////////
00149 DCField *DCClass::
00150 get_inherited_field(int n) {
00151   if (!_parents.empty()) {
00152     // This won't work for multiple dclass inheritance.
00153     int psize = _parents.front()->get_num_inherited_fields();
00154     if (n < psize) {
00155       return _parents.front()->get_inherited_field(n);
00156     }
00157 
00158     n -= psize;
00159   }
00160   return get_field(n);
00161 }
00162 
00163 ////////////////////////////////////////////////////////////////////
00164 //     Function: DCClass::Constructor
00165 //       Access: Public
00166 //  Description:
00167 ////////////////////////////////////////////////////////////////////
00168 DCClass::
00169 DCClass() {
00170 }
00171 
00172 ////////////////////////////////////////////////////////////////////
00173 //     Function: DCClass::Destructor
00174 //       Access: Public
00175 //  Description:
00176 ////////////////////////////////////////////////////////////////////
00177 DCClass::
00178 ~DCClass() {
00179   Fields::iterator fi;
00180   for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
00181     delete (*fi);
00182   }
00183 }
00184 
00185 ////////////////////////////////////////////////////////////////////
00186 //     Function: DCClass::write
00187 //       Access: Public
00188 //  Description: Generates a parseable description of the object to
00189 //               the indicated output stream.
00190 ////////////////////////////////////////////////////////////////////
00191 void DCClass::
00192 write(ostream &out, int indent_level) const {
00193   indent(out, indent_level)
00194     << "dclass " << _name;
00195 
00196   if (!_parents.empty()) {
00197     Parents::const_iterator pi = _parents.begin();
00198     out << " : " << (*pi)->_name;
00199     ++pi;
00200     while (pi != _parents.end()) {
00201       out << ", " << (*pi)->_name;
00202       ++pi;
00203     }
00204   }
00205   out << " {  // index " << _number << "\n";
00206 
00207   Fields::const_iterator fi;
00208   for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
00209     (*fi)->write(out, indent_level + 2);
00210   }
00211 
00212   indent(out, indent_level) << "};\n";
00213 }
00214 
00215 ////////////////////////////////////////////////////////////////////
00216 //     Function: DCClass::generate_hash
00217 //       Access: Public, Virtual
00218 //  Description: Accumulates the properties of this class into the
00219 //               hash.
00220 ////////////////////////////////////////////////////////////////////
00221 void DCClass::
00222 generate_hash(HashGenerator &hashgen) const {
00223   hashgen.add_string(_name);
00224 
00225   hashgen.add_int(_parents.size());
00226   Parents::const_iterator pi;
00227   for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
00228     hashgen.add_int((*pi)->get_number());
00229   }
00230 
00231   hashgen.add_int(_fields.size());
00232   Fields::const_iterator fi;
00233   for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
00234     (*fi)->generate_hash(hashgen);
00235   }
00236 }
00237 
00238 ////////////////////////////////////////////////////////////////////
00239 //     Function: DCClass::add_field
00240 //       Access: Public
00241 //  Description: Adds the newly-allocated field to the class.  The
00242 //               class becomes the owner of the pointer and will
00243 //               delete it when it destructs.  Returns true if the
00244 //               field is successfully added, or false if there was a
00245 //               name conflict.
00246 ////////////////////////////////////////////////////////////////////
00247 bool DCClass::
00248 add_field(DCField *field) {
00249   bool inserted = _fields_by_name.insert
00250     (FieldsByName::value_type(field->_name, field)).second;
00251 
00252   if (!inserted) {
00253     return false;
00254   }
00255 
00256   field->_number = get_num_inherited_fields();
00257   _fields.push_back(field);
00258   return true;
00259 }

Generated on Fri May 2 01:37:02 2003 for Direct by doxygen1.3