mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
more parsing games
This commit is contained in:
parent
e397109f73
commit
b020b2047a
@ -20,6 +20,7 @@
|
||||
#include "xParserDefs.h"
|
||||
#include "xLexerDefs.h"
|
||||
#include "xFileTemplate.h"
|
||||
#include "xFileDataObject.h"
|
||||
#include "config_xfile.h"
|
||||
#include "standard_templates.h"
|
||||
#include "zStream.h"
|
||||
@ -36,7 +37,7 @@ PT(XFile) XFile::_standard_templates;
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFile::
|
||||
XFile() : XFileNode("") {
|
||||
XFile() : XFileNode(this, "") {
|
||||
_major_version = 3;
|
||||
_minor_version = 2;
|
||||
_format_type = FT_text;
|
||||
@ -53,21 +54,6 @@ XFile::
|
||||
clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFile::add_child
|
||||
// Access: Public, Virtual
|
||||
// Description: Adds the indicated node as a child of this node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFile::
|
||||
add_child(XFileNode *node) {
|
||||
XFileNode::add_child(node);
|
||||
|
||||
if (node->is_of_type(XFileTemplate::get_class_type())) {
|
||||
XFileTemplate *xtemplate = DCAST(XFileTemplate, node);
|
||||
_templates_by_guid[xtemplate->get_guid()] = xtemplate;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFile::clear
|
||||
// Access: Public, Virtual
|
||||
@ -77,6 +63,8 @@ add_child(XFileNode *node) {
|
||||
void XFile::
|
||||
clear() {
|
||||
XFileNode::clear();
|
||||
|
||||
_nodes_by_guid.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -192,7 +180,7 @@ write(Filename filename) const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// function: XFile::write
|
||||
// Function: XFile::write
|
||||
// Access: Public
|
||||
// Description: Writes a parseable description of all the known
|
||||
// nodes and templates to the stream.
|
||||
@ -241,10 +229,11 @@ find_template(const string &name) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileTemplate *XFile::
|
||||
find_template(const WindowsGuid &guid) const {
|
||||
TemplatesByGuid::const_iterator gi;
|
||||
gi = _templates_by_guid.find(guid);
|
||||
if (gi != _templates_by_guid.end()) {
|
||||
return (*gi).second;
|
||||
NodesByGuid::const_iterator gi;
|
||||
gi = _nodes_by_guid.find(guid);
|
||||
if (gi != _nodes_by_guid.end() &&
|
||||
(*gi).second->is_of_type(XFileTemplate::get_class_type())) {
|
||||
return DCAST(XFileTemplate, (*gi).second);
|
||||
}
|
||||
|
||||
const XFile *standard_templates = get_standard_templates();
|
||||
@ -255,6 +244,41 @@ find_template(const WindowsGuid &guid) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFile::find_data_object
|
||||
// Access: Public
|
||||
// Description: Returns the data object associated with the indicated
|
||||
// name, if any, or NULL if none.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileDataObject *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);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFile::find_data_object
|
||||
// Access: Public
|
||||
// Description: Returns the data object associated with the indicated
|
||||
// GUID, if any, or NULL if none.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileDataObject *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);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFile::write_text
|
||||
// Access: Public, Virtual
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "pointerTo.h"
|
||||
|
||||
class XFileTemplate;
|
||||
class XFileDataObject;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFile
|
||||
@ -39,7 +40,6 @@ public:
|
||||
XFile();
|
||||
~XFile();
|
||||
|
||||
virtual void add_child(XFileNode *node);
|
||||
virtual void clear();
|
||||
|
||||
bool read(Filename filename);
|
||||
@ -51,6 +51,9 @@ 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;
|
||||
|
||||
virtual void write_text(ostream &out, int indent_level) const;
|
||||
|
||||
enum FormatType {
|
||||
@ -73,8 +76,8 @@ private:
|
||||
FormatType _format_type;
|
||||
FloatSize _float_size;
|
||||
|
||||
typedef pmap<WindowsGuid, XFileTemplate *> TemplatesByGuid;
|
||||
TemplatesByGuid _templates_by_guid;
|
||||
typedef pmap<WindowsGuid, XFileNode *> NodesByGuid;
|
||||
NodesByGuid _nodes_by_guid;
|
||||
|
||||
static PT(XFile) _standard_templates;
|
||||
|
||||
@ -94,6 +97,8 @@ public:
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class XFileNode;
|
||||
};
|
||||
|
||||
#include "xFile.I"
|
||||
|
@ -23,10 +23,58 @@
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileDataDef::
|
||||
XFileDataDef(XFileDataDef::Type type, const string &name,
|
||||
XFileTemplate *xtemplate) :
|
||||
XFileNode(name),
|
||||
XFileDataDef(XFile *x_file, const string &name,
|
||||
XFileDataDef::Type type, XFileTemplate *xtemplate) :
|
||||
XFileNode(x_file, name),
|
||||
_type(type),
|
||||
_template(xtemplate)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataDef::get_data_type
|
||||
// Access: Public
|
||||
// Description: Returns the primitive type of this element, or
|
||||
// T_template if this represents a nested template
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileDataDef::Type XFileDataDef::
|
||||
get_data_type() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataDef::get_template
|
||||
// Access: Public
|
||||
// Description: If get_data_type() returned T_template, this returns
|
||||
// the particular template pointer that this object
|
||||
// represents.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileTemplate *XFileDataDef::
|
||||
get_template() const {
|
||||
return _template;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataDef::get_num_array_defs
|
||||
// Access: Public
|
||||
// Description: Returns the number of dimensions of array elements on
|
||||
// this data object, or 0 if the data object is not an
|
||||
// array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int XFileDataDef::
|
||||
get_num_array_defs() const {
|
||||
return _array_def.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataDef::get_array_def
|
||||
// Access: Public
|
||||
// Description: Returns the description of the nth dimension of array
|
||||
// elements on this data object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const XFileArrayDef &XFileDataDef::
|
||||
get_array_def(int i) const {
|
||||
nassertr(i >= 0 && i < (int)_array_def.size(), _array_def[0]);
|
||||
return _array_def[i];
|
||||
}
|
||||
|
@ -30,7 +30,10 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileDataDef
|
||||
// Description : A definition of a single data element appearing
|
||||
// within a template record.
|
||||
// within a template record. This class represents the
|
||||
// *definition* of the data element (e.g. DWORD
|
||||
// nVertices); see XFileDataObject for its *value*
|
||||
// (e.g. 12).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileDataDef : public XFileNode {
|
||||
public:
|
||||
@ -49,13 +52,19 @@ public:
|
||||
T_template,
|
||||
};
|
||||
|
||||
INLINE XFileDataDef(Type type, const string &name,
|
||||
XFileTemplate *xtemplate = NULL);
|
||||
INLINE XFileDataDef(XFile *x_file, const string &name,
|
||||
Type type, XFileTemplate *xtemplate = NULL);
|
||||
virtual ~XFileDataDef();
|
||||
|
||||
virtual void clear();
|
||||
void add_array_def(const XFileArrayDef &array_def);
|
||||
|
||||
INLINE Type get_data_type() const;
|
||||
INLINE XFileTemplate *get_template() const;
|
||||
|
||||
INLINE int get_num_array_defs() const;
|
||||
INLINE const XFileArrayDef &get_array_def(int i) const;
|
||||
|
||||
virtual void write_text(ostream &out, int indent_level) const;
|
||||
|
||||
private:
|
||||
|
@ -23,6 +23,121 @@
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileDataObject::
|
||||
XFileDataObject(const string &name) : XFileNode(name)
|
||||
XFileDataObject(XFile *x_file, const string &name) :
|
||||
XFileNode(x_file, name)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::get_data_def
|
||||
// Access: Public
|
||||
// Description: Returns the data object that this object is
|
||||
// represented by, if any, or NULL if there is none.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileDataDef *XFileDataObject::
|
||||
get_data_def() const {
|
||||
return _data_def;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::i
|
||||
// Access: Public
|
||||
// Description: Unambiguously returns the object's representation as
|
||||
// an integer, or 0 if the object has no integer
|
||||
// representation. See also the typecast operators, and
|
||||
// get_data_def() to determine what kind of
|
||||
// representation this object has.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int XFileDataObject::
|
||||
i() const {
|
||||
return as_integer_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::d
|
||||
// Access: Public
|
||||
// Description: Unambiguously returns the object's representation as
|
||||
// a double, or 0.0 if the object has no double
|
||||
// representation. See also the typecast operators, and
|
||||
// get_data_def() to determine what kind of
|
||||
// representation this object has.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double XFileDataObject::
|
||||
d() const {
|
||||
return as_double_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::s
|
||||
// Access: Public
|
||||
// Description: Unambiguously returns the object's representation as
|
||||
// a string, or empty string if the object has no string
|
||||
// representation. See also the typecast operators, and
|
||||
// get_data_def() to determine what kind of
|
||||
// representation this object has.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string XFileDataObject::
|
||||
s() const {
|
||||
return as_string_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::int typecast operator
|
||||
// Access: Public
|
||||
// Description: Returns the object's representation as an integer, or
|
||||
// 0 if the object has no integer representation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileDataObject::
|
||||
operator int () const {
|
||||
return as_integer_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::double typecast operator
|
||||
// Access: Public
|
||||
// Description: Returns the object's representation as a double, or
|
||||
// 0.0 if the object has no integer representation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileDataObject::
|
||||
operator double () const {
|
||||
return as_double_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::string typecast operator
|
||||
// Access: Public
|
||||
// Description: Returns the object's representation as a string, or
|
||||
// empty string if the object has no string
|
||||
// representation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileDataObject::
|
||||
operator string () const {
|
||||
return as_string_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::operator [] (int)
|
||||
// Access: Public
|
||||
// Description: Returns the nth nested object within this object.
|
||||
// Call get_num_children() to determine the number of
|
||||
// nested objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const XFileDataObject &XFileDataObject::
|
||||
operator [] (int n) const {
|
||||
nassertr(n >= 0 && n < get_num_children(), *this);
|
||||
return *DCAST(XFileDataObject, get_child(n));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::operator [] (string)
|
||||
// Access: Public
|
||||
// Description: Returns the named nested object within this object.
|
||||
// It is an error if the named object does not exist.
|
||||
// Call find_child() instead if there is any doubt.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const XFileDataObject &XFileDataObject::
|
||||
operator [] (const string &name) const {
|
||||
XFileNode *child = find_child(name);
|
||||
nassertr(child != (XFileNode *)NULL, *this);
|
||||
return *DCAST(XFileDataObject, child);
|
||||
}
|
||||
|
@ -19,3 +19,36 @@
|
||||
#include "xFileDataObject.h"
|
||||
|
||||
TypeHandle XFileDataObject::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::as_integer_value
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the object's representation as an integer, if
|
||||
// it has one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int XFileDataObject::
|
||||
as_integer_value() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::as_double_value
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the object's representation as a double, if
|
||||
// it has one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double XFileDataObject::
|
||||
as_double_value() const {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObject::as_string_value
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the object's representation as a string, if
|
||||
// it has one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string XFileDataObject::
|
||||
as_string_value() const {
|
||||
return string();
|
||||
}
|
||||
|
@ -21,6 +21,9 @@
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "xFileNode.h"
|
||||
#include "xFileDataDef.h"
|
||||
#include "pointerTo.h"
|
||||
#include "dcast.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileDataObject
|
||||
@ -30,8 +33,27 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileDataObject : public XFileNode {
|
||||
public:
|
||||
INLINE XFileDataObject(const string &name);
|
||||
|
||||
INLINE XFileDataObject(XFile *x_file, const string &name);
|
||||
|
||||
INLINE XFileDataDef *get_data_def() const;
|
||||
|
||||
INLINE int i() const;
|
||||
INLINE double d() const;
|
||||
INLINE string s() const;
|
||||
INLINE operator int () const;
|
||||
INLINE operator double () const;
|
||||
INLINE operator string () const;
|
||||
|
||||
INLINE const XFileDataObject &operator [] (int n) const;
|
||||
INLINE const XFileDataObject &operator [] (const string &name) const;
|
||||
|
||||
protected:
|
||||
virtual int as_integer_value() const;
|
||||
virtual double as_double_value() const;
|
||||
virtual string as_string_value() const;
|
||||
|
||||
PT(XFileDataDef) _data_def;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -27,8 +27,9 @@ TypeHandle XFileDataObjectTemplate::_type_handle;
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileDataObjectTemplate::
|
||||
XFileDataObjectTemplate(XFileTemplate *xtemplate, const string &name) :
|
||||
XFileDataObject(name),
|
||||
XFileDataObjectTemplate(XFile *x_file, const string &name,
|
||||
XFileTemplate *xtemplate) :
|
||||
XFileDataObject(x_file, name),
|
||||
_template(xtemplate)
|
||||
{
|
||||
}
|
||||
@ -51,3 +52,72 @@ write_text(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level)
|
||||
<< "}\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::add_parse_object
|
||||
// Access: Public
|
||||
// Description: Adds the indicated object as a nested object
|
||||
// encountered in the parser. It will later be
|
||||
// processed by finalize_parse_data().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
add_parse_object(XFileDataObjectTemplate *object, bool reference) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::add_parse_double
|
||||
// Access: Public
|
||||
// Description: Adds the indicated list of doubles as a data element
|
||||
// encountered in the parser. It will later be
|
||||
// processed by finalize_parse_data().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
add_parse_double(PTA_double double_list, char separator) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::add_parse_int
|
||||
// Access: Public
|
||||
// Description: Adds the indicated list of ints as a data element
|
||||
// encountered in the parser. It will later be
|
||||
// processed by finalize_parse_data().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
add_parse_int(PTA_int int_list, char separator) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::add_parse_string
|
||||
// Access: Public
|
||||
// Description: Adds the indicated string as a data element
|
||||
// encountered in the parser. It will later be
|
||||
// processed by finalize_parse_data().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
add_parse_string(const string &str, char separator) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::add_parse_separator
|
||||
// Access: Public
|
||||
// Description: Adds the indicated separator character as an isolated
|
||||
// separator encountered in the parser. It will later
|
||||
// be processed by finalize_parse_data().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileDataObjectTemplate::
|
||||
add_parse_separator(char separator) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileDataObjectTemplate::finalize_parse_data
|
||||
// Access: Public
|
||||
// Description: Processes all of the data elements added by
|
||||
// add_parse_*(), checks them for syntactic and semantic
|
||||
// correctness against the Template definition, and
|
||||
// stores the appropriate child data elements. Returns
|
||||
// true on success, false if there is a mismatch.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileDataObjectTemplate::
|
||||
finalize_parse_data() {
|
||||
return true;
|
||||
}
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "xFileDataObject.h"
|
||||
#include "xFileTemplate.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pta_int.h"
|
||||
#include "pta_double.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileDataObjectTemplate
|
||||
@ -34,14 +36,48 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileDataObjectTemplate : public XFileDataObject {
|
||||
public:
|
||||
XFileDataObjectTemplate(XFileTemplate *xtemplate, const string &name);
|
||||
XFileDataObjectTemplate(XFile *x_file, const string &name,
|
||||
XFileTemplate *xtemplate);
|
||||
|
||||
INLINE XFileTemplate *get_template() const;
|
||||
|
||||
virtual void write_text(ostream &out, int indent_level) const;
|
||||
|
||||
public:
|
||||
void add_parse_object(XFileDataObjectTemplate *object, bool reference);
|
||||
void add_parse_double(PTA_double double_list, char separator);
|
||||
void add_parse_int(PTA_int int_list, char separator);
|
||||
void add_parse_string(const string &str, char separator);
|
||||
void add_parse_separator(char separator);
|
||||
bool finalize_parse_data();
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -17,6 +17,8 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "xFileNode.h"
|
||||
#include "windowsGuid.h"
|
||||
#include "xFile.h"
|
||||
|
||||
TypeHandle XFileNode::_type_handle;
|
||||
|
||||
@ -26,7 +28,9 @@ TypeHandle XFileNode::_type_handle;
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileNode::
|
||||
XFileNode(const string &name) : Namable(name)
|
||||
XFileNode(XFile *x_file, const string &name) :
|
||||
Namable(name),
|
||||
_x_file(x_file)
|
||||
{
|
||||
}
|
||||
|
||||
@ -57,6 +61,53 @@ find_child(const string &name) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileNode::find_descendent
|
||||
// Access: Public
|
||||
// Description: Returns the first child or descendent found with the
|
||||
// indicated name after a depth-first search, if any, or
|
||||
// NULL if none.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileNode *XFileNode::
|
||||
find_descendent(const string &name) const {
|
||||
XFileNode *child = find_child(name);
|
||||
if (child != (XFileNode *)NULL) {
|
||||
return child;
|
||||
}
|
||||
|
||||
Children::const_iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
XFileNode *child = (*ci)->find_descendent(name);
|
||||
if (child != (XFileNode *)NULL){
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileNode::has_guid
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this node has a GUID associated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileNode::
|
||||
has_guid() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileNode::get_guid
|
||||
// Access: Public, Virtual
|
||||
// Description: If has_guid() returned true, returns the particular
|
||||
// GUID associated with this node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const WindowsGuid &XFileNode::
|
||||
get_guid() const {
|
||||
static WindowsGuid empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileNode::add_child
|
||||
// Access: Public, Virtual
|
||||
@ -68,6 +119,9 @@ add_child(XFileNode *node) {
|
||||
if (node->has_name()) {
|
||||
_children_by_name[node->get_name()] = node;
|
||||
}
|
||||
if (node->has_guid()) {
|
||||
_x_file->_nodes_by_guid[node->get_guid()] = node;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -27,6 +27,9 @@
|
||||
#include "pvector.h"
|
||||
#include "pmap.h"
|
||||
|
||||
class XFile;
|
||||
class WindowsGuid;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : XFileNode
|
||||
// Description : A single node of an X file. This may be either a
|
||||
@ -34,12 +37,16 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileNode : public TypedReferenceCount, public Namable {
|
||||
public:
|
||||
XFileNode(const string &name);
|
||||
XFileNode(XFile *x_file, const string &name);
|
||||
virtual ~XFileNode();
|
||||
|
||||
INLINE int get_num_children() const;
|
||||
INLINE XFileNode *get_child(int n) const;
|
||||
XFileNode *find_child(const string &name) const;
|
||||
XFileNode *find_descendent(const string &name) const;
|
||||
|
||||
virtual bool has_guid() const;
|
||||
virtual const WindowsGuid &get_guid() const;
|
||||
|
||||
virtual void add_child(XFileNode *node);
|
||||
virtual void clear();
|
||||
@ -47,12 +54,14 @@ public:
|
||||
virtual void write_text(ostream &out, int indent_level) const;
|
||||
|
||||
protected:
|
||||
XFile *_x_file;
|
||||
|
||||
typedef pvector< PT(XFileNode) > Children;
|
||||
Children _children;
|
||||
|
||||
typedef pmap<string, XFileNode *> ChildrenByName;
|
||||
ChildrenByName _children_by_name;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -17,16 +17,6 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileTemplate::get_guid
|
||||
// Access: Public
|
||||
// Description: Returns the GUID associated with this template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const WindowsGuid &XFileTemplate::
|
||||
get_guid() const {
|
||||
return _guid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileTemplate::set_open
|
||||
// Access: Public
|
||||
|
@ -27,8 +27,8 @@ TypeHandle XFileTemplate::_type_handle;
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileTemplate::
|
||||
XFileTemplate(const string &name, const WindowsGuid &guid) :
|
||||
XFileNode(name),
|
||||
XFileTemplate(XFile *x_file, const string &name, const WindowsGuid &guid) :
|
||||
XFileNode(x_file, name),
|
||||
_guid(guid),
|
||||
_open(false)
|
||||
{
|
||||
@ -44,6 +44,26 @@ XFileTemplate::
|
||||
clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileTemplate::has_guid
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this node has a GUID associated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFileTemplate::
|
||||
has_guid() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileTemplate::get_guid
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the GUID associated with this template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const WindowsGuid &XFileTemplate::
|
||||
get_guid() const {
|
||||
return _guid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileTemplate::clear
|
||||
// Access: Public, Virtual
|
||||
|
@ -32,10 +32,11 @@ class XFileDataDef;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class XFileTemplate : public XFileNode {
|
||||
public:
|
||||
XFileTemplate(const string &name, const WindowsGuid &guid);
|
||||
XFileTemplate(XFile *x_file, const string &name, const WindowsGuid &guid);
|
||||
virtual ~XFileTemplate();
|
||||
|
||||
INLINE const WindowsGuid &get_guid() const;
|
||||
virtual bool has_guid() const;
|
||||
virtual const WindowsGuid &get_guid() const;
|
||||
|
||||
virtual void clear();
|
||||
virtual void write_text(ostream &out, int indent_level) const;
|
||||
|
@ -542,7 +542,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
// An integer as part of a semicolon-delimited list.
|
||||
accept();
|
||||
xyylval.int_list = parse_int_list(xyytext, ";");
|
||||
xyylval.u.separator_token = TOKEN_SEMICOLON;
|
||||
xyylval.u.separator = ';';
|
||||
|
||||
return TOKEN_INTEGER_LIST;
|
||||
}
|
||||
@ -551,7 +551,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
// A floating-point number as part of a semicolon-delimited list.
|
||||
accept();
|
||||
xyylval.double_list = parse_double_list(xyytext, ";");
|
||||
xyylval.u.separator_token = TOKEN_SEMICOLON;
|
||||
xyylval.u.separator = ';';
|
||||
|
||||
return TOKEN_REALNUM_LIST;
|
||||
}
|
||||
@ -560,7 +560,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
// An integer as part of a semicolon-delimited list.
|
||||
accept();
|
||||
xyylval.int_list = parse_int_list(xyytext, ",");
|
||||
xyylval.u.separator_token = TOKEN_COMMA;
|
||||
xyylval.u.separator = ',';
|
||||
|
||||
return TOKEN_INTEGER_LIST;
|
||||
}
|
||||
@ -569,7 +569,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
// A floating-point number as part of a semicolon-delimited list.
|
||||
accept();
|
||||
xyylval.double_list = parse_double_list(xyytext, ",");
|
||||
xyylval.u.separator_token = TOKEN_COMMA;
|
||||
xyylval.u.separator = ',';
|
||||
|
||||
return TOKEN_REALNUM_LIST;
|
||||
}
|
||||
|
@ -98,6 +98,8 @@ x_cleanup_parser() {
|
||||
%type <str> string
|
||||
%type <guid> class_id
|
||||
%type <guid> optional_class_id
|
||||
%type <u.separator> list_separator
|
||||
%type <u.node> data_reference
|
||||
|
||||
%%
|
||||
|
||||
@ -111,7 +113,7 @@ template:
|
||||
TOKEN_TEMPLATE name TOKEN_OBRACE class_id
|
||||
{
|
||||
$$ = current_node;
|
||||
XFileTemplate *templ = new XFileTemplate($2, $4);
|
||||
XFileTemplate *templ = new XFileTemplate(x_file, $2, $4);
|
||||
current_node->add_child(templ);
|
||||
current_node = templ;
|
||||
}
|
||||
@ -154,7 +156,7 @@ template_members:
|
||||
primitive:
|
||||
primitive_type optional_name TOKEN_SEMICOLON
|
||||
{
|
||||
current_data_def = new XFileDataDef($1, $2);
|
||||
current_data_def = new XFileDataDef(x_file, $2, $1);
|
||||
current_node->add_child(current_data_def);
|
||||
}
|
||||
;
|
||||
@ -170,7 +172,7 @@ template_reference:
|
||||
if (xtemplate == (XFileTemplate *)NULL) {
|
||||
yyerror("Unknown template: " + $1);
|
||||
} else {
|
||||
current_data_def = new XFileDataDef(XFileDataDef::T_template, $2, xtemplate);
|
||||
current_data_def = new XFileDataDef(x_file, $2, XFileDataDef::T_template, xtemplate);
|
||||
current_node->add_child(current_data_def);
|
||||
}
|
||||
}
|
||||
@ -226,7 +228,7 @@ primitive_type:
|
||||
array_data_type:
|
||||
primitive_type name
|
||||
{
|
||||
current_data_def = new XFileDataDef($1, $2);
|
||||
current_data_def = new XFileDataDef(x_file, $2, $1);
|
||||
current_node->add_child(current_data_def);
|
||||
}
|
||||
| name name
|
||||
@ -235,7 +237,7 @@ array_data_type:
|
||||
if (xtemplate == (XFileTemplate *)NULL) {
|
||||
yyerror("Unknown template: " + $1);
|
||||
} else {
|
||||
current_data_def = new XFileDataDef(XFileDataDef::T_template, $2, xtemplate);
|
||||
current_data_def = new XFileDataDef(x_file, $2, XFileDataDef::T_template, xtemplate);
|
||||
current_node->add_child(current_data_def);
|
||||
}
|
||||
}
|
||||
@ -285,7 +287,7 @@ template_option_part:
|
||||
DCAST(XFileTemplate, current_node)->add_option(xtemplate);
|
||||
}
|
||||
}
|
||||
| name TOKEN_GUID
|
||||
| name class_id
|
||||
{
|
||||
XFileTemplate *xtemplate = x_file->find_template($2);
|
||||
if (xtemplate == (XFileTemplate *)NULL) {
|
||||
@ -338,13 +340,19 @@ object:
|
||||
yyerror("Unknown template: " + $1);
|
||||
} else {
|
||||
XFileDataObjectTemplate *templ =
|
||||
new XFileDataObjectTemplate(xtemplate, $2);
|
||||
new XFileDataObjectTemplate(x_file, $2, xtemplate);
|
||||
current_node->add_child(templ);
|
||||
current_node = templ;
|
||||
}
|
||||
}
|
||||
optional_class_id data_parts_list TOKEN_CBRACE
|
||||
{
|
||||
XFileDataObjectTemplate *current_template =
|
||||
DCAST(XFileDataObjectTemplate, current_node);
|
||||
if (!current_template->finalize_parse_data()) {
|
||||
yyerror("Invalid data for object.");
|
||||
}
|
||||
|
||||
$$ = current_node;
|
||||
current_node = $<u.node>4;
|
||||
}
|
||||
@ -356,23 +364,53 @@ data_parts_list:
|
||||
;
|
||||
|
||||
data_part:
|
||||
data_reference
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
| object
|
||||
{
|
||||
XFileDataObjectTemplate *object =
|
||||
DCAST(XFileDataObjectTemplate, $1);
|
||||
XFileDataObjectTemplate *current_template =
|
||||
DCAST(XFileDataObjectTemplate, current_node);
|
||||
current_template->add_parse_object(object, false);
|
||||
}
|
||||
| integer_list
|
||||
{
|
||||
XFileDataObjectTemplate *current_template =
|
||||
DCAST(XFileDataObjectTemplate, current_node);
|
||||
current_template->add_parse_int($1, $<u.separator>1);
|
||||
}
|
||||
| realnum_list
|
||||
{
|
||||
XFileDataObjectTemplate *current_template =
|
||||
DCAST(XFileDataObjectTemplate, current_node);
|
||||
current_template->add_parse_double($1, $<u.separator>1);
|
||||
}
|
||||
| string list_separator
|
||||
{
|
||||
XFileDataObjectTemplate *current_template =
|
||||
DCAST(XFileDataObjectTemplate, current_node);
|
||||
current_template->add_parse_string($1, $2);
|
||||
}
|
||||
| list_separator
|
||||
{
|
||||
XFileDataObjectTemplate *current_template =
|
||||
DCAST(XFileDataObjectTemplate, current_node);
|
||||
current_template->add_parse_separator($1);
|
||||
}
|
||||
;
|
||||
|
||||
@ -390,11 +428,39 @@ string:
|
||||
|
||||
list_separator:
|
||||
TOKEN_SEMICOLON
|
||||
{
|
||||
$$ = ';';
|
||||
}
|
||||
| TOKEN_COMMA
|
||||
{
|
||||
$$ = ',';
|
||||
}
|
||||
;
|
||||
|
||||
data_reference:
|
||||
TOKEN_OBRACE name optional_class_id TOKEN_CBRACE
|
||||
name
|
||||
{
|
||||
XFileDataObject *data_object = x_file->find_data_object($1);
|
||||
if (data_object == (XFileDataObject *)NULL) {
|
||||
yyerror("Unknown data_object: " + $1);
|
||||
}
|
||||
|
||||
$$ = data_object;
|
||||
}
|
||||
| name class_id
|
||||
{
|
||||
XFileDataObject *data_object = x_file->find_data_object($2);
|
||||
if (data_object == (XFileDataObject *)NULL) {
|
||||
yyerror("Unknown data_object: " + $1);
|
||||
} else {
|
||||
if (data_object->get_name() != $1) {
|
||||
xyywarning("GUID identifies data_object " + data_object->get_name() +
|
||||
", not " + $1);
|
||||
}
|
||||
}
|
||||
|
||||
$$ = data_object;
|
||||
}
|
||||
;
|
||||
|
||||
empty:
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
int number;
|
||||
XFileNode *node;
|
||||
XFileDataDef::Type primitive_type;
|
||||
int separator_token; // This is filled in for double_list and int_list.
|
||||
char separator; // This is filled in for double_list and int_list.
|
||||
} u;
|
||||
string str;
|
||||
WindowsGuid guid;
|
||||
|
Loading…
x
Reference in New Issue
Block a user