552 lines
19 KiB
C++
552 lines
19 KiB
C++
/*
|
|
* Copyright 2006 Sony Computer Entertainment Inc.
|
|
*
|
|
* Licensed under the MIT Open Source License, for details please see license.txt or the website
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
*
|
|
*/
|
|
|
|
#ifndef __DAE_ELEMENT_H__
|
|
#define __DAE_ELEMENT_H__
|
|
#include <string>
|
|
#include <dae/daeTypes.h>
|
|
#include <dae/daeMemorySystem.h>
|
|
#include <wchar.h>
|
|
#include <dae/daeArray.h>
|
|
#include <dae/daeRefCountedObj.h>
|
|
#include <dae/daeSmartRef.h>
|
|
|
|
//#ifndef NO_MALLOC_HEADER
|
|
//#include <malloc.h>
|
|
//#endif
|
|
|
|
namespace COLLADA_TYPE
|
|
{
|
|
typedef int TypeEnum;
|
|
}
|
|
|
|
class DAE;
|
|
class daeMetaElement;
|
|
class daeMetaAttribute;
|
|
class daeDocument;
|
|
class daeURI;
|
|
|
|
/**
|
|
* The @c daeElement class represents an instance of a COLLADA "Element";
|
|
* it is the main base class for the COLLADA Dom.
|
|
* Features of this class include:
|
|
* - Uses factory concepts defined via daeMetaElement
|
|
* - Composed of attributes, content elements and content values
|
|
* - Reference counted via daeSmartRef
|
|
* - Contains information for XML base URI, and XML containing element
|
|
*/
|
|
class DLLSPEC daeElement : public daeRefCountedObj
|
|
{
|
|
public:
|
|
/**
|
|
* Macro that defines new and delete overrides for this class
|
|
*/
|
|
DAE_ALLOC
|
|
protected:
|
|
daeElement* _parent;
|
|
daeDocument* _document;
|
|
daeMetaElement* _meta;
|
|
daeString _elementName;
|
|
daeBoolArray _validAttributeArray; // This is now obsolete and can be removed
|
|
void* _userData;
|
|
|
|
protected:
|
|
daeElement( const daeElement &cpy ) : daeRefCountedObj() { (void)cpy; };
|
|
virtual daeElement &operator=( const daeElement &cpy ) { (void)cpy; return *this; }
|
|
|
|
void init();
|
|
|
|
// These functions are called internally.
|
|
void setDocument( daeDocument* c, bool notifyDocument );
|
|
daeElement* simpleAdd(daeString name, int index = -1);
|
|
|
|
public:
|
|
/**
|
|
* Element Constructor.
|
|
* @note This should not be used externally.
|
|
* Use factories to create elements
|
|
*/
|
|
daeElement();
|
|
/**
|
|
* Element Constructor.
|
|
* @note This should not be used externally.
|
|
* Use factories to create elements
|
|
*/
|
|
daeElement(DAE& dae);
|
|
|
|
/**
|
|
* Element Destructor.
|
|
* @note This should not be used externally,
|
|
* if daeSmartRefs are being used.
|
|
*/
|
|
virtual ~daeElement();
|
|
|
|
/**
|
|
* Sets up a @c daeElement. Called on all @c daeElements as part of their initialization.
|
|
* @param meta Meta element to use to configure this element.
|
|
* @note Should not be called externally.
|
|
*/
|
|
void setup(daeMetaElement* meta);
|
|
|
|
// These functions are for adding child elements. They return null if adding
|
|
// the element failed.
|
|
daeElement* add(daeString name, int index = -1);
|
|
daeElement* add(daeElement* elt, int index = -1);
|
|
daeElement* addBefore(daeElement* elt, daeElement* index);
|
|
daeElement* addAfter(daeElement* elt, daeElement* index);
|
|
|
|
// These functions are deprecated. Use 'add' instead.
|
|
daeElement* createAndPlace(daeString elementName);
|
|
daeElement* createAndPlaceAt(daeInt index, daeString elementName);
|
|
daeBool placeElement(daeElement* element);
|
|
daeBool placeElementAt(daeInt index, daeElement* element);
|
|
daeBool placeElementBefore( daeElement* marker, daeElement *element );
|
|
daeBool placeElementAfter( daeElement* marker, daeElement *element );
|
|
|
|
/**
|
|
* Finds the last index into the array of children of the name specified.
|
|
* @param elementName The name to look for.
|
|
* @return Returns the index into the children array of the last element with name elementName. -1 if
|
|
* there are no children of name elementName.
|
|
*/
|
|
daeInt findLastIndexOf( daeString elementName );
|
|
|
|
/**
|
|
* Removes the specified element from it parent, the @c this element.
|
|
* This function is the opposite of @c placeElement(). It removes the specified
|
|
* element from the <tt><i> _contents </i></tt> array, and from wherever else it appears
|
|
* inside of the @c this element. Use this function instead of @c clear(), @c remove() or @c delete()
|
|
* if you want to keep the <tt><i> _contents </i></tt> field up-to-date.
|
|
*
|
|
* @param element Element to be removed in the @c this container.
|
|
* @return Returns true if the element was successfully removed, false otherwise.
|
|
*/
|
|
daeBool removeChildElement(daeElement* element);
|
|
|
|
/**
|
|
* Removes the specified element from its parent element.
|
|
* This function is the opposite of @c placeElement(). It removes the specified
|
|
* element from both the <tt><i> _contents </i></tt> array and from wherever else it appears
|
|
* inside of its parent. The function itself finds the parent, and is defined as a static method,
|
|
* since removing the element from its parent may result in the deletion of the element.
|
|
* If the element has no parent, nothing is done.
|
|
*
|
|
* Use this function instead of @c clear(), @c remove() or @c delete()
|
|
* if you want to keep <tt><i> _contents </i></tt> up-to-date.
|
|
*
|
|
* @param element Element to remove from its parent container, the function finds the parent element.
|
|
* @return Returns true if the element was successfully removed, false otherwise.
|
|
*/
|
|
static daeBool removeFromParent(daeElement* element)
|
|
{
|
|
if(element != NULL && element->_parent != NULL)
|
|
return(element->_parent->removeChildElement(element));
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Returns the number of attributes in this element.
|
|
* @return The number of attributes this element has.
|
|
*/
|
|
size_t getAttributeCount();
|
|
|
|
/**
|
|
* Returns the daeMetaAttribute object corresponding to the attribute specified.
|
|
* @param name The name of the attribute to find.
|
|
* @return Returns the corresponding daeMetaAttribute object or NULL if this element
|
|
* doesn't have the specified attribute.
|
|
*/
|
|
daeMetaAttribute* getAttributeObject(daeString name);
|
|
|
|
/**
|
|
* Returns the daeMetaAttribute object corresponding to attribute i.
|
|
* @param i The index of the attribute to find.
|
|
* @return Returns the corresponding daeMetaAttribute object
|
|
*/
|
|
daeMetaAttribute* getAttributeObject(size_t i);
|
|
|
|
/**
|
|
* Returns the name of the attribute at the specified index.
|
|
* @param i The index of the attribute whose name should be retrieved.
|
|
* @return Returns the name of the attribute, or "" if the index is out of range.
|
|
*/
|
|
std::string getAttributeName(size_t i);
|
|
|
|
/**
|
|
* Checks if this element can have the attribute specified.
|
|
* @param name The name of the attribute to look for.
|
|
* @return Returns true is this element can have an attribute with the name specified. False otherwise.
|
|
*/
|
|
daeBool hasAttribute(daeString name);
|
|
|
|
/**
|
|
* Checks if an attribute has been set either by being loaded from the COLLADA document or set
|
|
* programmatically.
|
|
* @param name The name of the attribute to check.
|
|
* @return Returns true if the attribute has been set. False if the attribute hasn't been set
|
|
* or doesn't exist for this element.
|
|
*/
|
|
daeBool isAttributeSet(daeString name);
|
|
|
|
/**
|
|
* Gets an attribute's value as a string.
|
|
* @param name The name of the attribute.
|
|
* @return The value of the attribute. Returns an empty string if this element doesn't
|
|
* have the specified attribute.
|
|
*/
|
|
std::string getAttribute(daeString name);
|
|
|
|
/**
|
|
* Just like the previous method, this method gets an attribute's value as a string. It
|
|
* takes the string as a reference parameter instead of returning it, for extra efficiency.
|
|
* @param name The name of the attribute.
|
|
* @param A string in which to store the value of the attribute. This will be set to an empty
|
|
* string if this element doesn't have the specified attribute.
|
|
*/
|
|
void getAttribute(daeString name, std::string& value);
|
|
|
|
/**
|
|
* Gets an attribute's value as a string.
|
|
* @param i The index of the attribute to retrieve.
|
|
* @return The value of the attribute.
|
|
*/
|
|
std::string getAttribute(size_t i);
|
|
|
|
/**
|
|
* Just like the previous method, this method gets an attribute's value as a string. It
|
|
* takes the string as a reference parameter instead of returning it, for extra efficiency.
|
|
* @param i The index of the attribute to retrieve.
|
|
* @param A string in which to store the value of the attribute.
|
|
*/
|
|
void getAttribute(size_t i, std::string& value);
|
|
|
|
struct DLLSPEC attr {
|
|
attr();
|
|
attr(const std::string& name, const std::string& value);
|
|
|
|
std::string name;
|
|
std::string value;
|
|
};
|
|
|
|
/**
|
|
* Returns an array containing all the attributes of this element.
|
|
* @return A daeArray of attr objects.
|
|
*/
|
|
daeTArray<attr> getAttributes();
|
|
|
|
/**
|
|
* Just like the previous method, this method returns an array containing all the attributes
|
|
* of this element. It returns the result via a reference parameter for extra efficiency.
|
|
* @param attrs The array of attr objects to return.
|
|
*/
|
|
void getAttributes(daeTArray<attr>& attrs);
|
|
|
|
/**
|
|
* Sets the attribute to the specified value.
|
|
* @param name Attribute to set.
|
|
* @param value Value to apply to the attribute.
|
|
* @return Returns true if the attribute was found and the value was set, false otherwise.
|
|
*/
|
|
virtual daeBool setAttribute(daeString name, daeString value);
|
|
|
|
/**
|
|
* Sets the attribute at the specified index to the given value.
|
|
* @param i Index of the attribute to set.
|
|
* @param value Value to apply to the attribute.
|
|
* @return Returns true if the attribute was found and the value was set, false otherwise.
|
|
*/
|
|
virtual daeBool setAttribute(size_t i, daeString value);
|
|
|
|
/**
|
|
* Returns the daeMetaAttribute object corresponding to the character data for this element.
|
|
* @return Returns a daeMetaAttribute object or NULL if this element doesn't have
|
|
* character data.
|
|
*/
|
|
daeMetaAttribute* getCharDataObject();
|
|
|
|
/**
|
|
* Checks if this element can have character data.
|
|
* @return Returns true if this element can have character data, false otherwise.
|
|
*/
|
|
daeBool hasCharData();
|
|
|
|
/**
|
|
* Returns this element's character data as a string.
|
|
* @return A string containing this element's character data, or an empty string
|
|
* if this element can't have character data.
|
|
*/
|
|
std::string getCharData();
|
|
|
|
/**
|
|
* Similar to the previous method, but fills a string passed in by the user for efficiency.
|
|
* @param data The string to be filled with this element's character content. The
|
|
* string is set to an empty string if this element can't have character data.
|
|
*/
|
|
void getCharData(std::string& data);
|
|
|
|
/**
|
|
* Sets this element's character data.
|
|
* @param data The new character data of this element.
|
|
* @return Returns true if this element can have character data and the character data
|
|
* was successfully changed, false otherwise.
|
|
*/
|
|
daeBool setCharData(const std::string& data);
|
|
|
|
// These functions are deprecated.
|
|
daeMemoryRef getAttributeValue(daeString name); // Use getAttribute or getAttributeObject instead.
|
|
daeBool hasValue(); // Use hasCharData instead.
|
|
daeMemoryRef getValuePointer(); // Use getCharData or getCharDataObject instead.
|
|
|
|
/**
|
|
* Finds the database document associated with @c this element.
|
|
* @return Returns the @c daeDocument representing the containing file or database
|
|
* group.
|
|
*/
|
|
daeDocument* getDocument() const { return _document; }
|
|
|
|
/**
|
|
* Deprecated.
|
|
*/
|
|
daeDocument* getCollection() const { return _document; }
|
|
|
|
/**
|
|
* Get the associated DAE object.
|
|
* @return The associated DAE object.
|
|
*/
|
|
DAE* getDAE();
|
|
|
|
/**
|
|
* Sets the database document associated with this element.
|
|
* @param c The daeDocument to associate with this element.
|
|
*/
|
|
void setDocument(daeDocument* c) { setDocument( c, true ); }
|
|
/**
|
|
* Deprecated.
|
|
*/
|
|
void setCollection(daeDocument* c );
|
|
|
|
/**
|
|
* Gets the URI of the document containing this element, note that this is NOT the URI of the element.
|
|
* @return Returns a pointer to the daeURI of the document containing this element.
|
|
*/
|
|
daeURI* getDocumentURI() const;
|
|
|
|
/**
|
|
* Creates an element via the element factory system. This creation
|
|
* is based @em only on potential child elements of this element.
|
|
* @param elementName Class name of the subelement to create.
|
|
* @return Returns the created @c daeElement, if it was successfully created.
|
|
*/
|
|
daeSmartRef<daeElement> createElement(daeString elementName);
|
|
|
|
/**
|
|
* Gets the container element for @c this element.
|
|
* If @c createAndPlace() was used to create the element, its parent is the the caller of @c createAndPlace().
|
|
* @return Returns the parent element, if @c this is not the top level element.
|
|
*/
|
|
daeElement* getParentElement() { return _parent;}
|
|
/**
|
|
* Deprecated. Use getParentElement()
|
|
* @deprecated
|
|
*/
|
|
daeElement* getXMLParentElement() { return _parent;}
|
|
/**
|
|
* Sets the parent element for this element.
|
|
* @param newParent The element which is the new parent element for this element.
|
|
* @note This function is called internally and not meant to be called form the client application.
|
|
*/
|
|
void setParentElement( daeElement *parent ) { _parent = parent; }
|
|
|
|
// These are helper structures to let the xml hierarchy search functions know when we've
|
|
// found a match. You can implement a custom matcher by inheriting from this structure,
|
|
// just like matchName and matchType.
|
|
struct DLLSPEC matchElement {
|
|
virtual bool operator()(daeElement* elt) const = 0;
|
|
virtual ~matchElement() { };
|
|
};
|
|
|
|
// Matches an element by name
|
|
struct DLLSPEC matchName : public matchElement {
|
|
matchName(daeString name);
|
|
virtual bool operator()(daeElement* elt) const;
|
|
std::string name;
|
|
};
|
|
|
|
// Matches an element by schema type
|
|
struct DLLSPEC matchType : public matchElement {
|
|
matchType(daeInt typeID);
|
|
virtual bool operator()(daeElement* elt) const;
|
|
daeInt typeID;
|
|
};
|
|
|
|
// Returns a matching child element. By "child", I mean one hierarchy level beneath the
|
|
// current element. This function is basically the same as getDescendant, except that it
|
|
// only goes one level deep.
|
|
daeElement* getChild(const matchElement& matcher);
|
|
|
|
// Performs a breadth-first search and returns a matching descendant element. A "descendant
|
|
// element" is an element beneath the current element in the xml hierarchy.
|
|
daeElement* getDescendant(const matchElement& matcher);
|
|
|
|
// Returns the parent element.
|
|
daeElement* getParent();
|
|
|
|
// Searches up through the xml hiearchy and returns a matching element.
|
|
daeElement* getAncestor(const matchElement& matcher);
|
|
|
|
// These functions perform the same as the functions above, except that they take the element
|
|
// name to match as a string. This makes these functions a little simpler to use if you're
|
|
// matching based on element name, which is assumed to be the most common case. Instead of
|
|
// "getChild(matchName(eltName))", you can just write "getChild(eltName)".
|
|
daeElement* getChild(daeString eltName);
|
|
daeElement* getDescendant(daeString eltName);
|
|
daeElement* getAncestor(daeString eltName);
|
|
|
|
/**
|
|
* Gets the associated Meta information for this element. This
|
|
* Meta also acts as a factory. See @c daeMetaElement documentation for more
|
|
* information.
|
|
* @return Returns the associated meta information.
|
|
*/
|
|
inline daeMetaElement* getMeta() { return _meta; }
|
|
|
|
// These functions are deprecated. Use typeID instead.
|
|
virtual COLLADA_TYPE::TypeEnum getElementType() const { return (COLLADA_TYPE::TypeEnum)0; }
|
|
daeString getTypeName() const;
|
|
|
|
/**
|
|
* Returns this element's type ID. Every element is an instance of a type specified in
|
|
* the Collada schema, and every schema type has a unique ID.
|
|
* @return The element's type ID.
|
|
*/
|
|
virtual daeInt typeID() const = 0;
|
|
|
|
/**
|
|
* Gets this element's name.
|
|
* @return Returns the string for the name.
|
|
* @remarks This function returns NULL if the element's name is identical to it's type's name.
|
|
*/
|
|
daeString getElementName() const;
|
|
/**
|
|
* Sets this element's name.
|
|
* @param nm Specifies the string to use as the element's name.
|
|
* @remarks Use caution when using this function since you can easily create invalid COLLADA documents.
|
|
*/
|
|
void setElementName( daeString nm );
|
|
|
|
/**
|
|
* Gets the element ID if it exists.
|
|
* @return Returns the value of the ID attribute, if there is such
|
|
* an attribute on this element type.
|
|
* @return the string for the element ID if it exists.
|
|
*/
|
|
daeString getID() const;
|
|
|
|
/**
|
|
* Gets the children/sub-elements of this element.
|
|
* This is a helper function used to easily access an element's children without the use of the
|
|
* _meta objects. This function adds the convenience of the _contents array to elements that do
|
|
* not contain a _contents array.
|
|
* @return The return value. An elementref array to append this element's children to.
|
|
*/
|
|
daeTArray< daeSmartRef<daeElement> > getChildren();
|
|
|
|
/**
|
|
* Same as the previous function, but returns the result via a parameter instead
|
|
* of a return value, for extra efficiency.
|
|
* @param array The return value. An elementref array to append this element's children to.
|
|
*/
|
|
//void getChildren( daeElementRefArray &array );
|
|
void getChildren( daeTArray<daeSmartRef<daeElement> > &array );
|
|
|
|
/**
|
|
* Gets all the children of a particular type.
|
|
* @return An array containing the matching child elements.
|
|
*/
|
|
template<typename T>
|
|
daeTArray< daeSmartRef<T> > getChildrenByType() {
|
|
daeTArray< daeSmartRef<T> > result;
|
|
getChildrenByType(result);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Same as the previous function, but returns the result via a parameter instead
|
|
* of a return value, for extra efficiency.
|
|
* @return An array containing the matching child elements.
|
|
*/
|
|
template<typename T>
|
|
void getChildrenByType(daeTArray< daeSmartRef<T> >& matchingChildren) {
|
|
matchingChildren.setCount(0);
|
|
daeTArray< daeSmartRef<daeElement> > children;
|
|
getChildren(children);
|
|
for (size_t i = 0; i < children.getCount(); i++)
|
|
if (children[i]->typeID() == T::ID())
|
|
matchingChildren.append((T*)children[i].cast());
|
|
}
|
|
|
|
/**
|
|
* Clones/deep copies this @c daeElement and all of it's subtree.
|
|
* @param idSuffix A string to append to the copied element's ID, if one exists.
|
|
* Default is no ID mangling.
|
|
* @param nameSuffix A string to append to the copied element's name, if one exists.
|
|
* Default is no name mangling.
|
|
* @return Returns a @c daeElement smartref of the copy of this element.
|
|
*/
|
|
daeSmartRef<daeElement> clone( daeString idSuffix = NULL, daeString nameSuffix = NULL );
|
|
|
|
// Class for reporting info about element comparisons
|
|
struct DLLSPEC compareResult {
|
|
int compareValue; // > 0 if elt1 > elt2,
|
|
// < 0 if elt1 < elt2,
|
|
// = 0 if elt1 = elt2
|
|
daeElement* elt1;
|
|
daeElement* elt2;
|
|
bool nameMismatch; // true if the names didn't match
|
|
std::string attrMismatch; // The name of the mismatched attribute, or "" if there was no attr mismatch
|
|
bool charDataMismatch; // true if the char data didn't match
|
|
bool childCountMismatch; // true if the number of children didn't match
|
|
|
|
compareResult();
|
|
std::string format(); // Write to a string
|
|
};
|
|
|
|
// Function for doing a generic, recursive comparison of two xml elements. It
|
|
// also provides a full element ordering, so that you could store elements in
|
|
// a map or a set. Return val is > 0 if elt1 > elt2, < 0 if elt1 < elt2, and 0
|
|
// if elt1 == elt2.
|
|
static int compare(daeElement& elt1, daeElement& elt2);
|
|
|
|
// Same as the previous function, but returns a full compareResult object.
|
|
static compareResult compareWithFullResult(daeElement& elt1, daeElement& elt2);
|
|
|
|
/**
|
|
* Sets the user data pointer attached to this element.
|
|
* @param data User's custom data to store.
|
|
*/
|
|
void setUserData(void* data);
|
|
|
|
/**
|
|
* Gets the user data pointer attached to this element.
|
|
* @return User data pointer previously set with setUserData.
|
|
*/
|
|
void* getUserData();
|
|
|
|
public:
|
|
// This function is called internally
|
|
static void deleteCMDataArray(daeTArray<daeCharArray*>& cmData);
|
|
};
|
|
|
|
#include <dae/daeSmartRef.h>
|
|
typedef daeSmartRef<daeElement> daeElementRef;
|
|
typedef daeSmartRef<const daeElement> daeElementConstRef;
|
|
//#include <dae/daeArray.h>
|
|
typedef daeTArray<daeElementRef> daeElementRefArray;
|
|
|
|
#endif //__DAE_ELEMENT_H__
|