mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -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::
|
||||
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);
|
||||
if (child != (XFileNode *)NULL &&
|
||||
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();
|
||||
if (standard_templates != this) {
|
||||
return standard_templates->find_template(name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return standard;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -229,19 +238,28 @@ find_template(const string &name) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
XFileTemplate *XFile::
|
||||
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;
|
||||
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);
|
||||
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();
|
||||
if (standard_templates != this) {
|
||||
return standard_templates->find_template(guid);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return standard;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -497,6 +515,15 @@ get_standard_templates() {
|
||||
xfile_cat.error()
|
||||
<< "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;
|
||||
|
@ -56,3 +56,35 @@ output(ostream &out) const {
|
||||
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;
|
||||
|
||||
bool matches(const XFileArrayDef &other, const XFileDataDef *parent,
|
||||
const XFileDataDef *other_parent) const;
|
||||
|
||||
private:
|
||||
int _fixed_size;
|
||||
XFileDataDef *_dynamic_size;
|
||||
|
@ -253,6 +253,45 @@ fill_zero_data(XFileDataObject *object) const {
|
||||
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
|
||||
|
@ -75,6 +75,8 @@ public:
|
||||
|
||||
virtual bool fill_zero_data(XFileDataObject *object) const;
|
||||
|
||||
virtual bool matches(const XFileNode *other) const;
|
||||
|
||||
private:
|
||||
typedef PT(XFileDataObject)
|
||||
(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
|
||||
// Access: Public
|
||||
|
@ -39,6 +39,9 @@ class XFileDataNodeTemplate : public XFileDataNode {
|
||||
public:
|
||||
XFileDataNodeTemplate(XFile *x_file, const string &name,
|
||||
XFileTemplate *xtemplate);
|
||||
|
||||
virtual bool is_standard_object(const string &template_name) const;
|
||||
|
||||
void zero_fill();
|
||||
|
||||
virtual bool is_complex_object() const;
|
||||
|
@ -83,6 +83,23 @@ find_child_index(const string &name) const {
|
||||
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
|
||||
// Access: Public
|
||||
@ -131,8 +148,21 @@ get_guid() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileNode::add_child
|
||||
// Function: XFileNode::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 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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void XFileNode::
|
||||
@ -225,6 +255,34 @@ fill_zero_data(XFileDataObject *object) const {
|
||||
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
|
||||
// Access: Public
|
||||
|
@ -54,12 +54,15 @@ public:
|
||||
INLINE XFileNode *get_child(int n) const;
|
||||
XFileNode *find_child(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;
|
||||
|
||||
virtual bool has_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 write_text(ostream &out, int indent_level) const;
|
||||
@ -73,16 +76,12 @@ public:
|
||||
|
||||
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
|
||||
// standard template objects. These definitions match those defined
|
||||
// in standardTemplates.x in this directory (and compiled into the
|
||||
// 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_MeshNormals(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
|
||||
// Access: Public
|
||||
|
@ -30,6 +30,7 @@ XFileTemplate::
|
||||
XFileTemplate(XFile *x_file, const string &name, const WindowsGuid &guid) :
|
||||
XFileNode(x_file, name),
|
||||
_guid(guid),
|
||||
_is_standard(false),
|
||||
_open(false)
|
||||
{
|
||||
}
|
||||
@ -115,3 +116,25 @@ write_text(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level)
|
||||
<< "}\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 write_text(ostream &out, int indent_level) const;
|
||||
|
||||
INLINE bool is_standard() const;
|
||||
|
||||
INLINE void set_open(bool open);
|
||||
INLINE bool get_open() const;
|
||||
|
||||
INLINE void add_option(XFileTemplate *option);
|
||||
INLINE int get_num_options() const;
|
||||
INLINE XFileTemplate *get_option(int n) const;
|
||||
|
||||
virtual bool matches(const XFileNode *other) const;
|
||||
|
||||
private:
|
||||
WindowsGuid _guid;
|
||||
bool _is_standard;
|
||||
bool _open;
|
||||
|
||||
typedef pvector< PT(XFileTemplate) > Options;
|
||||
@ -71,6 +76,8 @@ public:
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class XFile;
|
||||
};
|
||||
|
||||
#include "xFileTemplate.I"
|
||||
|
Loading…
x
Reference in New Issue
Block a user