Panda3D

dcAtomicField.cxx

00001 // Filename: dcAtomicField.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 "dcAtomicField.h"
00016 #include "hashGenerator.h"
00017 #include "dcindent.h"
00018 #include "dcSimpleParameter.h"
00019 #include "dcPacker.h"
00020 
00021 #include <math.h>
00022 
00023 ////////////////////////////////////////////////////////////////////
00024 //     Function: DCAtomicField::Constructor
00025 //       Access: Public
00026 //  Description:
00027 ////////////////////////////////////////////////////////////////////
00028 DCAtomicField::
00029 DCAtomicField(const string &name, DCClass *dclass,
00030               bool bogus_field) : 
00031   DCField(name, dclass)
00032 {
00033   _bogus_field = bogus_field;
00034 }
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //     Function: DCAtomicField::Destructor
00038 //       Access: Public, Virtual
00039 //  Description:
00040 ////////////////////////////////////////////////////////////////////
00041 DCAtomicField::
00042 ~DCAtomicField() {
00043   Elements::iterator ei;  
00044   for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
00045     delete (*ei);
00046   }
00047   _elements.clear();
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: DCAtomicField::as_atomic_field
00052 //       Access: Published, Virtual
00053 //  Description: Returns the same field pointer converted to an atomic
00054 //               field pointer, if this is in fact an atomic field;
00055 //               otherwise, returns NULL.
00056 ////////////////////////////////////////////////////////////////////
00057 DCAtomicField *DCAtomicField::
00058 as_atomic_field() {
00059   return this;
00060 }
00061 
00062 ////////////////////////////////////////////////////////////////////
00063 //     Function: DCAtomicField::as_atomic_field
00064 //       Access: Published, Virtual
00065 //  Description: Returns the same field pointer converted to an atomic
00066 //               field pointer, if this is in fact an atomic field;
00067 //               otherwise, returns NULL.
00068 ////////////////////////////////////////////////////////////////////
00069 const DCAtomicField *DCAtomicField::
00070 as_atomic_field() const {
00071   return this;
00072 }
00073 
00074 ////////////////////////////////////////////////////////////////////
00075 //     Function: DCAtomicField::get_num_elements
00076 //       Access: Published
00077 //  Description: Returns the number of elements (parameters) of the
00078 //               atomic field.
00079 ////////////////////////////////////////////////////////////////////
00080 int DCAtomicField::
00081 get_num_elements() const {
00082   return _elements.size();
00083 }
00084 
00085 ////////////////////////////////////////////////////////////////////
00086 //     Function: DCAtomicField::get_element
00087 //       Access: Published
00088 //  Description: Returns the parameter object describing the
00089 //               nth element.
00090 ////////////////////////////////////////////////////////////////////
00091 DCParameter *DCAtomicField::
00092 get_element(int n) const {
00093   nassertr(n >= 0 && n < (int)_elements.size(), NULL);
00094   return _elements[n];
00095 }
00096 
00097 ////////////////////////////////////////////////////////////////////
00098 //     Function: DCAtomicField::get_element_default
00099 //       Access: Published
00100 //  Description: Returns the pre-formatted default value associated
00101 //               with the nth element of the field.  This is only
00102 //               valid if has_element_default() returns true, in which
00103 //               case this string represents the bytes that should be
00104 //               assigned to the field as a default value.
00105 //
00106 //               If the element is an array-type element, the returned
00107 //               value will include the two-byte length preceding the
00108 //               array data.
00109 //
00110 //               This is deprecated; use get_element() instead.
00111 ////////////////////////////////////////////////////////////////////
00112 string DCAtomicField::
00113 get_element_default(int n) const {
00114   nassertr(n >= 0 && n < (int)_elements.size(), string());
00115   return _elements[n]->get_default_value();
00116 }
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: DCAtomicField::has_element_default
00120 //       Access: Published
00121 //  Description: Returns true if the nth element of the field has a
00122 //               default value specified, false otherwise.
00123 //
00124 //               This is deprecated; use get_element() instead.
00125 ////////////////////////////////////////////////////////////////////
00126 bool DCAtomicField::
00127 has_element_default(int n) const {
00128   nassertr(n >= 0 && n < (int)_elements.size(), false);
00129   return _elements[n]->has_default_value();
00130 }
00131 
00132 ////////////////////////////////////////////////////////////////////
00133 //     Function: DCAtomicField::get_element_name
00134 //       Access: Published
00135 //  Description: Returns the name of the nth element of the field.
00136 //               This name is strictly for documentary purposes; it
00137 //               does not generally affect operation.  If a name is
00138 //               not specified, this will be the empty string.
00139 //
00140 //               This method is deprecated; use
00141 //               get_element()->get_name() instead.
00142 ////////////////////////////////////////////////////////////////////
00143 string DCAtomicField::
00144 get_element_name(int n) const {
00145   nassertr(n >= 0 && n < (int)_elements.size(), string());
00146   return _elements[n]->get_name();
00147 }
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 //     Function: DCAtomicField::get_element_type
00151 //       Access: Published
00152 //  Description: Returns the numeric type of the nth element of the
00153 //               field.  This method is deprecated; use
00154 //               get_element() instead.
00155 ////////////////////////////////////////////////////////////////////
00156 DCSubatomicType DCAtomicField::
00157 get_element_type(int n) const {
00158   nassertr(n >= 0 && n < (int)_elements.size(), ST_invalid);
00159   DCSimpleParameter *simple_parameter = _elements[n]->as_simple_parameter();
00160   nassertr(simple_parameter != (DCSimpleParameter *)NULL, ST_invalid);
00161   return simple_parameter->get_type();
00162 }
00163 
00164 ////////////////////////////////////////////////////////////////////
00165 //     Function: DCAtomicField::get_element_divisor
00166 //       Access: Published
00167 //  Description: Returns the divisor associated with the nth element
00168 //               of the field.  This implements an implicit
00169 //               fixed-point system; floating-point values are to be
00170 //               multiplied by this value before encoding into a
00171 //               packet, and divided by this number after decoding.
00172 //
00173 //               This method is deprecated; use
00174 //               get_element()->get_divisor() instead.
00175 ////////////////////////////////////////////////////////////////////
00176 int DCAtomicField::
00177 get_element_divisor(int n) const {
00178   nassertr(n >= 0 && n < (int)_elements.size(), 1);
00179   DCSimpleParameter *simple_parameter = _elements[n]->as_simple_parameter();
00180   nassertr(simple_parameter != (DCSimpleParameter *)NULL, 1);
00181   return simple_parameter->get_divisor();
00182 }
00183 
00184 ////////////////////////////////////////////////////////////////////
00185 //     Function: DCAtomicField::output
00186 //       Access: Public, Virtual
00187 //  Description: 
00188 ////////////////////////////////////////////////////////////////////
00189 void DCAtomicField::
00190 output(ostream &out, bool brief) const {
00191   out << _name << "(";
00192 
00193   if (!_elements.empty()) {
00194     Elements::const_iterator ei = _elements.begin();
00195     output_element(out, brief, *ei);
00196     ++ei;
00197     while (ei != _elements.end()) {
00198       out << ", ";
00199       output_element(out, brief, *ei);
00200       ++ei;
00201     }
00202   }
00203   out << ")";
00204 
00205   output_keywords(out);
00206 }
00207 
00208 ////////////////////////////////////////////////////////////////////
00209 //     Function: DCAtomicField::write
00210 //       Access: Public, Virtual
00211 //  Description: Generates a parseable description of the object to
00212 //               the indicated output stream.
00213 ////////////////////////////////////////////////////////////////////
00214 void DCAtomicField::
00215 write(ostream &out, bool brief, int indent_level) const {
00216   indent(out, indent_level);
00217   output(out, brief);
00218   out << ";";
00219   if (!brief && _number >= 0) {
00220     out << "  // field " << _number;
00221   }
00222   out << "\n";
00223 }
00224 
00225 ////////////////////////////////////////////////////////////////////
00226 //     Function: DCAtomicField::generate_hash
00227 //       Access: Public, Virtual
00228 //  Description: Accumulates the properties of this field into the
00229 //               hash.
00230 ////////////////////////////////////////////////////////////////////
00231 void DCAtomicField::
00232 generate_hash(HashGenerator &hashgen) const {
00233   DCField::generate_hash(hashgen);
00234 
00235   hashgen.add_int(_elements.size());
00236   Elements::const_iterator ei;
00237   for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
00238     (*ei)->generate_hash(hashgen);
00239   }
00240 
00241   DCKeywordList::generate_hash(hashgen);
00242 }
00243 
00244 ////////////////////////////////////////////////////////////////////
00245 //     Function: DCAtomicField::get_nested_field
00246 //       Access: Public, Virtual
00247 //  Description: Returns the DCPackerInterface object that represents
00248 //               the nth nested field.  This may return NULL if there
00249 //               is no such field (but it shouldn't do this if n is in
00250 //               the range 0 <= n < get_num_nested_fields()).
00251 ////////////////////////////////////////////////////////////////////
00252 DCPackerInterface *DCAtomicField::
00253 get_nested_field(int n) const {
00254   nassertr(n >= 0 && n < (int)_elements.size(), NULL);
00255   return _elements[n];
00256 }
00257 
00258 ////////////////////////////////////////////////////////////////////
00259 //     Function: DCAtomicField::add_element
00260 //       Access: Public
00261 //  Description: Adds a new element (parameter) to the field.
00262 //               Normally this is called only during parsing.  The
00263 //               DCAtomicField object becomes the owner of the new
00264 //               pointer and will delete it upon destruction.
00265 ////////////////////////////////////////////////////////////////////
00266 void DCAtomicField::
00267 add_element(DCParameter *element) {
00268   _elements.push_back(element);
00269   _num_nested_fields = (int)_elements.size();
00270 
00271   // See if we still have a fixed byte size.
00272   if (_has_fixed_byte_size) {
00273     _has_fixed_byte_size = element->has_fixed_byte_size();
00274     _fixed_byte_size += element->get_fixed_byte_size();
00275   }
00276   if (_has_fixed_structure) {
00277     _has_fixed_structure = element->has_fixed_structure();
00278   }
00279   if (!_has_range_limits) {
00280     _has_range_limits = element->has_range_limits();
00281   }
00282   if (!_has_default_value) {
00283     _has_default_value = element->has_default_value();
00284   }
00285   _default_value_stale = true;
00286 }
00287 
00288 ////////////////////////////////////////////////////////////////////
00289 //     Function: DCAtomicField::do_check_match
00290 //       Access: Protected, Virtual
00291 //  Description: Returns true if the other interface is bitwise the
00292 //               same as this one--that is, a uint32 only matches a
00293 //               uint32, etc. Names of components, and range limits,
00294 //               are not compared.
00295 ////////////////////////////////////////////////////////////////////
00296 bool DCAtomicField::
00297 do_check_match(const DCPackerInterface *other) const {
00298   return other->do_check_match_atomic_field(this);
00299 }
00300 
00301 ////////////////////////////////////////////////////////////////////
00302 //     Function: DCAtomicField::do_check_match_atomic_field
00303 //       Access: Protected, Virtual
00304 //  Description: Returns true if this field matches the indicated
00305 //               atomic field, false otherwise.
00306 ////////////////////////////////////////////////////////////////////
00307 bool DCAtomicField::
00308 do_check_match_atomic_field(const DCAtomicField *other) const {
00309   if (_elements.size() != other->_elements.size()) {
00310     return false;
00311   }
00312   for (size_t i = 0; i < _elements.size(); i++) {
00313     if (!_elements[i]->check_match(other->_elements[i])) {
00314       return false;
00315     }
00316   }
00317 
00318   return true;
00319 }
00320 
00321 ////////////////////////////////////////////////////////////////////
00322 //     Function: DCAtomicField::output_element
00323 //       Access: Private
00324 //  Description: 
00325 ////////////////////////////////////////////////////////////////////
00326 void DCAtomicField::
00327 output_element(ostream &out, bool brief, DCParameter *element) const {
00328   element->output(out, brief);
00329 
00330   if (!brief && element->has_default_value()) {
00331     out << " = ";
00332     DCPacker packer;
00333     packer.set_unpack_data(element->get_default_value());
00334     packer.begin_unpack(element);
00335     packer.unpack_and_format(out, false);
00336     packer.end_unpack();
00337   }
00338 }
 All Classes Functions Variables Enumerations