Panda3D
 All Classes Functions Variables Enumerations
dcMolecularField.cxx
1 // Filename: dcMolecularField.cxx
2 // Created by: drose (05Oct00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "dcMolecularField.h"
16 #include "dcAtomicField.h"
17 #include "hashGenerator.h"
18 #include "dcindent.h"
19 
20 
21 
22 ////////////////////////////////////////////////////////////////////
23 // Function: DCMolecularField::Constructor
24 // Access: Public
25 // Description:
26 ////////////////////////////////////////////////////////////////////
27 DCMolecularField::
28 DCMolecularField(const string &name, DCClass *dclass) : DCField(name, dclass) {
29  _got_keywords = false;
30 }
31 
32 ////////////////////////////////////////////////////////////////////
33 // Function: DCMolecularField::as_molecular_field
34 // Access: Published, Virtual
35 // Description: Returns the same field pointer converted to a
36 // molecular field pointer, if this is in fact a
37 // molecular field; otherwise, returns NULL.
38 ////////////////////////////////////////////////////////////////////
41  return this;
42 }
43 
44 ////////////////////////////////////////////////////////////////////
45 // Function: DCMolecularField::as_molecular_field
46 // Access: Published, Virtual
47 // Description: Returns the same field pointer converted to a
48 // molecular field pointer, if this is in fact a
49 // molecular field; otherwise, returns NULL.
50 ////////////////////////////////////////////////////////////////////
53  return this;
54 }
55 
56 ////////////////////////////////////////////////////////////////////
57 // Function: DCMolecularField::get_num_atomics
58 // Access: Published
59 // Description: Returns the number of atomic fields that make up this
60 // molecular field.
61 ////////////////////////////////////////////////////////////////////
63 get_num_atomics() const {
64  return _fields.size();
65 }
66 
67 ////////////////////////////////////////////////////////////////////
68 // Function: DCMolecularField::get_atomic
69 // Access: Published
70 // Description: Returns the nth atomic field that makes up this
71 // molecular field. This may or may not be a field of
72 // this particular class; it might be defined in a
73 // parent class.
74 ////////////////////////////////////////////////////////////////////
76 get_atomic(int n) const {
77  nassertr(n >= 0 && n < (int)_fields.size(), NULL);
78  return _fields[n];
79 }
80 
81 ////////////////////////////////////////////////////////////////////
82 // Function: DCMolecularField::add_atomic
83 // Access: Public
84 // Description: Adds the indicated atomic field to the end of the
85 // list of atomic fields that make up the molecular
86 // field. This is normally called only during parsing
87 // of the dc file. The atomic field should be fully
88 // defined by this point; you should not modify the
89 // atomic field (e.g. by adding more elements) after
90 // adding it to a molecular field.
91 ////////////////////////////////////////////////////////////////////
94  if (!atomic->is_bogus_field()) {
95  if (!_got_keywords) {
96  // The first non-bogus atomic field determines our keywords.
97  copy_keywords(*atomic);
98  _got_keywords = true;
99  }
100  }
101  _fields.push_back(atomic);
102 
103  int num_atomic_fields = atomic->get_num_nested_fields();
104  for (int i = 0; i < num_atomic_fields; i++) {
105  _nested_fields.push_back(atomic->get_nested_field(i));
106  }
107 
108  _num_nested_fields = _nested_fields.size();
109 
110  // See if we still have a fixed byte size.
111  if (_has_fixed_byte_size) {
112  _has_fixed_byte_size = atomic->has_fixed_byte_size();
113  _fixed_byte_size += atomic->get_fixed_byte_size();
114  }
115  if (_has_fixed_structure) {
116  _has_fixed_structure = atomic->has_fixed_structure();
117  }
118  if (!_has_range_limits) {
119  _has_range_limits = atomic->has_range_limits();
120  }
121  if (!_has_default_value) {
122  _has_default_value = atomic->has_default_value();
123  }
124  _default_value_stale = true;
125 }
126 
127 ////////////////////////////////////////////////////////////////////
128 // Function: DCMolecularField::output
129 // Access: Public, Virtual
130 // Description:
131 ////////////////////////////////////////////////////////////////////
132 void DCMolecularField::
133 output(ostream &out, bool brief) const {
134  out << _name;
135 
136  if (!_fields.empty()) {
137  Fields::const_iterator fi = _fields.begin();
138  out << " : " << (*fi)->get_name();
139  ++fi;
140  while (fi != _fields.end()) {
141  out << ", " << (*fi)->get_name();
142  ++fi;
143  }
144  }
145 
146  out << ";";
147 }
148 
149 ////////////////////////////////////////////////////////////////////
150 // Function: DCMolecularField::write
151 // Access: Public, Virtual
152 // Description: Generates a parseable description of the object to
153 // the indicated output stream.
154 ////////////////////////////////////////////////////////////////////
156 write(ostream &out, bool brief, int indent_level) const {
157  indent(out, indent_level);
158  output(out, brief);
159  if (!brief) {
160  out << " // field " << _number;
161  }
162  out << "\n";
163 }
164 
165 
166 ////////////////////////////////////////////////////////////////////
167 // Function: DCMolecularField::generate_hash
168 // Access: Public, Virtual
169 // Description: Accumulates the properties of this field into the
170 // hash.
171 ////////////////////////////////////////////////////////////////////
173 generate_hash(HashGenerator &hashgen) const {
174  DCField::generate_hash(hashgen);
175 
176  hashgen.add_int(_fields.size());
177  Fields::const_iterator fi;
178  for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
179  (*fi)->generate_hash(hashgen);
180  }
181 }
182 
183 ////////////////////////////////////////////////////////////////////
184 // Function: DCMolecularField::get_nested_field
185 // Access: Public, Virtual
186 // Description: Returns the DCPackerInterface object that represents
187 // the nth nested field. This may return NULL if there
188 // is no such field (but it shouldn't do this if n is in
189 // the range 0 <= n < get_num_nested_fields()).
190 ////////////////////////////////////////////////////////////////////
192 get_nested_field(int n) const {
193  nassertr(n >= 0 && n < (int)_nested_fields.size(), NULL);
194  return _nested_fields[n];
195 }
196 
197 ////////////////////////////////////////////////////////////////////
198 // Function: DCMolecularField::do_check_match
199 // Access: Protected, Virtual
200 // Description: Returns true if the other interface is bitwise the
201 // same as this one--that is, a uint32 only matches a
202 // uint32, etc. Names of components, and range limits,
203 // are not compared.
204 ////////////////////////////////////////////////////////////////////
205 bool DCMolecularField::
206 do_check_match(const DCPackerInterface *other) const {
207  return other->do_check_match_molecular_field(this);
208 }
209 
210 ////////////////////////////////////////////////////////////////////
211 // Function: DCMolecularField::do_check_match_molecular_field
212 // Access: Protected, Virtual
213 // Description: Returns true if this field matches the indicated
214 // molecular field, false otherwise.
215 ////////////////////////////////////////////////////////////////////
216 bool DCMolecularField::
217 do_check_match_molecular_field(const DCMolecularField *other) const {
218  if (_nested_fields.size() != other->_nested_fields.size()) {
219  return false;
220  }
221  for (size_t i = 0; i < _nested_fields.size(); i++) {
222  if (!_nested_fields[i]->check_match(other->_nested_fields[i])) {
223  return false;
224  }
225  }
226 
227  return true;
228 }
void add_atomic(DCAtomicField *atomic)
Adds the indicated atomic field to the end of the list of atomic fields that make up the molecular fi...
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this field into the hash.
Definition: dcField.cxx:524
DCAtomicField * get_atomic(int n) const
Returns the nth atomic field that makes up this molecular field.
virtual void write(ostream &out, bool brief, int indent_level) const
Generates a parseable description of the object to the indicated output stream.
virtual DCMolecularField * as_molecular_field()
Returns the same field pointer converted to a molecular field pointer, if this is in fact a molecular...
bool is_bogus_field() const
Returns true if the field has been flagged as a bogus field.
Definition: dcField.I:77
void add_int(int num)
Adds another integer to the hash so far.
A single field of a Distributed Class, either atomic or molecular.
Definition: dcField.h:40
bool has_default_value() const
Returns true if a default value has been explicitly established for this field, false otherwise...
Definition: dcField.I:46
int get_num_nested_fields() const
Returns the number of nested fields required by this field type.
size_t get_fixed_byte_size() const
If has_fixed_byte_size() returns true, this returns the number of bytes this field type will use...
Defines a particular DistributedClass as read from an input .dc file.
Definition: dcClass.h:47
bool has_range_limits() const
Returns true if this field, or any sub-field of this field, has a limit imposed in the DC file on its...
A single atomic field of a Distributed Class, as read from a .dc file.
Definition: dcAtomicField.h:34
virtual void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this field into the hash.
virtual DCPackerInterface * get_nested_field(int n) const
Returns the DCPackerInterface object that represents the nth nested field.
virtual bool do_check_match_molecular_field(const DCMolecularField *other) const
Returns true if this field matches the indicated molecular field, false otherwise.
This class generates an arbitrary hash number from a sequence of ints.
Definition: hashGenerator.h:26
void copy_keywords(const DCKeywordList &other)
Replaces this keyword list with those from the other list.
bool has_fixed_structure() const
Returns true if this field type always has the same structure regardless of the data in the stream...
bool check_match(const DCPackerInterface *other) const
Returns true if the other interface is bitwise the same as this one–that is, a uint32 only matches a ...
int get_num_atomics() const
Returns the number of atomic fields that make up this molecular field.
A single molecular field of a Distributed Class, as read from a .dc file.
This defines the internal interface for packing values into a DCField.
virtual DCPackerInterface * get_nested_field(int n) const
Returns the DCPackerInterface object that represents the nth nested field.
bool has_fixed_byte_size() const
Returns true if this field type always packs to the same number of bytes, false if it is variable...