Panda3D
xFileDataNodeTemplate.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file xFileDataNodeTemplate.cxx
10  * @author drose
11  * @date 2004-10-03
12  */
13 
14 #include "xFileDataNodeTemplate.h"
15 #include "indent.h"
16 #include "xFileParseData.h"
17 #include "xLexerDefs.h"
18 #include "config_xfile.h"
19 
20 using std::string;
21 
22 TypeHandle XFileDataNodeTemplate::_type_handle;
23 
24 /**
25  *
26  */
27 XFileDataNodeTemplate::
28 XFileDataNodeTemplate(XFile *x_file, const string &name,
29  XFileTemplate *xtemplate) :
30  XFileDataNode(x_file, name, xtemplate)
31 {
32 }
33 
34 /**
35  * Fills the data node with zero-valued elements appropriate to the template.
36  */
39  _template->fill_zero_data(this);
40 }
41 
42 /**
43  * Returns true if this kind of data object is a complex object that can hold
44  * nested data elements, false otherwise.
45  */
48  return true;
49 }
50 
51 /**
52  * Adds the indicated list of doubles as a data element encountered in the
53  * parser. It will later be processed by finalize_parse_data().
54  */
56 add_parse_double(PTA_double double_list) {
57  XFileParseData pdata;
58  pdata._double_list = double_list;
59  pdata._parse_flags = XFileParseData::PF_double;
60 
61  _parse_data_list._list.push_back(pdata);
62 }
63 
64 /**
65  * Adds the indicated list of ints as a data element encountered in the
66  * parser. It will later be processed by finalize_parse_data().
67  */
69 add_parse_int(PTA_int int_list) {
70  XFileParseData pdata;
71  pdata._int_list = int_list;
72  pdata._parse_flags = XFileParseData::PF_int;
73 
74  _parse_data_list._list.push_back(pdata);
75 }
76 
77 /**
78  * Adds the indicated string as a data element encountered in the parser. It
79  * will later be processed by finalize_parse_data().
80  */
82 add_parse_string(const string &str) {
83  XFileParseData pdata;
84  pdata._string = str;
85  pdata._parse_flags = XFileParseData::PF_string;
86 
87  _parse_data_list._list.push_back(pdata);
88 }
89 
90 /**
91  * Processes all of the data elements added by add_parse_*(), checks them for
92  * syntactic and semantic correctness against the Template definition, and
93  * stores the appropriate child data elements. Returns true on success, false
94  * if there is a mismatch.
95  */
98  // Recursively walk through our template definition, while simultaneously
99  // walking through the list of parse data elements we encountered, and re-
100  // pack them as actual nested elements.
101  PrevData prev_data;
102  size_t index = 0;
103  size_t sub_index = 0;
104 
105  if (!_template->repack_data(this, _parse_data_list,
106  prev_data, index, sub_index)) {
107  return false;
108  }
109 
110  if (index != _parse_data_list._list.size()) {
111  xyywarning("Too many data elements in structure.");
112  }
113 
114  return true;
115 }
116 
117 /**
118  * Adds the indicated element as a nested data element, if this data object
119  * type supports it. Returns true if added successfully, false if the data
120  * object type does not support nested data elements.
121  */
124  _nested_elements.push_back(element);
125  return true;
126 }
127 
128 /**
129  * Writes a suitable representation of this node to an .x file in text mode.
130  */
132 write_text(std::ostream &out, int indent_level) const {
133  indent(out, indent_level)
134  << _template->get_name();
135  if (has_name()) {
136  out << " " << get_name();
137  }
138  out << " {\n";
139 
140  NestedElements::const_iterator ni;
141  for (ni = _nested_elements.begin(); ni != _nested_elements.end(); ++ni) {
142  (*ni)->write_data(out, indent_level + 2, ";");
143  }
144 
145  XFileNode::write_text(out, indent_level + 2);
146  indent(out, indent_level)
147  << "}\n";
148 }
149 
150 /**
151  * Writes a suitable representation of this node to an .x file in text mode.
152  */
154 write_data(std::ostream &out, int indent_level, const char *separator) const {
155  if (!_nested_elements.empty()) {
156  bool indented = false;
157  for (size_t i = 0; i < _nested_elements.size() - 1; i++) {
158  XFileDataObject *object = _nested_elements[i];
159  if (object->is_complex_object()) {
160  // If we have a "complex" nested object, output it on its own line.
161  if (indented) {
162  out << "\n";
163  indented = false;
164  }
165  object->write_data(out, indent_level, ";");
166 
167  } else {
168  // Otherwise, output them all on the same line.
169  if (!indented) {
170  indent(out, indent_level);
171  indented = true;
172  }
173  out << *object << "; ";
174  }
175  }
176 
177  // The last object is the set is different, because it gets separator
178  // appended to it, and it always gets a newline.
179  XFileDataObject *object = _nested_elements.back();
180  if (object->is_complex_object()) {
181  if (indented) {
182  out << "\n";
183  }
184  string combined_separator = string(";") + string(separator);
185  object->write_data(out, indent_level, combined_separator.c_str());
186 
187  } else {
188  if (!indented) {
189  indent(out, indent_level);
190  }
191  out << *object << ";" << separator << "\n";
192  }
193  }
194 }
195 
196 /**
197  * Returns the number of nested data elements within the object. This may be,
198  * e.g. the size of the array, if it is an array.
199  */
200 int XFileDataNodeTemplate::
201 get_num_elements() const {
202  return _nested_elements.size();
203 }
204 
205 /**
206  * Returns the nth nested data element within the object.
207  */
208 XFileDataObject *XFileDataNodeTemplate::
209 get_element(int n) {
210  nassertr(n >= 0 && n < (int)_nested_elements.size(), nullptr);
211  return _nested_elements[n];
212 }
213 
214 /**
215  * Returns the nested data element within the object that has the indicated
216  * name.
217  */
218 XFileDataObject *XFileDataNodeTemplate::
219 get_element(const string &name) {
220  int child_index = _template->find_child_index(name);
221  if (child_index >= 0) {
222  return get_element(child_index);
223  }
224  xfile_cat.warning()
225  << "\"" << name << "\" not a member of " << _template->get_name()
226  << "\n";
227  return nullptr;
228 }
config_xfile.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
indent
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
XFileDataNodeTemplate::write_data
virtual void write_data(std::ostream &out, int indent_level, const char *separator) const
Writes a suitable representation of this node to an .x file in text mode.
Definition: xFileDataNodeTemplate.cxx:154
XFileDataNodeTemplate::add_parse_int
void add_parse_int(PTA_int int_list)
Adds the indicated list of ints as a data element encountered in the parser.
Definition: xFileDataNodeTemplate.cxx:69
XFileDataObject
The abstract base class for a number of different types of data elements that may be stored in the X ...
Definition: xFileDataObject.h:30
pmap
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
xFileDataNodeTemplate.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFile
This represents the complete contents of an X file (file.x) in memory.
Definition: xFile.h:32
xLexerDefs.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFileDataNodeTemplate::add_element
virtual bool add_element(XFileDataObject *element)
Adds the indicated element as a nested data element, if this data object type supports it.
Definition: xFileDataNodeTemplate.cxx:123
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
XFileDataNodeTemplate::add_parse_double
void add_parse_double(PTA_double double_list)
Adds the indicated list of doubles as a data element encountered in the parser.
Definition: xFileDataNodeTemplate.cxx:56
xFileParseData.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFileTemplate
A template definition in the X file.
Definition: xFileTemplate.h:27
Namable::has_name
bool has_name() const
Returns true if the Namable has a nonempty name set, false if the name is empty.
Definition: namable.I:44
XFileDataNodeTemplate::is_complex_object
virtual bool is_complex_object() const
Returns true if this kind of data object is a complex object that can hold nested data elements,...
Definition: xFileDataNodeTemplate.cxx:47
XFileDataNodeTemplate::write_text
virtual void write_text(std::ostream &out, int indent_level) const
Writes a suitable representation of this node to an .x file in text mode.
Definition: xFileDataNodeTemplate.cxx:132
XFileDataObject::i
int i() const
Unambiguously returns the object's representation as an integer, or 0 if the object has no integer re...
Definition: xFileDataObject.I:178
XFileParseData
This class is used to fill up the data into an XFileDataNodeTemplate object as the data values are pa...
Definition: xFileParseData.h:30
indent.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFileDataNodeTemplate::finalize_parse_data
bool finalize_parse_data()
Processes all of the data elements added by add_parse_*(), checks them for syntactic and semantic cor...
Definition: xFileDataNodeTemplate.cxx:97
XFileDataObject::is_complex_object
virtual bool is_complex_object() const
Returns true if this kind of data object is a complex object that can hold nested data elements,...
Definition: xFileDataObject.cxx:40
XFileDataNodeTemplate::add_parse_string
void add_parse_string(const std::string &str)
Adds the indicated string as a data element encountered in the parser.
Definition: xFileDataNodeTemplate.cxx:82
XFileDataNode
This is an abstract base class for an XFileNode which is also an XFileDataObject.
Definition: xFileDataNode.h:33
XFileNode::write_text
virtual void write_text(std::ostream &out, int indent_level) const
Writes a suitable representation of this node to an .x file in text mode.
Definition: xFileNode.cxx:219
XFileDataNodeTemplate::zero_fill
void zero_fill()
Fills the data node with zero-valued elements appropriate to the template.
Definition: xFileDataNodeTemplate.cxx:38