mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
more parser stuff
This commit is contained in:
parent
8ce7d33fd8
commit
e4bd5e2c46
@ -20,8 +20,12 @@
|
||||
xFileArrayDef.cxx xFileArrayDef.I xFileArrayDef.h \
|
||||
xFileDataDef.cxx xFileDataDef.I xFileDataDef.h \
|
||||
xFileDataObject.cxx xFileDataObject.I xFileDataObject.h \
|
||||
xFileDataObjectArray.cxx xFileDataObjectArray.I xFileDataObjectArray.h \
|
||||
xFileDataObjectDouble.cxx xFileDataObjectDouble.I xFileDataObjectDouble.h \
|
||||
xFileDataObjectInteger.cxx xFileDataObjectInteger.I xFileDataObjectInteger.h \
|
||||
xFileDataObjectTemplate.cxx xFileDataObjectTemplate.I xFileDataObjectTemplate.h \
|
||||
xFileNode.cxx xFileNode.I xFileNode.h \
|
||||
xFileParseData.cxx xFileParseData.I xFileParseData.h \
|
||||
xFileTemplate.cxx xFileTemplate.I xFileTemplate.h
|
||||
|
||||
#end ss_lib_target
|
||||
|
@ -20,6 +20,9 @@
|
||||
#include "xFile.h"
|
||||
#include "xFileDataDef.h"
|
||||
#include "xFileDataObject.h"
|
||||
#include "xFileDataObjectArray.h"
|
||||
#include "xFileDataObjectDouble.h"
|
||||
#include "xFileDataObjectInteger.h"
|
||||
#include "xFileDataObjectTemplate.h"
|
||||
#include "xFileNode.h"
|
||||
#include "xFileTemplate.h"
|
||||
@ -58,6 +61,9 @@ init_libxfile() {
|
||||
XFile::init_type();
|
||||
XFileDataDef::init_type();
|
||||
XFileDataObject::init_type();
|
||||
XFileDataObjectArray::init_type();
|
||||
XFileDataObjectDouble::init_type();
|
||||
XFileDataObjectInteger::init_type();
|
||||
XFileDataObjectTemplate::init_type();
|
||||
XFileNode::init_type();
|
||||
XFileTemplate::init_type();
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "xParserDefs.h"
|
||||
#include "xLexerDefs.h"
|
||||
#include "xFileTemplate.h"
|
||||
#include "xFileDataObject.h"
|
||||
#include "xFileDataObjectTemplate.h"
|
||||
#include "config_xfile.h"
|
||||
#include "standard_templates.h"
|
||||
#include "zStream.h"
|
||||
@ -250,12 +250,12 @@ find_template(const WindowsGuid &guid) const {
|
||||
// Description: Returns the data object associated with the indicated
|
||||
// name, if any, or NULL if none.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileDataObject *XFile::
|
||||
XFileDataObjectTemplate *XFile::
|
||||
find_data_object(const string &name) const {
|
||||
XFileNode *child = find_descendent(name);
|
||||
if (child != (XFileNode *)NULL &&
|
||||
child->is_of_type(XFileDataObject::get_class_type())) {
|
||||
return DCAST(XFileDataObject, child);
|
||||
child->is_of_type(XFileDataObjectTemplate::get_class_type())) {
|
||||
return DCAST(XFileDataObjectTemplate, child);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -267,13 +267,13 @@ find_data_object(const string &name) const {
|
||||
// Description: Returns the data object associated with the indicated
|
||||
// GUID, if any, or NULL if none.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileDataObject *XFile::
|
||||
XFileDataObjectTemplate *XFile::
|
||||
find_data_object(const WindowsGuid &guid) const {
|
||||
NodesByGuid::const_iterator gi;
|
||||
gi = _nodes_by_guid.find(guid);
|
||||
if (gi != _nodes_by_guid.end() &&
|
||||
(*gi).second->is_of_type(XFileDataObject::get_class_type())) {
|
||||
return DCAST(XFileDataObject, (*gi).second);
|
||||
(*gi).second->is_of_type(XFileDataObjectTemplate::get_class_type())) {
|
||||
return DCAST(XFileDataObjectTemplate, (*gi).second);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "pointerTo.h"
|
||||
|
||||
class XFileTemplate;
|
||||
class XFileDataObject;
|
||||
class XFileDataObjectTemplate;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFile
|
||||
@ -51,8 +51,8 @@ public:
|
||||
XFileTemplate *find_template(const string &name) const;
|
||||
XFileTemplate *find_template(const WindowsGuid &guid) const;
|
||||
|
||||
XFileDataObject *find_data_object(const string &name) const;
|
||||
XFileDataObject *find_data_object(const WindowsGuid &guid) const;
|
||||
XFileDataObjectTemplate *find_data_object(const string &name) const;
|
||||
XFileDataObjectTemplate *find_data_object(const WindowsGuid &guid) const;
|
||||
|
||||
virtual void write_text(ostream &out, int indent_level) const;
|
||||
|
||||
|
@ -18,6 +18,30 @@
|
||||
|
||||
#include "xFileArrayDef.h"
|
||||
#include "xFileDataDef.h"
|
||||
#include "xFileDataObject.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileArrayDef::get_size
|
||||
// Access: Public
|
||||
// Description: Returns the size of the array dimension. If this is
|
||||
// a fixed array, the size is trivial; if it is dynamic,
|
||||
// the size is determined by looking up the dynamic_size
|
||||
// element in the prev_data table (which lists all of
|
||||
// the data values already defined at this scoping
|
||||
// level).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileArrayDef::
|
||||
get_size(const XFileNode::PrevData &prev_data) const {
|
||||
if (is_fixed_size()) {
|
||||
return _fixed_size;
|
||||
} else {
|
||||
XFileNode::PrevData::const_iterator pi;
|
||||
pi = prev_data.find(_dynamic_size);
|
||||
nassertr(pi != prev_data.end(), 0);
|
||||
nassertr((*pi).second != (XFileDataObject *)NULL, 0);
|
||||
return (*pi).second->i();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileArrayDef::output
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "notify.h"
|
||||
#include "xFileNode.h"
|
||||
|
||||
class XFileDataDef;
|
||||
|
||||
@ -38,6 +39,8 @@ public:
|
||||
INLINE int get_fixed_size() const;
|
||||
INLINE XFileDataDef *get_dynamic_size() const;
|
||||
|
||||
int get_size(const XFileNode::PrevData &prev_data) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
private:
|
||||
|
@ -18,6 +18,12 @@
|
||||
|
||||
#include "xFileDataDef.h"
|
||||
#include "indent.h"
|
||||
#include "xLexerDefs.h"
|
||||
#include "xFileParseData.h"
|
||||
#include "xFileDataObjectInteger.h"
|
||||
#include "xFileDataObjectDouble.h"
|
||||
#include "xFileDataObjectTemplate.h"
|
||||
#include "xFileDataObjectArray.h"
|
||||
|
||||
TypeHandle XFileDataDef::_type_handle;
|
||||
|
||||
@ -128,3 +134,291 @@ write_text(ostream &out, int indent_level) const {
|
||||
|
||||
out << ";\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataDef::repack_data
|
||||
// Access: Public, Virtual
|
||||
// Description: This is called on the template that defines an
|
||||
// object, once the data for the object has been parsed.
|
||||
// It is responsible for identifying which component of
|
||||
// the template owns each data element, and packing the
|
||||
// data elements appropriately back into the object.
|
||||
//
|
||||
// It returns true on success, or false on an error
|
||||
// (e.g. too many semicolons, not enough data elements,
|
||||
// mismatched data type).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileDataDef::
|
||||
repack_data(XFileDataObject *object,
|
||||
const XFileParseDataList &parse_data_list,
|
||||
XFileDataDef::PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index) const {
|
||||
if (index >= parse_data_list._list.size()) {
|
||||
xyyerror("Not enough data elements in structure.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// We'll fill this in with the data value we pack, if any.
|
||||
PT(XFileDataObject) data_value;
|
||||
|
||||
// What kind of data element are we expecting?
|
||||
switch (_type) {
|
||||
case T_word:
|
||||
case T_dword:
|
||||
case T_char:
|
||||
case T_uchar:
|
||||
case T_sword:
|
||||
case T_sdword:
|
||||
// Expected integer data.
|
||||
data_value = unpack_value(parse_data_list, 0,
|
||||
prev_data, index, sub_index,
|
||||
XFileParseData::PF_semicolon,
|
||||
&XFileDataDef::unpack_integer_value);
|
||||
break;
|
||||
|
||||
case T_float:
|
||||
case T_double:
|
||||
data_value = unpack_value(parse_data_list, 0,
|
||||
prev_data, index, sub_index,
|
||||
XFileParseData::PF_semicolon,
|
||||
&XFileDataDef::unpack_double_value);
|
||||
break;
|
||||
|
||||
case T_template:
|
||||
data_value = unpack_value(parse_data_list, 0,
|
||||
prev_data, index, sub_index,
|
||||
XFileParseData::PF_semicolon,
|
||||
&XFileDataDef::unpack_template_value);
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
const XFileParseData &parse_data = parse_data_list._list[index];
|
||||
parse_data.yyerror("Unexpected data for " + get_name());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data_value != (XFileDataObject *)NULL) {
|
||||
if (!object->add_element(data_value)) {
|
||||
// This is really an internal error--this shouldn't happen.
|
||||
const XFileParseData &parse_data = parse_data_list._list[index];
|
||||
parse_data.yyerror("Data does not accept a nested element.");
|
||||
}
|
||||
}
|
||||
prev_data[this] = data_value;
|
||||
|
||||
return XFileNode::repack_data(object, parse_data_list,
|
||||
prev_data, index, sub_index);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataDef::unpack_integer_value
|
||||
// Access: Private
|
||||
// Description: Unpacks and returns the next sequential integer value
|
||||
// from the parse_data_list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(XFileDataObject) XFileDataDef::
|
||||
unpack_integer_value(const XFileParseDataList &parse_data_list,
|
||||
const XFileDataDef::PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index,
|
||||
int separator_mask) const {
|
||||
const XFileParseData &parse_data = parse_data_list._list[index];
|
||||
|
||||
PT(XFileDataObject) data_value;
|
||||
|
||||
if ((parse_data._parse_flags & XFileParseData::PF_int) != 0) {
|
||||
nassertr(sub_index < parse_data._int_list.size(), false);
|
||||
int value = parse_data._int_list[sub_index];
|
||||
data_value = new XFileDataObjectInteger(this, value);
|
||||
|
||||
sub_index++;
|
||||
if (sub_index >= parse_data._int_list.size()) {
|
||||
index++;
|
||||
sub_index = 0;
|
||||
}
|
||||
|
||||
if (separator_mask != 0) {
|
||||
// Now consume a separator character. These may be defined
|
||||
// implicitly on an integer list.
|
||||
if ((parse_data._parse_flags & separator_mask) == 0) {
|
||||
// The separator we were looking for wasn't what was being
|
||||
// used to delimit the list. As a special exception, if we
|
||||
// just reached the end of the list and the next token is a
|
||||
// standalone separator that matches what we expect, take that
|
||||
// one.
|
||||
if (sub_index == 0 && index < parse_data_list._list.size() &&
|
||||
parse_data_list._list[index]._parse_flags == separator_mask) {
|
||||
// Bingo! This is the special case--we incremented past
|
||||
// the end of the list to a standalone separator.
|
||||
index++;
|
||||
|
||||
} else {
|
||||
// Some other case; the separator character we were
|
||||
// expecting isn't to be found.
|
||||
if ((separator_mask & XFileParseData::PF_semicolon) != 0) {
|
||||
parse_data.yyerror("Semicolon expected.");
|
||||
} else {
|
||||
parse_data.yyerror("Comma expected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
parse_data.yyerror("Expected integer data for " + get_name());
|
||||
}
|
||||
|
||||
return data_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataDef::unpack_double_value
|
||||
// Access: Private
|
||||
// Description: Unpacks and returns the next sequential double value
|
||||
// from the parse_data_list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(XFileDataObject) XFileDataDef::
|
||||
unpack_double_value(const XFileParseDataList &parse_data_list,
|
||||
const XFileDataDef::PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index,
|
||||
int separator_mask) const {
|
||||
const XFileParseData &parse_data = parse_data_list._list[index];
|
||||
|
||||
PT(XFileDataObject) data_value;
|
||||
|
||||
if ((parse_data._parse_flags & XFileParseData::PF_double) != 0) {
|
||||
if (separator_mask != 0 &&
|
||||
(parse_data._parse_flags & separator_mask) == 0) {
|
||||
if ((separator_mask & XFileParseData::PF_semicolon) != 0) {
|
||||
parse_data.yyerror("Semicolon expected.");
|
||||
} else {
|
||||
parse_data.yyerror("Comma expected.");
|
||||
}
|
||||
|
||||
} else {
|
||||
nassertr(sub_index < parse_data._double_list.size(), false);
|
||||
double value = parse_data._double_list[sub_index];
|
||||
data_value = new XFileDataObjectDouble(this, value);
|
||||
|
||||
sub_index++;
|
||||
if (sub_index >= parse_data._double_list.size()) {
|
||||
index++;
|
||||
sub_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((parse_data._parse_flags & XFileParseData::PF_int) != 0) {
|
||||
if (separator_mask != 0 &&
|
||||
(parse_data._parse_flags & separator_mask) == 0) {
|
||||
if ((separator_mask & XFileParseData::PF_semicolon) != 0) {
|
||||
parse_data.yyerror("Semicolon expected.");
|
||||
} else {
|
||||
parse_data.yyerror("Comma expected.");
|
||||
}
|
||||
|
||||
} else {
|
||||
nassertr(sub_index < parse_data._int_list.size(), false);
|
||||
int value = parse_data._int_list[sub_index];
|
||||
data_value = new XFileDataObjectDouble(this, value);
|
||||
|
||||
sub_index++;
|
||||
if (sub_index >= parse_data._int_list.size()) {
|
||||
index++;
|
||||
sub_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
parse_data.yyerror("Expected floating-point data for " + get_name());
|
||||
}
|
||||
|
||||
return data_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataDef::unpack_template_value
|
||||
// Access: Private
|
||||
// Description: Unpacks a nested template object's data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(XFileDataObject) XFileDataDef::
|
||||
unpack_template_value(const XFileParseDataList &parse_data_list,
|
||||
const XFileDataDef::PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index,
|
||||
int separator_mask) const {
|
||||
PT(XFileDataObjectTemplate) data_value =
|
||||
new XFileDataObjectTemplate(get_x_file(), get_name(), _template);
|
||||
|
||||
PrevData nested_prev_data(prev_data);
|
||||
if (!_template->repack_data(data_value, parse_data_list,
|
||||
nested_prev_data, index, sub_index)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (separator_mask != 0) {
|
||||
// Also expect a trailing semicolon or comma.
|
||||
if (index >= parse_data_list._list.size()) {
|
||||
if ((separator_mask & XFileParseData::PF_semicolon) != 0) {
|
||||
xyyerror("Semicolon expected.");
|
||||
} else {
|
||||
xyyerror("Comma expected.");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const XFileParseData &new_parse_data = parse_data_list._list[index];
|
||||
if ((new_parse_data._parse_flags & XFileParseData::PF_any_data) != 0 ||
|
||||
(new_parse_data._parse_flags & separator_mask) == 0) {
|
||||
if ((separator_mask & XFileParseData::PF_semicolon) != 0) {
|
||||
new_parse_data.yyerror("Semicolon expected.");
|
||||
} else {
|
||||
new_parse_data.yyerror("Comma expected.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return data_value.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataDef::unpack_value
|
||||
// Access: Private
|
||||
// Description: Unpacks and returns the next sequential value, of the
|
||||
// type supported by the unpack_method. If the value
|
||||
// is an array type, unpacks all the elements of the
|
||||
// array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(XFileDataObject) XFileDataDef::
|
||||
unpack_value(const XFileParseDataList &parse_data_list, int array_index,
|
||||
const XFileDataDef::PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index, int separator_mask,
|
||||
XFileDataDef::UnpackMethod unpack_method) const {
|
||||
PT(XFileDataObject) data_value;
|
||||
|
||||
if (array_index == (int)_array_def.size()) {
|
||||
data_value = (this->*unpack_method)(parse_data_list, prev_data,
|
||||
index, sub_index, separator_mask);
|
||||
|
||||
} else {
|
||||
data_value = new XFileDataObjectArray(this);
|
||||
int array_size = _array_def[array_index].get_size(prev_data);
|
||||
|
||||
for (int i = 0; i < array_size - 1; i++) {
|
||||
PT(XFileDataObject) array_element =
|
||||
unpack_value(parse_data_list, array_index + 1,
|
||||
prev_data, index, sub_index,
|
||||
XFileParseData::PF_comma, unpack_method);
|
||||
data_value->add_element(array_element);
|
||||
}
|
||||
PT(XFileDataObject) array_element =
|
||||
unpack_value(parse_data_list, array_index + 1,
|
||||
prev_data, index, sub_index,
|
||||
separator_mask, unpack_method);
|
||||
data_value->add_element(array_element);
|
||||
}
|
||||
|
||||
return data_value;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "xFileNode.h"
|
||||
#include "xFileArrayDef.h"
|
||||
#include "xFileTemplate.h"
|
||||
#include "xFileDataObject.h"
|
||||
#include "pvector.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
@ -67,6 +68,40 @@ public:
|
||||
|
||||
virtual void write_text(ostream &out, int indent_level) const;
|
||||
|
||||
virtual bool repack_data(XFileDataObject *object,
|
||||
const XFileParseDataList &parse_data_list,
|
||||
PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index) const;
|
||||
|
||||
private:
|
||||
typedef PT(XFileDataObject)
|
||||
(XFileDataDef::*UnpackMethod)(const XFileParseDataList &parse_data_list,
|
||||
const PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index,
|
||||
int separator_mask) const;
|
||||
|
||||
PT(XFileDataObject)
|
||||
unpack_integer_value(const XFileParseDataList &parse_data_list,
|
||||
const PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index,
|
||||
int separator_mask) const;
|
||||
PT(XFileDataObject)
|
||||
unpack_double_value(const XFileParseDataList &parse_data_list,
|
||||
const PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index,
|
||||
int separator_mask) const;
|
||||
PT(XFileDataObject)
|
||||
unpack_template_value(const XFileParseDataList &parse_data_list,
|
||||
const PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index,
|
||||
int separator_mask) const;
|
||||
|
||||
PT(XFileDataObject)
|
||||
unpack_value(const XFileParseDataList &parse_data_list, int array_index,
|
||||
const PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index, int separator_mask,
|
||||
UnpackMethod unpack_method) const;
|
||||
|
||||
private:
|
||||
Type _type;
|
||||
PT(XFileTemplate) _template;
|
||||
|
@ -23,8 +23,8 @@
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileDataObject::
|
||||
XFileDataObject(XFile *x_file, const string &name) :
|
||||
XFileNode(x_file, name)
|
||||
XFileDataObject(const XFileDataDef *data_def) :
|
||||
_data_def(data_def)
|
||||
{
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ XFileDataObject(XFile *x_file, const string &name) :
|
||||
// Description: Returns the data object that this object is
|
||||
// represented by, if any, or NULL if there is none.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileDataDef *XFileDataObject::
|
||||
INLINE const XFileDataDef *XFileDataObject::
|
||||
get_data_def() const {
|
||||
return _data_def;
|
||||
}
|
||||
@ -115,6 +115,17 @@ operator string () const {
|
||||
return as_string_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::size
|
||||
// Access: Public
|
||||
// Description: Returns the number of nested data objects within this
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int XFileDataObject::
|
||||
size() const {
|
||||
return get_num_elements();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::operator [] (int)
|
||||
// Access: Public
|
||||
@ -124,8 +135,9 @@ operator string () const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const XFileDataObject &XFileDataObject::
|
||||
operator [] (int n) const {
|
||||
nassertr(n >= 0 && n < get_num_children(), *this);
|
||||
return *DCAST(XFileDataObject, get_child(n));
|
||||
const XFileDataObject *element = get_element(n);
|
||||
nassertr(element != (XFileDataObject *)NULL, *this);
|
||||
return *element;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -137,7 +149,13 @@ operator [] (int n) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const XFileDataObject &XFileDataObject::
|
||||
operator [] (const string &name) const {
|
||||
XFileNode *child = find_child(name);
|
||||
nassertr(child != (XFileNode *)NULL, *this);
|
||||
return *DCAST(XFileDataObject, child);
|
||||
const XFileDataObject *element = get_element(name);
|
||||
nassertr(element != (XFileDataObject *)NULL, *this);
|
||||
return *element;
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const XFileDataObject &data_object) {
|
||||
data_object.output_data(out);
|
||||
return out;
|
||||
}
|
||||
|
@ -17,9 +17,55 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "xFileDataObject.h"
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle XFileDataObject::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileDataObject::
|
||||
~XFileDataObject() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::add_element
|
||||
// Access: Public, Virtual
|
||||
// Description: Adds the indicated element as a nested data element,
|
||||
// if this data object type supports it. Returns true
|
||||
// if added successfully, false if the data object type
|
||||
// does not support nested data elements.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileDataObject::
|
||||
add_element(XFileDataObject *element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::output_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes a suitable representation of this node to an
|
||||
// .x file in text mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObject::
|
||||
output_data(ostream &out) const {
|
||||
out << "(" << get_type() << "::output_data() not implemented.)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::write_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes a suitable representation of this node to an
|
||||
// .x file in text mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObject::
|
||||
write_data(ostream &out, int indent_level, const char *) const {
|
||||
indent(out, indent_level)
|
||||
<< "(" << get_type() << "::write_data() not implemented.)\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::as_integer_value
|
||||
// Access: Protected, Virtual
|
||||
@ -52,3 +98,37 @@ string XFileDataObject::
|
||||
as_string_value() const {
|
||||
return string();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::get_num_elements
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the number of nested data elements within the
|
||||
// object. This may be, e.g. the size of the array, if
|
||||
// it is an array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileDataObject::
|
||||
get_num_elements() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::get_element
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the nth nested data element within the
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const XFileDataObject *XFileDataObject::
|
||||
get_element(int n) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::get_element
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the nested data element within the
|
||||
// object that has the indicated name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const XFileDataObject *XFileDataObject::
|
||||
get_element(const string &name) const {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -20,22 +20,24 @@
|
||||
#define XFILEDATAOBJECT_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "xFileNode.h"
|
||||
#include "xFileDataDef.h"
|
||||
#include "referenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "dcast.h"
|
||||
|
||||
class XFileDataDef;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileDataObject
|
||||
// Description : The abstract base class for a number of different
|
||||
// types of data elements that may be stored in the X
|
||||
// file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileDataObject : public XFileNode {
|
||||
class XFileDataObject : virtual public ReferenceCount {
|
||||
public:
|
||||
INLINE XFileDataObject(XFile *x_file, const string &name);
|
||||
INLINE XFileDataObject(const XFileDataDef *data_def = NULL);
|
||||
virtual ~XFileDataObject();
|
||||
|
||||
INLINE XFileDataDef *get_data_def() const;
|
||||
INLINE const XFileDataDef *get_data_def() const;
|
||||
|
||||
INLINE int i() const;
|
||||
INLINE double d() const;
|
||||
@ -44,24 +46,35 @@ public:
|
||||
INLINE operator double () const;
|
||||
INLINE operator string () const;
|
||||
|
||||
INLINE int size() const;
|
||||
INLINE const XFileDataObject &operator [] (int n) const;
|
||||
INLINE const XFileDataObject &operator [] (const string &name) const;
|
||||
|
||||
virtual bool add_element(XFileDataObject *element);
|
||||
|
||||
virtual void output_data(ostream &out) const;
|
||||
virtual void write_data(ostream &out, int indent_level,
|
||||
const char *separator) const;
|
||||
|
||||
protected:
|
||||
virtual int as_integer_value() const;
|
||||
virtual double as_double_value() const;
|
||||
virtual string as_string_value() const;
|
||||
|
||||
PT(XFileDataDef) _data_def;
|
||||
virtual int get_num_elements() const;
|
||||
virtual const XFileDataObject *get_element(int n) const;
|
||||
virtual const XFileDataObject *get_element(const string &name) const;
|
||||
|
||||
const XFileDataDef *_data_def;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
XFileNode::init_type();
|
||||
ReferenceCount::init_type();
|
||||
register_type(_type_handle, "XFileDataObject",
|
||||
XFileNode::get_class_type());
|
||||
ReferenceCount::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
@ -72,6 +85,8 @@ private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const XFileDataObject &data_object);
|
||||
|
||||
#include "xFileDataObject.I"
|
||||
|
||||
#endif
|
||||
|
29
pandatool/src/xfile/xFileDataObjectArray.I
Normal file
29
pandatool/src/xfile/xFileDataObjectArray.I
Normal file
@ -0,0 +1,29 @@
|
||||
// Filename: xFileDataObjectArray.I
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectArray::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileDataObjectArray::
|
||||
XFileDataObjectArray(const XFileDataDef *data_def) :
|
||||
XFileDataObject(data_def)
|
||||
{
|
||||
}
|
88
pandatool/src/xfile/xFileDataObjectArray.cxx
Normal file
88
pandatool/src/xfile/xFileDataObjectArray.cxx
Normal file
@ -0,0 +1,88 @@
|
||||
// Filename: xFileDataObjectArray.cxx
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "xFileDataObjectArray.h"
|
||||
#include "string_utils.h"
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle XFileDataObjectArray::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectArray::write_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes a suitable representation of this node to an
|
||||
// .x file in text mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectArray::
|
||||
write_data(ostream &out, int indent_level, const char *separator) const {
|
||||
if (!_nested_elements.empty()) {
|
||||
if (_nested_elements.front()->size() != 0) {
|
||||
// If we have a complex nested structure, output one per line.
|
||||
for (size_t i = 0; i < _nested_elements.size() - 1; i++) {
|
||||
_nested_elements[i]->write_data(out, indent_level, ",");
|
||||
}
|
||||
_nested_elements.back()->write_data(out, indent_level, separator);
|
||||
|
||||
} else {
|
||||
// Otherwise, output them all on the same line.
|
||||
indent(out, indent_level);
|
||||
for (size_t i = 0; i < _nested_elements.size() - 1; i++) {
|
||||
out << *_nested_elements[i] << ", ";
|
||||
}
|
||||
out << *_nested_elements.back() << separator << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectArray::add_element
|
||||
// Access: Public, Virtual
|
||||
// Description: Adds the indicated element as a nested data element,
|
||||
// if this data object type supports it. Returns true
|
||||
// if added successfully, false if the data object type
|
||||
// does not support nested data elements.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileDataObjectArray::
|
||||
add_element(XFileDataObject *element) {
|
||||
_nested_elements.push_back(element);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectArray::get_num_elements
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the number of nested data elements within the
|
||||
// object. This may be, e.g. the size of the array, if
|
||||
// it is an array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileDataObjectArray::
|
||||
get_num_elements() const {
|
||||
return _nested_elements.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectArray::get_element
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the nth nested data element within the
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const XFileDataObject *XFileDataObjectArray::
|
||||
get_element(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_nested_elements.size(), NULL);
|
||||
return _nested_elements[n];
|
||||
}
|
66
pandatool/src/xfile/xFileDataObjectArray.h
Normal file
66
pandatool/src/xfile/xFileDataObjectArray.h
Normal file
@ -0,0 +1,66 @@
|
||||
// Filename: xFileDataObjectArray.h
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XFILEDATAOBJECTARRAY_H
|
||||
#define XFILEDATAOBJECTARRAY_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "xFileDataObject.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileDataObjectArray
|
||||
// Description : An array of nested data elements.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileDataObjectArray : public XFileDataObject {
|
||||
public:
|
||||
INLINE XFileDataObjectArray(const XFileDataDef *data_def);
|
||||
|
||||
virtual void write_data(ostream &out, int indent_level,
|
||||
const char *separator) const;
|
||||
|
||||
virtual bool add_element(XFileDataObject *element);
|
||||
|
||||
protected:
|
||||
virtual int get_num_elements() const;
|
||||
virtual const XFileDataObject *get_element(int n) const;
|
||||
|
||||
private:
|
||||
typedef pvector< PT(XFileDataObject) > NestedElements;
|
||||
NestedElements _nested_elements;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
XFileDataObject::init_type();
|
||||
register_type(_type_handle, "XFileDataObjectArray",
|
||||
XFileDataObject::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "xFileDataObjectArray.I"
|
||||
|
||||
#endif
|
18
pandatool/src/xfile/xFileDataObjectDouble.I
Normal file
18
pandatool/src/xfile/xFileDataObjectDouble.I
Normal file
@ -0,0 +1,18 @@
|
||||
// Filename: xFileDataObjectDouble.I
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
97
pandatool/src/xfile/xFileDataObjectDouble.cxx
Normal file
97
pandatool/src/xfile/xFileDataObjectDouble.cxx
Normal file
@ -0,0 +1,97 @@
|
||||
// Filename: xFileDataObjectDouble.cxx
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "xFileDataObjectDouble.h"
|
||||
#include "string_utils.h"
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle XFileDataObjectDouble::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectDouble::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileDataObjectDouble::
|
||||
XFileDataObjectDouble(const XFileDataDef *data_def, double value) :
|
||||
XFileDataObject(data_def),
|
||||
_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectDouble::output_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes a suitable representation of this node to an
|
||||
// .x file in text mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectDouble::
|
||||
output_data(ostream &out) const {
|
||||
out << as_string_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectDouble::write_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes a suitable representation of this node to an
|
||||
// .x file in text mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectDouble::
|
||||
write_data(ostream &out, int indent_level, const char *separator) const {
|
||||
indent(out, indent_level)
|
||||
<< as_string_value() << separator << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectDouble::as_integer_value
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the object's representation as an integer, if
|
||||
// it has one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileDataObjectDouble::
|
||||
as_integer_value() const {
|
||||
return (int)_value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectDouble::as_double_value
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the object's representation as a double, if
|
||||
// it has one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double XFileDataObjectDouble::
|
||||
as_double_value() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectDouble::as_string_value
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the object's representation as a string, if
|
||||
// it has one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string XFileDataObjectDouble::
|
||||
as_string_value() const {
|
||||
// It's important to format with a decimal point, even if the value
|
||||
// is integral, since the DirectX .x reader differentiates betweens
|
||||
// doubles and integers on parsing.
|
||||
char buffer[128];
|
||||
sprintf(buffer, "%f", _value);
|
||||
|
||||
return buffer;
|
||||
}
|
67
pandatool/src/xfile/xFileDataObjectDouble.h
Normal file
67
pandatool/src/xfile/xFileDataObjectDouble.h
Normal file
@ -0,0 +1,67 @@
|
||||
// Filename: xFileDataObjectDouble.h
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XFILEDATAOBJECTDOUBLE_H
|
||||
#define XFILEDATAOBJECTDOUBLE_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "xFileDataObject.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileDataObjectDouble
|
||||
// Description : An double-valued data element. This matches one
|
||||
// double data member of a template, or a single
|
||||
// element of an double array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileDataObjectDouble : public XFileDataObject {
|
||||
public:
|
||||
XFileDataObjectDouble(const XFileDataDef *data_def, double value);
|
||||
|
||||
virtual void output_data(ostream &out) const;
|
||||
virtual void write_data(ostream &out, int indent_level,
|
||||
const char *separator) const;
|
||||
|
||||
protected:
|
||||
virtual int as_integer_value() const;
|
||||
virtual double as_double_value() const;
|
||||
virtual string as_string_value() const;
|
||||
|
||||
private:
|
||||
double _value;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
XFileDataObject::init_type();
|
||||
register_type(_type_handle, "XFileDataObjectDouble",
|
||||
XFileDataObject::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "xFileDataObjectDouble.I"
|
||||
|
||||
#endif
|
18
pandatool/src/xfile/xFileDataObjectInteger.I
Normal file
18
pandatool/src/xfile/xFileDataObjectInteger.I
Normal file
@ -0,0 +1,18 @@
|
||||
// Filename: xFileDataObjectInteger.I
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
91
pandatool/src/xfile/xFileDataObjectInteger.cxx
Normal file
91
pandatool/src/xfile/xFileDataObjectInteger.cxx
Normal file
@ -0,0 +1,91 @@
|
||||
// Filename: xFileDataObjectInteger.cxx
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "xFileDataObjectInteger.h"
|
||||
#include "string_utils.h"
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle XFileDataObjectInteger::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectInteger::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileDataObjectInteger::
|
||||
XFileDataObjectInteger(const XFileDataDef *data_def, int value) :
|
||||
XFileDataObject(data_def),
|
||||
_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectInteger::output_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes a suitable representation of this node to an
|
||||
// .x file in text mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectInteger::
|
||||
output_data(ostream &out) const {
|
||||
out << _value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectInteger::write_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes a suitable representation of this node to an
|
||||
// .x file in text mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectInteger::
|
||||
write_data(ostream &out, int indent_level, const char *separator) const {
|
||||
indent(out, indent_level)
|
||||
<< _value << separator << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectInteger::as_integer_value
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the object's representation as an integer, if
|
||||
// it has one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileDataObjectInteger::
|
||||
as_integer_value() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectInteger::as_double_value
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the object's representation as a double, if
|
||||
// it has one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double XFileDataObjectInteger::
|
||||
as_double_value() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectInteger::as_string_value
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the object's representation as a string, if
|
||||
// it has one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string XFileDataObjectInteger::
|
||||
as_string_value() const {
|
||||
return format_string(_value);
|
||||
}
|
67
pandatool/src/xfile/xFileDataObjectInteger.h
Normal file
67
pandatool/src/xfile/xFileDataObjectInteger.h
Normal file
@ -0,0 +1,67 @@
|
||||
// Filename: xFileDataObjectInteger.h
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XFILEDATAOBJECTINTEGER_H
|
||||
#define XFILEDATAOBJECTINTEGER_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "xFileDataObject.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileDataObjectInteger
|
||||
// Description : An integer-valued data element. This matches one
|
||||
// integer data member of a template, or a single
|
||||
// element of an integer array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileDataObjectInteger : public XFileDataObject {
|
||||
public:
|
||||
XFileDataObjectInteger(const XFileDataDef *data_def, int value);
|
||||
|
||||
virtual void output_data(ostream &out) const;
|
||||
virtual void write_data(ostream &out, int indent_level,
|
||||
const char *separator) const;
|
||||
|
||||
protected:
|
||||
virtual int as_integer_value() const;
|
||||
virtual double as_double_value() const;
|
||||
virtual string as_string_value() const;
|
||||
|
||||
private:
|
||||
int _value;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
XFileDataObject::init_type();
|
||||
register_type(_type_handle, "XFileDataObjectInteger",
|
||||
XFileDataObject::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "xFileDataObjectInteger.I"
|
||||
|
||||
#endif
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include "xFileDataObjectTemplate.h"
|
||||
#include "indent.h"
|
||||
#include "xFileParseData.h"
|
||||
#include "xLexerDefs.h"
|
||||
|
||||
TypeHandle XFileDataObjectTemplate::_type_handle;
|
||||
|
||||
@ -29,7 +31,7 @@ TypeHandle XFileDataObjectTemplate::_type_handle;
|
||||
XFileDataObjectTemplate::
|
||||
XFileDataObjectTemplate(XFile *x_file, const string &name,
|
||||
XFileTemplate *xtemplate) :
|
||||
XFileDataObject(x_file, name),
|
||||
XFileNode(x_file, name),
|
||||
_template(xtemplate)
|
||||
{
|
||||
}
|
||||
@ -48,11 +50,46 @@ write_text(ostream &out, int indent_level) const {
|
||||
out << " " << get_name();
|
||||
}
|
||||
out << " {\n";
|
||||
XFileDataObject::write_text(out, indent_level + 2);
|
||||
|
||||
int num_elements = get_num_elements();
|
||||
for (int i = 0; i < num_elements; i++) {
|
||||
get_element(i)->write_data(out, indent_level + 2, ";");
|
||||
}
|
||||
|
||||
XFileNode::write_text(out, indent_level + 2);
|
||||
indent(out, indent_level)
|
||||
<< "}\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::write_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes a suitable representation of this node to an
|
||||
// .x file in text mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
write_data(ostream &out, int indent_level, const char *separator) const {
|
||||
if (!_nested_elements.empty()) {
|
||||
if (_nested_elements.front()->size() != 0) {
|
||||
// If we have a complex nested structure, output one per line.
|
||||
for (size_t i = 0; i < _nested_elements.size() - 1; i++) {
|
||||
_nested_elements[i]->write_data(out, indent_level, ";");
|
||||
}
|
||||
string combined_separator = string(";") + string(separator);
|
||||
_nested_elements.back()->write_data(out, indent_level,
|
||||
combined_separator.c_str());
|
||||
|
||||
} else {
|
||||
// Otherwise, output them all on the same line.
|
||||
indent(out, indent_level);
|
||||
for (size_t i = 0; i < _nested_elements.size() - 1; i++) {
|
||||
out << *_nested_elements[i] << "; ";
|
||||
}
|
||||
out << *_nested_elements.back() << ";" << separator << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::add_parse_object
|
||||
// Access: Public
|
||||
@ -62,6 +99,14 @@ write_text(ostream &out, int indent_level) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
add_parse_object(XFileDataObjectTemplate *object, bool reference) {
|
||||
XFileParseData pdata;
|
||||
pdata._object = object;
|
||||
pdata._parse_flags = XFileParseData::PF_object;
|
||||
if (reference) {
|
||||
pdata._parse_flags |= XFileParseData::PF_reference;
|
||||
}
|
||||
|
||||
_parse_data_list._list.push_back(pdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -73,6 +118,20 @@ add_parse_object(XFileDataObjectTemplate *object, bool reference) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
add_parse_double(PTA_double double_list, char separator) {
|
||||
XFileParseData pdata;
|
||||
pdata._double_list = double_list;
|
||||
pdata._parse_flags = XFileParseData::PF_double;
|
||||
switch (separator) {
|
||||
case ',':
|
||||
pdata._parse_flags |= XFileParseData::PF_comma;
|
||||
break;
|
||||
|
||||
case ';':
|
||||
pdata._parse_flags |= XFileParseData::PF_semicolon;
|
||||
break;
|
||||
}
|
||||
|
||||
_parse_data_list._list.push_back(pdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -84,6 +143,20 @@ add_parse_double(PTA_double double_list, char separator) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
add_parse_int(PTA_int int_list, char separator) {
|
||||
XFileParseData pdata;
|
||||
pdata._int_list = int_list;
|
||||
pdata._parse_flags = XFileParseData::PF_int;
|
||||
switch (separator) {
|
||||
case ',':
|
||||
pdata._parse_flags |= XFileParseData::PF_comma;
|
||||
break;
|
||||
|
||||
case ';':
|
||||
pdata._parse_flags |= XFileParseData::PF_semicolon;
|
||||
break;
|
||||
}
|
||||
|
||||
_parse_data_list._list.push_back(pdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -95,6 +168,20 @@ add_parse_int(PTA_int int_list, char separator) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
add_parse_string(const string &str, char separator) {
|
||||
XFileParseData pdata;
|
||||
pdata._string = str;
|
||||
pdata._parse_flags = XFileParseData::PF_string;
|
||||
switch (separator) {
|
||||
case ',':
|
||||
pdata._parse_flags |= XFileParseData::PF_comma;
|
||||
break;
|
||||
|
||||
case ';':
|
||||
pdata._parse_flags |= XFileParseData::PF_semicolon;
|
||||
break;
|
||||
}
|
||||
|
||||
_parse_data_list._list.push_back(pdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -106,6 +193,19 @@ add_parse_string(const string &str, char separator) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
add_parse_separator(char separator) {
|
||||
XFileParseData pdata;
|
||||
pdata._parse_flags = 0;
|
||||
switch (separator) {
|
||||
case ',':
|
||||
pdata._parse_flags |= XFileParseData::PF_comma;
|
||||
break;
|
||||
|
||||
case ';':
|
||||
pdata._parse_flags |= XFileParseData::PF_semicolon;
|
||||
break;
|
||||
}
|
||||
|
||||
_parse_data_list._list.push_back(pdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -119,5 +219,79 @@ add_parse_separator(char separator) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileDataObjectTemplate::
|
||||
finalize_parse_data() {
|
||||
// Recursively walk through our template definition, while
|
||||
// simultaneously walking through the list of parse data elements we
|
||||
// encountered, and re-pack them as actual nested elements.
|
||||
PrevData prev_data;
|
||||
size_t index = 0;
|
||||
size_t sub_index = 0;
|
||||
|
||||
if (!_template->repack_data(this, _parse_data_list,
|
||||
prev_data, index, sub_index)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Quietly allow an extra semicolon at the end of the structure.
|
||||
// (Why is this sometimes here?)
|
||||
if (index < _parse_data_list._list.size() &&
|
||||
_parse_data_list._list[index]._parse_flags == XFileParseData::PF_semicolon) {
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index != _parse_data_list._list.size()) {
|
||||
cerr << "flags = " << hex << _parse_data_list._list[index]._parse_flags << dec << "\n";
|
||||
xyyerror("Too many data elements in structure.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::add_element
|
||||
// Access: Public, Virtual
|
||||
// Description: Adds the indicated element as a nested data element,
|
||||
// if this data object type supports it. Returns true
|
||||
// if added successfully, false if the data object type
|
||||
// does not support nested data elements.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileDataObjectTemplate::
|
||||
add_element(XFileDataObject *element) {
|
||||
_nested_elements.push_back(element);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::get_num_elements
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the number of nested data elements within the
|
||||
// object. This may be, e.g. the size of the array, if
|
||||
// it is an array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileDataObjectTemplate::
|
||||
get_num_elements() const {
|
||||
return _nested_elements.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::get_element
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the nth nested data element within the
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const XFileDataObject *XFileDataObjectTemplate::
|
||||
get_element(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_nested_elements.size(), NULL);
|
||||
return _nested_elements[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::get_element
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the nested data element within the
|
||||
// object that has the indicated name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const XFileDataObject *XFileDataObjectTemplate::
|
||||
get_element(const string &name) const {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -20,8 +20,10 @@
|
||||
#define XFILEDATAOBJECTTEMPLATE_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "xFileNode.h"
|
||||
#include "xFileDataObject.h"
|
||||
#include "xFileTemplate.h"
|
||||
#include "xFileParseData.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pta_int.h"
|
||||
#include "pta_double.h"
|
||||
@ -34,7 +36,7 @@
|
||||
// obtained by walking through the children of this
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileDataObjectTemplate : public XFileDataObject {
|
||||
class XFileDataObjectTemplate : public XFileNode, public XFileDataObject {
|
||||
public:
|
||||
XFileDataObjectTemplate(XFile *x_file, const string &name,
|
||||
XFileTemplate *xtemplate);
|
||||
@ -42,6 +44,8 @@ public:
|
||||
INLINE XFileTemplate *get_template() const;
|
||||
|
||||
virtual void write_text(ostream &out, int indent_level) const;
|
||||
virtual void write_data(ostream &out, int indent_level,
|
||||
const char *separator) const;
|
||||
|
||||
public:
|
||||
void add_parse_object(XFileDataObjectTemplate *object, bool reference);
|
||||
@ -51,41 +55,30 @@ public:
|
||||
void add_parse_separator(char separator);
|
||||
bool finalize_parse_data();
|
||||
|
||||
virtual bool add_element(XFileDataObject *element);
|
||||
|
||||
protected:
|
||||
virtual int get_num_elements() const;
|
||||
virtual const XFileDataObject *get_element(int n) const;
|
||||
virtual const XFileDataObject *get_element(const string &name) const;
|
||||
|
||||
private:
|
||||
PT(XFileTemplate) _template;
|
||||
|
||||
// This class is used to fill up the data as the values are parsed.
|
||||
// It only has a temporary lifespan; it will be converted into
|
||||
// actual data by finalize_parse_data().
|
||||
enum ParseFlags {
|
||||
PF_object = 0x001,
|
||||
PF_reference = 0x002,
|
||||
PF_double = 0x004,
|
||||
PF_int = 0x008,
|
||||
PF_string = 0x010,
|
||||
PF_comma = 0x020,
|
||||
PF_semicolon = 0x040,
|
||||
};
|
||||
XFileParseDataList _parse_data_list;
|
||||
|
||||
class ParseData {
|
||||
public:
|
||||
PT(XFileDataObjectTemplate) _object;
|
||||
PTA_double _double_list;
|
||||
PTA_int _int_list;
|
||||
string _string;
|
||||
int _parse_flags;
|
||||
};
|
||||
|
||||
typedef pvector<ParseData> ParseDataList;
|
||||
ParseDataList _parse_data_list;
|
||||
typedef pvector< PT(XFileDataObject) > NestedElements;
|
||||
NestedElements _nested_elements;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
XFileNode::init_type();
|
||||
XFileDataObject::init_type();
|
||||
register_type(_type_handle, "XFileDataObjectTemplate",
|
||||
XFileNode::get_class_type(),
|
||||
XFileDataObject::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
|
@ -17,6 +17,16 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileNode::get_num_children
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFile *XFileNode::
|
||||
get_x_file() const {
|
||||
return _x_file;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileNode::get_num_children
|
||||
// Access: Public
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "xFileNode.h"
|
||||
#include "windowsGuid.h"
|
||||
#include "xFile.h"
|
||||
#include "xLexerDefs.h"
|
||||
#include "xFileParseData.h"
|
||||
|
||||
TypeHandle XFileNode::_type_handle;
|
||||
|
||||
@ -149,3 +151,37 @@ write_text(ostream &out, int indent_level) const {
|
||||
(*ci)->write_text(out, indent_level);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileNode::repack_data
|
||||
// Access: Public, Virtual
|
||||
// Description: This is called on the template that defines an
|
||||
// object, once the data for the object has been parsed.
|
||||
// It is responsible for identifying which component of
|
||||
// the template owns each data element, and packing the
|
||||
// data elements appropriately back into the object.
|
||||
//
|
||||
// It returns true on success, or false on an error
|
||||
// (e.g. too many semicolons, not enough data elements,
|
||||
// mismatched data type).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileNode::
|
||||
repack_data(XFileDataObject *object,
|
||||
const XFileParseDataList &parse_data_list,
|
||||
XFileNode::PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index) const {
|
||||
// This method should be specialized for data types that actually
|
||||
// consume a data element. Here in the base class, it just walks
|
||||
// through its children, asking each one to pull off the appropriate
|
||||
// number of data elements.
|
||||
|
||||
Children::const_iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
if (!(*ci)->repack_data(object, parse_data_list,
|
||||
prev_data, index, sub_index)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -20,7 +20,8 @@
|
||||
#define XFILENODE_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "typedReferenceCount.h"
|
||||
#include "typedObject.h"
|
||||
#include "referenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "namable.h"
|
||||
#include "notify.h"
|
||||
@ -29,17 +30,23 @@
|
||||
|
||||
class XFile;
|
||||
class WindowsGuid;
|
||||
class XFileParseDataList;
|
||||
class XFileDataDef;
|
||||
class XFileDataObject;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileNode
|
||||
// Description : A single node of an X file. This may be either a
|
||||
// template or a data node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileNode : public TypedReferenceCount, public Namable {
|
||||
class XFileNode : public TypedObject, public Namable,
|
||||
virtual public ReferenceCount {
|
||||
public:
|
||||
XFileNode(XFile *x_file, const string &name);
|
||||
virtual ~XFileNode();
|
||||
|
||||
INLINE XFile *get_x_file() const;
|
||||
|
||||
INLINE int get_num_children() const;
|
||||
INLINE XFileNode *get_child(int n) const;
|
||||
XFileNode *find_child(const string &name) const;
|
||||
@ -53,6 +60,13 @@ public:
|
||||
|
||||
virtual void write_text(ostream &out, int indent_level) const;
|
||||
|
||||
typedef pmap<const XFileDataDef *, XFileDataObject *> PrevData;
|
||||
|
||||
virtual bool repack_data(XFileDataObject *object,
|
||||
const XFileParseDataList &parse_data_list,
|
||||
PrevData &prev_data,
|
||||
size_t &index, size_t &sub_index) const;
|
||||
|
||||
protected:
|
||||
XFile *_x_file;
|
||||
|
||||
@ -67,9 +81,11 @@ public:
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedReferenceCount::init_type();
|
||||
TypedObject::init_type();
|
||||
ReferenceCount::init_type();
|
||||
register_type(_type_handle, "XFileNode",
|
||||
TypedReferenceCount::get_class_type());
|
||||
TypedObject::get_class_type(),
|
||||
ReferenceCount::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
18
pandatool/src/xfile/xFileParseData.I
Normal file
18
pandatool/src/xfile/xFileParseData.I
Normal file
@ -0,0 +1,18 @@
|
||||
// Filename: xFileParseData.I
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
50
pandatool/src/xfile/xFileParseData.cxx
Normal file
50
pandatool/src/xfile/xFileParseData.cxx
Normal file
@ -0,0 +1,50 @@
|
||||
// Filename: xFileParseData.cxx
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "xFileParseData.h"
|
||||
#include "xLexerDefs.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileParseData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileParseData::
|
||||
XFileParseData() :
|
||||
_parse_flags(0)
|
||||
{
|
||||
// Save the line number, column number, and line text in case we
|
||||
// detect an error later and want to report a meaningful message to
|
||||
// the user.
|
||||
_line_number = x_line_number;
|
||||
_col_number = x_col_number;
|
||||
_current_line = x_current_line;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileParseData::yyerror
|
||||
// Access: Public
|
||||
// Description: Reports a parsing error message to the user, showing
|
||||
// the line and column from which this object was
|
||||
// originally parsed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileParseData::
|
||||
yyerror(const string &message) const {
|
||||
xyyerror(message, _line_number, _col_number, _current_line);
|
||||
}
|
82
pandatool/src/xfile/xFileParseData.h
Normal file
82
pandatool/src/xfile/xFileParseData.h
Normal file
@ -0,0 +1,82 @@
|
||||
// Filename: xFileParseData.h
|
||||
// Created by: drose (07Oct04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XFILEPARSEDATA_H
|
||||
#define XFILEPARSEDATA_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "xFileDataObject.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pta_int.h"
|
||||
#include "pta_double.h"
|
||||
#include "pvector.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileParseData
|
||||
// Description : This class is used to fill up the data into an
|
||||
// XFileDataObjectTemplate object as the data values are
|
||||
// parsed out of the X file. It only has a temporary
|
||||
// lifespan; it will be converted into actual data by
|
||||
// XFileDataObjectTemplate::finalize_parse_data().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileParseData {
|
||||
public:
|
||||
XFileParseData();
|
||||
|
||||
void yyerror(const string &message) const;
|
||||
|
||||
enum ParseFlags {
|
||||
PF_object = 0x001,
|
||||
PF_reference = 0x002,
|
||||
PF_double = 0x004,
|
||||
PF_int = 0x008,
|
||||
PF_string = 0x010,
|
||||
PF_any_data = 0x01f,
|
||||
PF_comma = 0x020,
|
||||
PF_semicolon = 0x040,
|
||||
};
|
||||
|
||||
PT(XFileDataObject) _object;
|
||||
PTA_double _double_list;
|
||||
PTA_int _int_list;
|
||||
string _string;
|
||||
int _parse_flags;
|
||||
|
||||
int _line_number;
|
||||
int _col_number;
|
||||
string _current_line;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileParseDataList
|
||||
// Description : A container for a pvector of the above objects. We
|
||||
// need this wrapper class to avoid circular #includes;
|
||||
// this allows XFileNode to define a forward reference
|
||||
// to this class (without having to include this file or
|
||||
// know that it contains a template class).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileParseDataList {
|
||||
public:
|
||||
typedef pvector<XFileParseData> List;
|
||||
List _list;
|
||||
};
|
||||
|
||||
#include "xFileParseData.I"
|
||||
|
||||
#endif
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "xParser.h"
|
||||
#include "indent.h"
|
||||
#include "string_utils.h"
|
||||
#include "notify.h"
|
||||
#include "config_xfile.h"
|
||||
|
||||
static int yyinput(void); // declared by flex.
|
||||
extern "C" int xyywrap();
|
||||
@ -22,13 +22,13 @@ extern "C" int xyywrap();
|
||||
|
||||
// We'll increment line_number and col_number as we parse the file, so
|
||||
// that we can report the position of an error.
|
||||
static int line_number = 0;
|
||||
static int col_number = 0;
|
||||
int x_line_number = 0;
|
||||
int x_col_number = 0;
|
||||
|
||||
// current_line holds as much of the current line as will fit. Its
|
||||
// only purpose is for printing it out to report an error to the user.
|
||||
static const int max_error_width = 1024;
|
||||
static char current_line[max_error_width + 1];
|
||||
char x_current_line[max_error_width + 1];
|
||||
|
||||
static int error_count = 0;
|
||||
static int warning_count = 0;
|
||||
@ -49,8 +49,8 @@ void
|
||||
x_init_lexer(istream &in, const string &filename) {
|
||||
inp = ∈
|
||||
x_filename = filename;
|
||||
line_number = 0;
|
||||
col_number = 0;
|
||||
x_line_number = 0;
|
||||
x_col_number = 0;
|
||||
error_count = 0;
|
||||
warning_count = 0;
|
||||
}
|
||||
@ -77,14 +77,20 @@ xyywrap(void) {
|
||||
|
||||
void
|
||||
xyyerror(const string &msg) {
|
||||
cerr << "\nError";
|
||||
xyyerror(msg, x_line_number, x_col_number, x_current_line);
|
||||
}
|
||||
|
||||
void
|
||||
xyyerror(const string &msg, int line_number, int col_number,
|
||||
const string ¤t_line) {
|
||||
xfile_cat.error(false) << "\nError";
|
||||
if (!x_filename.empty()) {
|
||||
cerr << " in " << x_filename;
|
||||
xfile_cat.error(false) << " in " << x_filename;
|
||||
}
|
||||
cerr
|
||||
xfile_cat.error(false)
|
||||
<< " at line " << line_number << ", column " << col_number << ":\n"
|
||||
<< current_line << "\n";
|
||||
indent(cerr, col_number-1)
|
||||
indent(xfile_cat.error(false), col_number-1)
|
||||
<< "^\n" << msg << "\n\n";
|
||||
|
||||
error_count++;
|
||||
@ -92,14 +98,14 @@ xyyerror(const string &msg) {
|
||||
|
||||
void
|
||||
xyywarning(const string &msg) {
|
||||
cerr << "\nWarning";
|
||||
xfile_cat.warning(false) << "\nWarning";
|
||||
if (!x_filename.empty()) {
|
||||
cerr << " in " << x_filename;
|
||||
xfile_cat.warning(false) << " in " << x_filename;
|
||||
}
|
||||
cerr
|
||||
<< " at line " << line_number << ", column " << col_number << ":\n"
|
||||
<< current_line << "\n";
|
||||
indent(cerr, col_number-1)
|
||||
xfile_cat.warning(false)
|
||||
<< " at line " << x_line_number << ", column " << x_col_number << ":\n"
|
||||
<< x_current_line << "\n";
|
||||
indent(xfile_cat.warning(false), x_col_number-1)
|
||||
<< "^\n" << msg << "\n\n";
|
||||
|
||||
warning_count++;
|
||||
@ -118,18 +124,18 @@ input_chars(char *buffer, int &result, int max_size) {
|
||||
buffer[result] = '\0';
|
||||
}
|
||||
|
||||
if (line_number == 0) {
|
||||
if (x_line_number == 0) {
|
||||
// This is a special case. If we are reading the very first bit
|
||||
// from the stream, copy it into the current_line array. This
|
||||
// is because the \n.* rule below, which fills current_line
|
||||
// from the stream, copy it into the x_current_line array. This
|
||||
// is because the \n.* rule below, which fills x_current_line
|
||||
// normally, doesn't catch the first line.
|
||||
strncpy(current_line, xyytext, max_error_width);
|
||||
current_line[max_error_width] = '\0';
|
||||
line_number++;
|
||||
col_number = 0;
|
||||
strncpy(x_current_line, xyytext, max_error_width);
|
||||
x_current_line[max_error_width] = '\0';
|
||||
x_line_number++;
|
||||
x_col_number = 0;
|
||||
|
||||
// Truncate it at the newline.
|
||||
char *end = strchr(current_line, '\n');
|
||||
char *end = strchr(x_current_line, '\n');
|
||||
if (end != NULL) {
|
||||
*end = '\0';
|
||||
}
|
||||
@ -170,11 +176,11 @@ scan_quoted_string(char quote_mark) {
|
||||
// occurring at the start of the string, not at the end--somewhat
|
||||
// more convenient for the user.
|
||||
|
||||
// Instead of adjusting the global line_number and col_number
|
||||
// Instead of adjusting the global x_line_number and x_col_number
|
||||
// variables, we'll operate on our own local variables for the
|
||||
// interim.
|
||||
int line = line_number;
|
||||
int col = col_number;
|
||||
int line = x_line_number;
|
||||
int col = x_col_number;
|
||||
|
||||
int c;
|
||||
c = read_char(line, col);
|
||||
@ -274,8 +280,8 @@ scan_quoted_string(char quote_mark) {
|
||||
xyyerror("This quotation mark is unterminated.");
|
||||
}
|
||||
|
||||
line_number = line;
|
||||
col_number = col;
|
||||
x_line_number = line;
|
||||
x_col_number = col;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -290,11 +296,11 @@ scan_guid_string() {
|
||||
// occurring at the start of the string, not at the end--somewhat
|
||||
// more convenient for the user.
|
||||
|
||||
// Instead of adjusting the global line_number and col_number
|
||||
// Instead of adjusting the global x_line_number and x_col_number
|
||||
// variables, we'll operate on our own local variables for the
|
||||
// interim.
|
||||
int line = line_number;
|
||||
int col = col_number;
|
||||
int line = x_line_number;
|
||||
int col = x_col_number;
|
||||
|
||||
int num_digits = 0;
|
||||
int num_hyphens = 0;
|
||||
@ -311,8 +317,8 @@ scan_guid_string() {
|
||||
num_hyphens++;
|
||||
|
||||
} else {
|
||||
line_number = line;
|
||||
col_number = col;
|
||||
x_line_number = line;
|
||||
x_col_number = col;
|
||||
xyyerror("Invalid character in GUID.");
|
||||
return string();
|
||||
}
|
||||
@ -335,19 +341,25 @@ scan_guid_string() {
|
||||
return string();
|
||||
}
|
||||
|
||||
line_number = line;
|
||||
col_number = col;
|
||||
x_line_number = line;
|
||||
x_col_number = col;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parses the text into a list of integers and returns them.
|
||||
static PTA_int
|
||||
parse_int_list(const string &text, const string &delimiter) {
|
||||
parse_int_list(const string &text, char delimiter) {
|
||||
PTA_int result;
|
||||
|
||||
vector_string words;
|
||||
tokenize(text, words, delimiter);
|
||||
|
||||
// The last character of text might be the delimiter.
|
||||
if (!text.empty() && text[text.size() - 1] == delimiter) {
|
||||
tokenize(text.substr(0, text.size() - 1), words, string(1, delimiter));
|
||||
} else {
|
||||
tokenize(text, words, string(1, delimiter));
|
||||
}
|
||||
|
||||
vector_string::const_iterator wi;
|
||||
for (wi = words.begin(); wi != words.end(); ++wi) {
|
||||
@ -361,11 +373,17 @@ parse_int_list(const string &text, const string &delimiter) {
|
||||
|
||||
// Parses the text into a list of doubles and returns them.
|
||||
static PTA_double
|
||||
parse_double_list(const string &text, const string &delimiter) {
|
||||
parse_double_list(const string &text, char delimiter) {
|
||||
PTA_double result;
|
||||
|
||||
vector_string words;
|
||||
tokenize(text, words, delimiter);
|
||||
|
||||
// The last character of text might be the delimiter.
|
||||
if (!text.empty() && text[text.size() - 1] == delimiter) {
|
||||
tokenize(text.substr(0, text.size() - 1), words, string(1, delimiter));
|
||||
} else {
|
||||
tokenize(text, words, string(1, delimiter));
|
||||
}
|
||||
|
||||
vector_string::const_iterator wi;
|
||||
for (wi = words.begin(); wi != words.end(); ++wi) {
|
||||
@ -382,7 +400,7 @@ parse_double_list(const string &text, const string &delimiter) {
|
||||
// accept() is called below as each piece is pulled off and
|
||||
// accepted by the lexer; it increments the current column number.
|
||||
inline void accept() {
|
||||
col_number += yyleng;
|
||||
x_col_number += yyleng;
|
||||
}
|
||||
|
||||
%}
|
||||
@ -399,10 +417,10 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
// New line. Save a copy of the line so we can print it out for the
|
||||
// benefit of the user in case we get an error.
|
||||
|
||||
strncpy(current_line, xyytext+1, max_error_width);
|
||||
current_line[max_error_width] = '\0';
|
||||
line_number++;
|
||||
col_number=0;
|
||||
strncpy(x_current_line, xyytext+1, max_error_width);
|
||||
x_current_line[max_error_width] = '\0';
|
||||
x_line_number++;
|
||||
x_col_number=0;
|
||||
|
||||
// Return the whole line to the lexer, except the newline character,
|
||||
// which we eat.
|
||||
@ -541,7 +559,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
({INTEGERNUM};)+ {
|
||||
// An integer as part of a semicolon-delimited list.
|
||||
accept();
|
||||
xyylval.int_list = parse_int_list(xyytext, ";");
|
||||
xyylval.int_list = parse_int_list(xyytext, ';');
|
||||
xyylval.u.separator = ';';
|
||||
|
||||
return TOKEN_INTEGER_LIST;
|
||||
@ -550,25 +568,43 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
({REALNUM};)+ {
|
||||
// A floating-point number as part of a semicolon-delimited list.
|
||||
accept();
|
||||
xyylval.double_list = parse_double_list(xyytext, ";");
|
||||
xyylval.double_list = parse_double_list(xyytext, ';');
|
||||
xyylval.u.separator = ';';
|
||||
|
||||
return TOKEN_REALNUM_LIST;
|
||||
}
|
||||
|
||||
({INTEGERNUM},)+ {
|
||||
// An integer as part of a semicolon-delimited list.
|
||||
// An integer as part of a comma-delimited list.
|
||||
accept();
|
||||
xyylval.int_list = parse_int_list(xyytext, ",");
|
||||
xyylval.int_list = parse_int_list(xyytext, ',');
|
||||
xyylval.u.separator = ',';
|
||||
|
||||
return TOKEN_INTEGER_LIST;
|
||||
}
|
||||
|
||||
({REALNUM},)+ {
|
||||
// A floating-point number as part of a semicolon-delimited list.
|
||||
// A floating-point number as part of a comma-delimited list.
|
||||
accept();
|
||||
xyylval.double_list = parse_double_list(xyytext, ",");
|
||||
xyylval.double_list = parse_double_list(xyytext, ',');
|
||||
xyylval.u.separator = ',';
|
||||
|
||||
return TOKEN_REALNUM_LIST;
|
||||
}
|
||||
|
||||
({INTEGERNUM},)+{INTEGERNUM} {
|
||||
// An integer as part of a comma-delimited list.
|
||||
accept();
|
||||
xyylval.int_list = parse_int_list(xyytext, ',');
|
||||
xyylval.u.separator = ',';
|
||||
|
||||
return TOKEN_INTEGER_LIST;
|
||||
}
|
||||
|
||||
({REALNUM},)+{REALNUM} {
|
||||
// A floating-point number as part of a comma-delimited list.
|
||||
accept();
|
||||
xyylval.double_list = parse_double_list(xyytext, ',');
|
||||
xyylval.u.separator = ',';
|
||||
|
||||
return TOKEN_REALNUM_LIST;
|
||||
|
@ -26,8 +26,14 @@ int x_error_count();
|
||||
int x_warning_count();
|
||||
|
||||
void xyyerror(const string &msg);
|
||||
void xyyerror(const string &msg, int line_number, int col_number,
|
||||
const string ¤t_line);
|
||||
void xyywarning(const string &msg);
|
||||
|
||||
int xyylex();
|
||||
|
||||
extern int x_line_number;
|
||||
extern int x_col_number;
|
||||
extern char x_current_line[];
|
||||
|
||||
#endif
|
||||
|
@ -349,9 +349,7 @@ object:
|
||||
{
|
||||
XFileDataObjectTemplate *current_template =
|
||||
DCAST(XFileDataObjectTemplate, current_node);
|
||||
if (!current_template->finalize_parse_data()) {
|
||||
yyerror("Invalid data for object.");
|
||||
}
|
||||
current_template->finalize_parse_data();
|
||||
|
||||
$$ = current_node;
|
||||
current_node = $<u.node>4;
|
||||
@ -366,27 +364,11 @@ data_parts_list:
|
||||
data_part:
|
||||
TOKEN_OBRACE data_reference TOKEN_CBRACE
|
||||
{
|
||||
if ($2 != (XFileNode *)NULL) {
|
||||
if (!$2->is_of_type(XFileDataObjectTemplate::get_class_type())) {
|
||||
// Actually, maybe you can--the docs aren't clear about this.
|
||||
// But I don't think there's any real reason to.
|
||||
yyerror("Can't reference primitive data type.");
|
||||
} else {
|
||||
XFileDataObjectTemplate *object =
|
||||
DCAST(XFileDataObjectTemplate, $2);
|
||||
XFileDataObjectTemplate *current_template =
|
||||
DCAST(XFileDataObjectTemplate, current_node);
|
||||
current_template->add_parse_object(object, true);
|
||||
}
|
||||
}
|
||||
// nested references should be added as children too.
|
||||
}
|
||||
| object
|
||||
{
|
||||
XFileDataObjectTemplate *object =
|
||||
DCAST(XFileDataObjectTemplate, $1);
|
||||
XFileDataObjectTemplate *current_template =
|
||||
DCAST(XFileDataObjectTemplate, current_node);
|
||||
current_template->add_parse_object(object, false);
|
||||
// nested objects are just quietly added as children.
|
||||
}
|
||||
| integer_list
|
||||
{
|
||||
@ -440,7 +422,7 @@ list_separator:
|
||||
data_reference:
|
||||
name
|
||||
{
|
||||
XFileDataObject *data_object = x_file->find_data_object($1);
|
||||
XFileDataObjectTemplate *data_object = x_file->find_data_object($1);
|
||||
if (data_object == (XFileDataObject *)NULL) {
|
||||
yyerror("Unknown data_object: " + $1);
|
||||
}
|
||||
@ -449,7 +431,7 @@ data_reference:
|
||||
}
|
||||
| name class_id
|
||||
{
|
||||
XFileDataObject *data_object = x_file->find_data_object($2);
|
||||
XFileDataObjectTemplate *data_object = x_file->find_data_object($2);
|
||||
if (data_object == (XFileDataObject *)NULL) {
|
||||
yyerror("Unknown data_object: " + $1);
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user