mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
add XFileNode::is_standard_object()
This commit is contained in:
parent
81aa4087ee
commit
209c02fc6e
@ -207,18 +207,27 @@ write(ostream &out) const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
XFileTemplate *XFile::
|
XFileTemplate *XFile::
|
||||||
find_template(const string &name) const {
|
find_template(const string &name) const {
|
||||||
|
XFileTemplate *standard = (XFileTemplate *)NULL;
|
||||||
|
const XFile *standard_templates = get_standard_templates();
|
||||||
|
if (standard_templates != this) {
|
||||||
|
standard = standard_templates->find_template(name);
|
||||||
|
}
|
||||||
|
|
||||||
XFileNode *child = find_child(name);
|
XFileNode *child = find_child(name);
|
||||||
if (child != (XFileNode *)NULL &&
|
if (child != (XFileNode *)NULL &&
|
||||||
child->is_of_type(XFileTemplate::get_class_type())) {
|
child->is_of_type(XFileTemplate::get_class_type())) {
|
||||||
return DCAST(XFileTemplate, child);
|
XFileTemplate *xtemplate = DCAST(XFileTemplate, child);
|
||||||
|
if (standard != (XFileTemplate *)NULL && xtemplate->matches(standard)) {
|
||||||
|
// If the template matches a standard template, return the
|
||||||
|
// standard instead. The assumption is that code may expect a
|
||||||
|
// certain naming scheme for the data elements of the standard
|
||||||
|
// template, so we want to be sure to provide it.
|
||||||
|
return standard;
|
||||||
|
}
|
||||||
|
return xtemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
const XFile *standard_templates = get_standard_templates();
|
return standard;
|
||||||
if (standard_templates != this) {
|
|
||||||
return standard_templates->find_template(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -229,19 +238,28 @@ find_template(const string &name) const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
XFileTemplate *XFile::
|
XFileTemplate *XFile::
|
||||||
find_template(const WindowsGuid &guid) const {
|
find_template(const WindowsGuid &guid) const {
|
||||||
|
XFileTemplate *standard = (XFileTemplate *)NULL;
|
||||||
|
const XFile *standard_templates = get_standard_templates();
|
||||||
|
if (standard_templates != this) {
|
||||||
|
standard = standard_templates->find_template(guid);
|
||||||
|
}
|
||||||
|
|
||||||
NodesByGuid::const_iterator gi;
|
NodesByGuid::const_iterator gi;
|
||||||
gi = _nodes_by_guid.find(guid);
|
gi = _nodes_by_guid.find(guid);
|
||||||
if (gi != _nodes_by_guid.end() &&
|
if (gi != _nodes_by_guid.end() &&
|
||||||
(*gi).second->is_of_type(XFileTemplate::get_class_type())) {
|
(*gi).second->is_of_type(XFileTemplate::get_class_type())) {
|
||||||
return DCAST(XFileTemplate, (*gi).second);
|
XFileTemplate *xtemplate = DCAST(XFileTemplate, (*gi).second);
|
||||||
|
if (standard != (XFileTemplate *)NULL && xtemplate->matches(standard)) {
|
||||||
|
// If the template matches a standard template, return the
|
||||||
|
// standard instead. The assumption is that code may expect a
|
||||||
|
// certain naming scheme for the data elements of the standard
|
||||||
|
// template, so we want to be sure to provide it.
|
||||||
|
return standard;
|
||||||
|
}
|
||||||
|
return xtemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
const XFile *standard_templates = get_standard_templates();
|
return standard;
|
||||||
if (standard_templates != this) {
|
|
||||||
return standard_templates->find_template(guid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -497,6 +515,15 @@ get_standard_templates() {
|
|||||||
xfile_cat.error()
|
xfile_cat.error()
|
||||||
<< "Internal error: Unable to parse built-in standardTemplates.x!\n";
|
<< "Internal error: Unable to parse built-in standardTemplates.x!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now flag all of these templates as "standard".
|
||||||
|
for (int i = 0; i < _standard_templates->get_num_children(); i++) {
|
||||||
|
XFileNode *child = _standard_templates->get_child(i);
|
||||||
|
if (child->is_of_type(XFileTemplate::get_class_type())) {
|
||||||
|
XFileTemplate *xtemplate = DCAST(XFileTemplate, child);
|
||||||
|
xtemplate->_is_standard = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _standard_templates;
|
return _standard_templates;
|
||||||
|
@ -56,3 +56,35 @@ output(ostream &out) const {
|
|||||||
out << "[" << _dynamic_size->get_name() << "]";
|
out << "[" << _dynamic_size->get_name() << "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileArrayDef::matches
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if the node, particularly a template
|
||||||
|
// node, is structurally equivalent to the other node
|
||||||
|
// (which must be of the same type). This checks data
|
||||||
|
// element types, but does not compare data element
|
||||||
|
// names.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileArrayDef::
|
||||||
|
matches(const XFileArrayDef &other, const XFileDataDef *parent,
|
||||||
|
const XFileDataDef *other_parent) const {
|
||||||
|
if (other.is_fixed_size() != is_fixed_size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (is_fixed_size()) {
|
||||||
|
if (other.get_fixed_size() != get_fixed_size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
int child_index = parent->find_child_index(get_dynamic_size());
|
||||||
|
int other_child_index =
|
||||||
|
other_parent->find_child_index(other.get_dynamic_size());
|
||||||
|
if (other_child_index != child_index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -43,6 +43,9 @@ public:
|
|||||||
|
|
||||||
void output(ostream &out) const;
|
void output(ostream &out) const;
|
||||||
|
|
||||||
|
bool matches(const XFileArrayDef &other, const XFileDataDef *parent,
|
||||||
|
const XFileDataDef *other_parent) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _fixed_size;
|
int _fixed_size;
|
||||||
XFileDataDef *_dynamic_size;
|
XFileDataDef *_dynamic_size;
|
||||||
|
@ -253,6 +253,45 @@ fill_zero_data(XFileDataObject *object) const {
|
|||||||
return XFileNode::fill_zero_data(object);
|
return XFileNode::fill_zero_data(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileDataDef::matches
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if the node, particularly a template
|
||||||
|
// node, is structurally equivalent to the other node
|
||||||
|
// (which must be of the same type). This checks data
|
||||||
|
// element types, but does not compare data element
|
||||||
|
// names.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileDataDef::
|
||||||
|
matches(const XFileNode *other) const {
|
||||||
|
if (!XFileNode::matches(other)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const XFileDataDef *data_def = DCAST(XFileDataDef, other);
|
||||||
|
if (data_def->get_data_type() != get_data_type()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_data_type() == T_template &&
|
||||||
|
!get_template()->matches(data_def->get_template())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_def->get_num_array_defs() != get_num_array_defs()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < get_num_array_defs(); i++) {
|
||||||
|
if (!get_array_def(i).matches(data_def->get_array_def(i),
|
||||||
|
this, data_def)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: XFileDataDef::unpack_integer_value
|
// Function: XFileDataDef::unpack_integer_value
|
||||||
|
@ -75,6 +75,8 @@ public:
|
|||||||
|
|
||||||
virtual bool fill_zero_data(XFileDataObject *object) const;
|
virtual bool fill_zero_data(XFileDataObject *object) const;
|
||||||
|
|
||||||
|
virtual bool matches(const XFileNode *other) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef PT(XFileDataObject)
|
typedef PT(XFileDataObject)
|
||||||
(XFileDataDef::*UnpackMethod)(const XFileParseDataList &parse_data_list,
|
(XFileDataDef::*UnpackMethod)(const XFileParseDataList &parse_data_list,
|
||||||
|
@ -36,6 +36,24 @@ XFileDataNodeTemplate(XFile *x_file, const string &name,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileDataNodeTemplate::is_standard_object
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if this node represents an instance of
|
||||||
|
// the standard template with the indicated name, or
|
||||||
|
// false otherwise. If this returns true, the object
|
||||||
|
// must be of type XFileDataNodeTemplate.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileDataNodeTemplate::
|
||||||
|
is_standard_object(const string &template_name) const {
|
||||||
|
if (_template->is_standard() &&
|
||||||
|
_template->get_name() == template_name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: XFileDataNodeTemplate::zero_fill
|
// Function: XFileDataNodeTemplate::zero_fill
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -39,6 +39,9 @@ class XFileDataNodeTemplate : public XFileDataNode {
|
|||||||
public:
|
public:
|
||||||
XFileDataNodeTemplate(XFile *x_file, const string &name,
|
XFileDataNodeTemplate(XFile *x_file, const string &name,
|
||||||
XFileTemplate *xtemplate);
|
XFileTemplate *xtemplate);
|
||||||
|
|
||||||
|
virtual bool is_standard_object(const string &template_name) const;
|
||||||
|
|
||||||
void zero_fill();
|
void zero_fill();
|
||||||
|
|
||||||
virtual bool is_complex_object() const;
|
virtual bool is_complex_object() const;
|
||||||
|
@ -83,6 +83,23 @@ find_child_index(const string &name) const {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileNode::find_child_index
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the index number of the indicated child,
|
||||||
|
// or -1 if none.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int XFileNode::
|
||||||
|
find_child_index(const XFileNode *child) const {
|
||||||
|
for (int i = 0; i < (int)_children.size(); i++) {
|
||||||
|
if (_children[i] == child) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: XFileNode::find_descendent
|
// Function: XFileNode::find_descendent
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -131,8 +148,21 @@ get_guid() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: XFileNode::add_child
|
// Function: XFileNode::is_standard_object
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if this node represents an instance of
|
||||||
|
// the standard template with the indicated name, or
|
||||||
|
// false otherwise. If this returns true, the object
|
||||||
|
// must be of type XFileDataNodeTemplate.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileNode::
|
||||||
|
is_standard_object(const string &template_name) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileNode::add_child
|
||||||
|
// Access: Public
|
||||||
// Description: Adds the indicated node as a child of this node.
|
// Description: Adds the indicated node as a child of this node.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void XFileNode::
|
void XFileNode::
|
||||||
@ -225,6 +255,34 @@ fill_zero_data(XFileDataObject *object) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileNode::matches
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if the node, particularly a template
|
||||||
|
// node, is structurally equivalent to the other node
|
||||||
|
// (which must be of the same type). This checks data
|
||||||
|
// element types, but does not compare data element
|
||||||
|
// names.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileNode::
|
||||||
|
matches(const XFileNode *other) const {
|
||||||
|
if (other->get_type() != get_type()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other->get_num_children() != get_num_children()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < get_num_children(); i++) {
|
||||||
|
if (!get_child(i)->matches(other->get_child(i))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: XFileNode::add_Mesh
|
// Function: XFileNode::add_Mesh
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -54,12 +54,15 @@ public:
|
|||||||
INLINE XFileNode *get_child(int n) const;
|
INLINE XFileNode *get_child(int n) const;
|
||||||
XFileNode *find_child(const string &name) const;
|
XFileNode *find_child(const string &name) const;
|
||||||
int find_child_index(const string &name) const;
|
int find_child_index(const string &name) const;
|
||||||
|
int find_child_index(const XFileNode *child) const;
|
||||||
XFileNode *find_descendent(const string &name) const;
|
XFileNode *find_descendent(const string &name) const;
|
||||||
|
|
||||||
virtual bool has_guid() const;
|
virtual bool has_guid() const;
|
||||||
virtual const WindowsGuid &get_guid() const;
|
virtual const WindowsGuid &get_guid() const;
|
||||||
|
|
||||||
virtual void add_child(XFileNode *node);
|
virtual bool is_standard_object(const string &template_name) const;
|
||||||
|
|
||||||
|
void add_child(XFileNode *node);
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
virtual void write_text(ostream &out, int indent_level) const;
|
virtual void write_text(ostream &out, int indent_level) const;
|
||||||
@ -73,16 +76,12 @@ public:
|
|||||||
|
|
||||||
virtual bool fill_zero_data(XFileDataObject *object) const;
|
virtual bool fill_zero_data(XFileDataObject *object) const;
|
||||||
|
|
||||||
|
virtual bool matches(const XFileNode *other) const;
|
||||||
|
|
||||||
// The following methods can be used to create instances of the
|
// The following methods can be used to create instances of the
|
||||||
// standard template objects. These definitions match those defined
|
// standard template objects. These definitions match those defined
|
||||||
// in standardTemplates.x in this directory (and compiled into the
|
// in standardTemplates.x in this directory (and compiled into the
|
||||||
// executable).
|
// executable).
|
||||||
/*
|
|
||||||
PT(XFileNode) make_Header(int major, int minor, int flags);
|
|
||||||
PT(XFileNode) make_Vector(const LVecBase3d &vector);
|
|
||||||
PT(XFileNode) make_MeshFace(int num_vertex_indices, const int *vertex_indices);
|
|
||||||
*/
|
|
||||||
XFileDataNode *add_Mesh(const string &name);
|
XFileDataNode *add_Mesh(const string &name);
|
||||||
XFileDataNode *add_MeshNormals(const string &name);
|
XFileDataNode *add_MeshNormals(const string &name);
|
||||||
XFileDataNode *add_MeshVertexColors(const string &name);
|
XFileDataNode *add_MeshVertexColors(const string &name);
|
||||||
|
@ -17,6 +17,20 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileTemplate::is_standard
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if this particular template is one of
|
||||||
|
// the "standard" templates defined by
|
||||||
|
// standardTemplates.x in this directory (and compiled
|
||||||
|
// into the binary), or false if it is a user-custom
|
||||||
|
// template.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool XFileTemplate::
|
||||||
|
is_standard() const {
|
||||||
|
return _is_standard;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: XFileTemplate::set_open
|
// Function: XFileTemplate::set_open
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -30,6 +30,7 @@ XFileTemplate::
|
|||||||
XFileTemplate(XFile *x_file, const string &name, const WindowsGuid &guid) :
|
XFileTemplate(XFile *x_file, const string &name, const WindowsGuid &guid) :
|
||||||
XFileNode(x_file, name),
|
XFileNode(x_file, name),
|
||||||
_guid(guid),
|
_guid(guid),
|
||||||
|
_is_standard(false),
|
||||||
_open(false)
|
_open(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -115,3 +116,25 @@ write_text(ostream &out, int indent_level) const {
|
|||||||
indent(out, indent_level)
|
indent(out, indent_level)
|
||||||
<< "}\n";
|
<< "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileTemplate::matches
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if the node, particularly a template
|
||||||
|
// node, is structurally equivalent to the other node
|
||||||
|
// (which must be of the same type). This checks data
|
||||||
|
// element types, but does not compare data element
|
||||||
|
// names.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileTemplate::
|
||||||
|
matches(const XFileNode *other) const {
|
||||||
|
if (!XFileNode::matches(other)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We *could* compare the open/closed/options associated with the
|
||||||
|
// template, but since this is only used for validating the set of
|
||||||
|
// children for the instances of this template (which we don't even
|
||||||
|
// bother to do anyway), it doesn't seem to matter.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -41,15 +41,20 @@ public:
|
|||||||
virtual void clear();
|
virtual void clear();
|
||||||
virtual void write_text(ostream &out, int indent_level) const;
|
virtual void write_text(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
|
INLINE bool is_standard() const;
|
||||||
|
|
||||||
INLINE void set_open(bool open);
|
INLINE void set_open(bool open);
|
||||||
INLINE bool get_open() const;
|
INLINE bool get_open() const;
|
||||||
|
|
||||||
INLINE void add_option(XFileTemplate *option);
|
INLINE void add_option(XFileTemplate *option);
|
||||||
INLINE int get_num_options() const;
|
INLINE int get_num_options() const;
|
||||||
INLINE XFileTemplate *get_option(int n) const;
|
INLINE XFileTemplate *get_option(int n) const;
|
||||||
|
|
||||||
|
virtual bool matches(const XFileNode *other) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WindowsGuid _guid;
|
WindowsGuid _guid;
|
||||||
|
bool _is_standard;
|
||||||
bool _open;
|
bool _open;
|
||||||
|
|
||||||
typedef pvector< PT(XFileTemplate) > Options;
|
typedef pvector< PT(XFileTemplate) > Options;
|
||||||
@ -71,6 +76,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static TypeHandle _type_handle;
|
static TypeHandle _type_handle;
|
||||||
|
|
||||||
|
friend class XFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "xFileTemplate.I"
|
#include "xFileTemplate.I"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user