00001 // Filename: dcMolecularField.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 "dcMolecularField.h" 00016 #include "dcAtomicField.h" 00017 #include "hashGenerator.h" 00018 #include "dcindent.h" 00019 00020 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: DCMolecularField::Constructor 00024 // Access: Public 00025 // Description: 00026 //////////////////////////////////////////////////////////////////// 00027 DCMolecularField:: 00028 DCMolecularField(const string &name, DCClass *dclass) : DCField(name, dclass) { 00029 _got_keywords = false; 00030 } 00031 00032 //////////////////////////////////////////////////////////////////// 00033 // Function: DCMolecularField::as_molecular_field 00034 // Access: Published, Virtual 00035 // Description: Returns the same field pointer converted to a 00036 // molecular field pointer, if this is in fact a 00037 // molecular field; otherwise, returns NULL. 00038 //////////////////////////////////////////////////////////////////// 00039 DCMolecularField *DCMolecularField:: 00040 as_molecular_field() { 00041 return this; 00042 } 00043 00044 //////////////////////////////////////////////////////////////////// 00045 // Function: DCMolecularField::as_molecular_field 00046 // Access: Published, Virtual 00047 // Description: Returns the same field pointer converted to a 00048 // molecular field pointer, if this is in fact a 00049 // molecular field; otherwise, returns NULL. 00050 //////////////////////////////////////////////////////////////////// 00051 const DCMolecularField *DCMolecularField:: 00052 as_molecular_field() const { 00053 return this; 00054 } 00055 00056 //////////////////////////////////////////////////////////////////// 00057 // Function: DCMolecularField::get_num_atomics 00058 // Access: Published 00059 // Description: Returns the number of atomic fields that make up this 00060 // molecular field. 00061 //////////////////////////////////////////////////////////////////// 00062 int DCMolecularField:: 00063 get_num_atomics() const { 00064 return _fields.size(); 00065 } 00066 00067 //////////////////////////////////////////////////////////////////// 00068 // Function: DCMolecularField::get_atomic 00069 // Access: Published 00070 // Description: Returns the nth atomic field that makes up this 00071 // molecular field. This may or may not be a field of 00072 // this particular class; it might be defined in a 00073 // parent class. 00074 //////////////////////////////////////////////////////////////////// 00075 DCAtomicField *DCMolecularField:: 00076 get_atomic(int n) const { 00077 nassertr(n >= 0 && n < (int)_fields.size(), NULL); 00078 return _fields[n]; 00079 } 00080 00081 //////////////////////////////////////////////////////////////////// 00082 // Function: DCMolecularField::add_atomic 00083 // Access: Public 00084 // Description: Adds the indicated atomic field to the end of the 00085 // list of atomic fields that make up the molecular 00086 // field. This is normally called only during parsing 00087 // of the dc file. The atomic field should be fully 00088 // defined by this point; you should not modify the 00089 // atomic field (e.g. by adding more elements) after 00090 // adding it to a molecular field. 00091 //////////////////////////////////////////////////////////////////// 00092 void DCMolecularField:: 00093 add_atomic(DCAtomicField *atomic) { 00094 if (!atomic->is_bogus_field()) { 00095 if (!_got_keywords) { 00096 // The first non-bogus atomic field determines our keywords. 00097 copy_keywords(*atomic); 00098 _got_keywords = true; 00099 } 00100 } 00101 _fields.push_back(atomic); 00102 00103 int num_atomic_fields = atomic->get_num_nested_fields(); 00104 for (int i = 0; i < num_atomic_fields; i++) { 00105 _nested_fields.push_back(atomic->get_nested_field(i)); 00106 } 00107 00108 _num_nested_fields = _nested_fields.size(); 00109 00110 // See if we still have a fixed byte size. 00111 if (_has_fixed_byte_size) { 00112 _has_fixed_byte_size = atomic->has_fixed_byte_size(); 00113 _fixed_byte_size += atomic->get_fixed_byte_size(); 00114 } 00115 if (_has_fixed_structure) { 00116 _has_fixed_structure = atomic->has_fixed_structure(); 00117 } 00118 if (!_has_range_limits) { 00119 _has_range_limits = atomic->has_range_limits(); 00120 } 00121 if (!_has_default_value) { 00122 _has_default_value = atomic->has_default_value(); 00123 } 00124 _default_value_stale = true; 00125 } 00126 00127 //////////////////////////////////////////////////////////////////// 00128 // Function: DCMolecularField::output 00129 // Access: Public, Virtual 00130 // Description: 00131 //////////////////////////////////////////////////////////////////// 00132 void DCMolecularField:: 00133 output(ostream &out, bool brief) const { 00134 out << _name; 00135 00136 if (!_fields.empty()) { 00137 Fields::const_iterator fi = _fields.begin(); 00138 out << " : " << (*fi)->get_name(); 00139 ++fi; 00140 while (fi != _fields.end()) { 00141 out << ", " << (*fi)->get_name(); 00142 ++fi; 00143 } 00144 } 00145 00146 out << ";"; 00147 } 00148 00149 //////////////////////////////////////////////////////////////////// 00150 // Function: DCMolecularField::write 00151 // Access: Public, Virtual 00152 // Description: Generates a parseable description of the object to 00153 // the indicated output stream. 00154 //////////////////////////////////////////////////////////////////// 00155 void DCMolecularField:: 00156 write(ostream &out, bool brief, int indent_level) const { 00157 indent(out, indent_level); 00158 output(out, brief); 00159 if (!brief) { 00160 out << " // field " << _number; 00161 } 00162 out << "\n"; 00163 } 00164 00165 00166 //////////////////////////////////////////////////////////////////// 00167 // Function: DCMolecularField::generate_hash 00168 // Access: Public, Virtual 00169 // Description: Accumulates the properties of this field into the 00170 // hash. 00171 //////////////////////////////////////////////////////////////////// 00172 void DCMolecularField:: 00173 generate_hash(HashGenerator &hashgen) const { 00174 DCField::generate_hash(hashgen); 00175 00176 hashgen.add_int(_fields.size()); 00177 Fields::const_iterator fi; 00178 for (fi = _fields.begin(); fi != _fields.end(); ++fi) { 00179 (*fi)->generate_hash(hashgen); 00180 } 00181 } 00182 00183 //////////////////////////////////////////////////////////////////// 00184 // Function: DCMolecularField::get_nested_field 00185 // Access: Public, Virtual 00186 // Description: Returns the DCPackerInterface object that represents 00187 // the nth nested field. This may return NULL if there 00188 // is no such field (but it shouldn't do this if n is in 00189 // the range 0 <= n < get_num_nested_fields()). 00190 //////////////////////////////////////////////////////////////////// 00191 DCPackerInterface *DCMolecularField:: 00192 get_nested_field(int n) const { 00193 nassertr(n >= 0 && n < (int)_nested_fields.size(), NULL); 00194 return _nested_fields[n]; 00195 } 00196 00197 //////////////////////////////////////////////////////////////////// 00198 // Function: DCMolecularField::do_check_match 00199 // Access: Protected, Virtual 00200 // Description: Returns true if the other interface is bitwise the 00201 // same as this one--that is, a uint32 only matches a 00202 // uint32, etc. Names of components, and range limits, 00203 // are not compared. 00204 //////////////////////////////////////////////////////////////////// 00205 bool DCMolecularField:: 00206 do_check_match(const DCPackerInterface *other) const { 00207 return other->do_check_match_molecular_field(this); 00208 } 00209 00210 //////////////////////////////////////////////////////////////////// 00211 // Function: DCMolecularField::do_check_match_molecular_field 00212 // Access: Protected, Virtual 00213 // Description: Returns true if this field matches the indicated 00214 // molecular field, false otherwise. 00215 //////////////////////////////////////////////////////////////////// 00216 bool DCMolecularField:: 00217 do_check_match_molecular_field(const DCMolecularField *other) const { 00218 if (_nested_fields.size() != other->_nested_fields.size()) { 00219 return false; 00220 } 00221 for (size_t i = 0; i < _nested_fields.size(); i++) { 00222 if (!_nested_fields[i]->check_match(other->_nested_fields[i])) { 00223 return false; 00224 } 00225 } 00226 00227 return true; 00228 }