mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-25 06:15:36 +00:00
Initial Implementation of the Taml, Asset and Modules systems.
Only has example and shape assets currently.
This commit is contained in:
parent
2044b2691e
commit
7a3b40a86d
123 changed files with 30435 additions and 181 deletions
193
Engine/source/persistence/taml/xml/tamlXmlParser.cpp
Normal file
193
Engine/source/persistence/taml/xml/tamlXmlParser.cpp
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2013 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "persistence/taml/xml/tamlXmlParser.h"
|
||||
#include "persistence/taml/tamlVisitor.h"
|
||||
#include "console/console.h"
|
||||
|
||||
// Debug Profiling.
|
||||
#include "platform/profiler.h"
|
||||
|
||||
#ifndef _FILESTREAM_H_
|
||||
#include "core/stream/fileStream.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool TamlXmlParser::accept( const char* pFilename, TamlVisitor& visitor )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlParser_Accept);
|
||||
|
||||
// Sanity!
|
||||
AssertFatal( pFilename != NULL, "Cannot parse a NULL filename." );
|
||||
|
||||
// Expand the file-path.
|
||||
char filenameBuffer[1024];
|
||||
// TODO: Make sure this is a proper substitute for
|
||||
// Con::expandPath (T2D)
|
||||
Con::expandToolScriptFilename( filenameBuffer, sizeof(filenameBuffer), pFilename );
|
||||
/** T2D uses a custom version of TinyXML that supports FileStream.
|
||||
* We don't so we can't do this
|
||||
*
|
||||
FileStream stream;
|
||||
|
||||
#ifdef TORQUE_OS_ANDROID
|
||||
if (strlen(pFilename) > strlen(filenameBuffer)) {
|
||||
strcpy(filenameBuffer, pFilename);
|
||||
}
|
||||
#endif
|
||||
|
||||
// File open for read?
|
||||
if ( !stream.open( filenameBuffer, Torque::FS::File::AccessMode::Read ) )
|
||||
{
|
||||
// No, so warn.
|
||||
Con::warnf("TamlXmlParser::parse() - Could not open filename '%s' for parse.", filenameBuffer );
|
||||
return false;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
TiXmlDocument xmlDocument;
|
||||
|
||||
// Load document from stream.
|
||||
if ( !xmlDocument.LoadFile( filenameBuffer ) )
|
||||
{
|
||||
// Warn!
|
||||
Con::warnf("TamlXmlParser: Could not load Taml XML file from stream.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close the stream.
|
||||
// stream.close();
|
||||
|
||||
// Set parsing filename.
|
||||
setParsingFilename( filenameBuffer );
|
||||
|
||||
// Flag document as not dirty.
|
||||
mDocumentDirty = false;
|
||||
|
||||
// Parse root element.
|
||||
parseElement( xmlDocument.RootElement(), visitor );
|
||||
|
||||
// Reset parsing filename.
|
||||
setParsingFilename( StringTable->EmptyString() );
|
||||
|
||||
// Finish if the document is not dirty.
|
||||
if ( !mDocumentDirty )
|
||||
return true;
|
||||
|
||||
// Open for write?
|
||||
/*if ( !stream.open( filenameBuffer, FileStream::StreamWrite ) )
|
||||
{
|
||||
// No, so warn.
|
||||
Con::warnf("TamlXmlParser::parse() - Could not open filename '%s' for write.", filenameBuffer );
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// Yes, so save the document.
|
||||
if ( !xmlDocument.SaveFile( filenameBuffer ) )
|
||||
{
|
||||
// Warn!
|
||||
Con::warnf("TamlXmlParser: Could not save Taml XML document.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close the stream.
|
||||
//stream.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline bool TamlXmlParser::parseElement( TiXmlElement* pXmlElement, TamlVisitor& visitor )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlParser_ParseElement);
|
||||
|
||||
// Parse attributes (stop processing if instructed).
|
||||
if ( !parseAttributes( pXmlElement, visitor ) )
|
||||
return false;
|
||||
|
||||
// Finish if only the root is needed.
|
||||
if ( visitor.wantsRootOnly() )
|
||||
return false;
|
||||
|
||||
// Fetch any children.
|
||||
TiXmlNode* pChildXmlNode = pXmlElement->FirstChild();
|
||||
|
||||
// Do we have any element children?
|
||||
if ( pChildXmlNode != NULL && pChildXmlNode->Type() == TiXmlNode::TINYXML_ELEMENT )
|
||||
{
|
||||
// Iterate children.
|
||||
for ( TiXmlElement* pChildXmlElement = dynamic_cast<TiXmlElement*>( pChildXmlNode ); pChildXmlElement; pChildXmlElement = pChildXmlElement->NextSiblingElement() )
|
||||
{
|
||||
// Parse element (stop processing if instructed).
|
||||
if ( !parseElement( pChildXmlElement, visitor ) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline bool TamlXmlParser::parseAttributes( TiXmlElement* pXmlElement, TamlVisitor& visitor )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlParser_ParseAttribute);
|
||||
|
||||
// Calculate if element is at the root or not.
|
||||
const bool isRoot = pXmlElement->GetDocument()->RootElement() == pXmlElement;
|
||||
|
||||
// Create a visitor property state.
|
||||
TamlVisitor::PropertyState propertyState;
|
||||
propertyState.setObjectName( pXmlElement->Value(), isRoot );
|
||||
|
||||
// Iterate attributes.
|
||||
for ( TiXmlAttribute* pAttribute = pXmlElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->Next() )
|
||||
{
|
||||
// Configure property state.
|
||||
propertyState.setProperty( pAttribute->Name(), pAttribute->Value() );
|
||||
|
||||
// Visit this attribute.
|
||||
const bool visitStatus = visitor.visit( *this, propertyState );
|
||||
|
||||
// Was the property value changed?
|
||||
if ( propertyState.getPropertyValueDirty() )
|
||||
{
|
||||
// Yes, so update the attribute.
|
||||
pAttribute->SetValue( propertyState.getPropertyValue() );
|
||||
|
||||
// Flag the document as dirty.
|
||||
mDocumentDirty = true;
|
||||
}
|
||||
|
||||
// Finish if requested.
|
||||
if ( !visitStatus )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
57
Engine/source/persistence/taml/xml/tamlXmlParser.h
Normal file
57
Engine/source/persistence/taml/xml/tamlXmlParser.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2013 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _TAML_XMLPARSER_H_
|
||||
#define _TAML_XMLPARSER_H_
|
||||
|
||||
#ifndef _TAML_PARSER_H_
|
||||
#include "persistence/taml/tamlParser.h"
|
||||
#endif
|
||||
|
||||
#ifndef TINYXML_INCLUDED
|
||||
#include "tinyXML/tinyxml.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @ingroup tamlGroup
|
||||
/// @see tamlGroup
|
||||
class TamlXmlParser : public TamlParser
|
||||
{
|
||||
public:
|
||||
TamlXmlParser() {}
|
||||
virtual ~TamlXmlParser() {}
|
||||
|
||||
/// Whether the parser can change a property or not.
|
||||
virtual bool canChangeProperty( void ) { return true; }
|
||||
|
||||
/// Accept visitor.
|
||||
virtual bool accept( const char* pFilename, TamlVisitor& visitor );
|
||||
|
||||
private:
|
||||
inline bool parseElement( TiXmlElement* pXmlElement, TamlVisitor& visitor );
|
||||
inline bool parseAttributes( TiXmlElement* pXmlElement, TamlVisitor& visitor );
|
||||
|
||||
bool mDocumentDirty;
|
||||
};
|
||||
|
||||
#endif // _TAML_XMLPARSER_H_
|
||||
484
Engine/source/persistence/taml/xml/tamlXmlReader.cpp
Normal file
484
Engine/source/persistence/taml/xml/tamlXmlReader.cpp
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2013 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "persistence/taml/xml/tamlXmlReader.h"
|
||||
|
||||
// Debug Profiling.
|
||||
#include "platform/profiler.h"
|
||||
#include "persistence/taml/fsTinyxml.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SimObject* TamlXmlReader::read( FileStream& stream )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlReader_Read);
|
||||
|
||||
// Create document.
|
||||
fsTiXmlDocument xmlDocument;
|
||||
|
||||
// Load document from stream.
|
||||
if ( !xmlDocument.LoadFile( stream ) )
|
||||
{
|
||||
// Warn!
|
||||
Con::warnf("Taml: Could not load Taml XML file from stream.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Parse root element.
|
||||
SimObject* pSimObject = parseElement( xmlDocument.RootElement() );
|
||||
|
||||
// Reset parse.
|
||||
resetParse();
|
||||
|
||||
return pSimObject;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlXmlReader::resetParse( void )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlReader_ResetParse);
|
||||
|
||||
// Clear object reference map.
|
||||
mObjectReferenceMap.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SimObject* TamlXmlReader::parseElement( TiXmlElement* pXmlElement )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlReader_ParseElement);
|
||||
|
||||
SimObject* pSimObject = NULL;
|
||||
|
||||
// Fetch element name.
|
||||
StringTableEntry typeName = StringTable->insert( pXmlElement->Value() );
|
||||
|
||||
// Fetch reference to Id.
|
||||
const U32 tamlRefToId = getTamlRefToId( pXmlElement );
|
||||
|
||||
// Do we have a reference to Id?
|
||||
if ( tamlRefToId != 0 )
|
||||
{
|
||||
// Yes, so fetch reference.
|
||||
typeObjectReferenceHash::Iterator referenceItr = mObjectReferenceMap.find( tamlRefToId );
|
||||
|
||||
// Did we find the reference?
|
||||
if ( referenceItr == mObjectReferenceMap.end() )
|
||||
{
|
||||
// No, so warn.
|
||||
Con::warnf( "Taml: Could not find a reference Id of '%d'", tamlRefToId );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Return object.
|
||||
return referenceItr->value;
|
||||
}
|
||||
|
||||
// No, so fetch reference Id.
|
||||
const U32 tamlRefId = getTamlRefId( pXmlElement );
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
// Format the type location.
|
||||
char typeLocationBuffer[64];
|
||||
dSprintf( typeLocationBuffer, sizeof(typeLocationBuffer), "Taml [format='xml' row=%d column=%d]", pXmlElement->Row(), pXmlElement->Column() );
|
||||
|
||||
// Create type.
|
||||
pSimObject = Taml::createType( typeName, mpTaml, typeLocationBuffer );
|
||||
#else
|
||||
// Create type.
|
||||
pSimObject = Taml::createType( typeName, mpTaml );
|
||||
#endif
|
||||
|
||||
|
||||
// Finish if we couldn't create the type.
|
||||
if ( pSimObject == NULL )
|
||||
return NULL;
|
||||
|
||||
// Find Taml callbacks.
|
||||
TamlCallbacks* pCallbacks = dynamic_cast<TamlCallbacks*>( pSimObject );
|
||||
|
||||
// Are there any Taml callbacks?
|
||||
if ( pCallbacks != NULL )
|
||||
{
|
||||
// Yes, so call it.
|
||||
mpTaml->tamlPreRead( pCallbacks );
|
||||
}
|
||||
|
||||
// Parse attributes.
|
||||
parseAttributes( pXmlElement, pSimObject );
|
||||
|
||||
// Fetch object name.
|
||||
StringTableEntry objectName = StringTable->insert( getTamlObjectName( pXmlElement ) );
|
||||
|
||||
// Does the object require a name?
|
||||
if ( objectName == StringTable->EmptyString() )
|
||||
{
|
||||
// No, so just register anonymously.
|
||||
pSimObject->registerObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Yes, so register a named object.
|
||||
pSimObject->registerObject( objectName );
|
||||
|
||||
// Was the name assigned?
|
||||
if ( pSimObject->getName() != objectName )
|
||||
{
|
||||
// No, so warn that the name was rejected.
|
||||
#ifdef TORQUE_DEBUG
|
||||
Con::warnf( "Taml::parseElement() - Registered an instance of type '%s' but a request to name it '%s' was rejected. This is typically because an object of that name already exists. '%s'", typeName, objectName, typeLocationBuffer );
|
||||
#else
|
||||
Con::warnf( "Taml::parseElement() - Registered an instance of type '%s' but a request to name it '%s' was rejected. This is typically because an object of that name already exists.", typeName, objectName );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Do we have a reference Id?
|
||||
if ( tamlRefId != 0 )
|
||||
{
|
||||
// Yes, so insert reference.
|
||||
mObjectReferenceMap.insertUnique( tamlRefId, pSimObject );
|
||||
}
|
||||
|
||||
// Fetch any children.
|
||||
TiXmlNode* pChildXmlNode = pXmlElement->FirstChild();
|
||||
|
||||
TamlCustomNodes customProperties;
|
||||
|
||||
// Do we have any element children?
|
||||
if ( pChildXmlNode != NULL )
|
||||
{
|
||||
// Fetch the Taml children.
|
||||
TamlChildren* pChildren = dynamic_cast<TamlChildren*>( pSimObject );
|
||||
|
||||
// Fetch any container child class specifier.
|
||||
AbstractClassRep* pContainerChildClass = pSimObject->getClassRep()->getContainerChildClass( true );
|
||||
|
||||
// Iterate siblings.
|
||||
do
|
||||
{
|
||||
// Fetch element.
|
||||
TiXmlElement* pChildXmlElement = dynamic_cast<TiXmlElement*>( pChildXmlNode );
|
||||
|
||||
// Move to next sibling.
|
||||
pChildXmlNode = pChildXmlNode->NextSibling();
|
||||
|
||||
// Skip if this is not an element?
|
||||
if ( pChildXmlElement == NULL )
|
||||
continue;
|
||||
|
||||
// Is this a standard child element?
|
||||
if ( dStrchr( pChildXmlElement->Value(), '.' ) == NULL )
|
||||
{
|
||||
// Is this a Taml child?
|
||||
if ( pChildren == NULL )
|
||||
{
|
||||
// No, so warn.
|
||||
Con::warnf("Taml: Child element '%s' found under parent '%s' but object cannot have children.",
|
||||
pChildXmlElement->Value(),
|
||||
pXmlElement->Value() );
|
||||
|
||||
// Skip.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Yes, so parse child element.
|
||||
SimObject* pChildSimObject = parseElement( pChildXmlElement );
|
||||
|
||||
// Skip if the child was not created.
|
||||
if ( pChildSimObject == NULL )
|
||||
continue;
|
||||
|
||||
// Do we have a container child class?
|
||||
if ( pContainerChildClass != NULL )
|
||||
{
|
||||
// Yes, so is the child object the correctly derived type?
|
||||
if ( !pChildSimObject->getClassRep()->isClass( pContainerChildClass ) )
|
||||
{
|
||||
// No, so warn.
|
||||
Con::warnf("Taml: Child element '%s' found under parent '%s' but object is restricted to children of type '%s'.",
|
||||
pChildSimObject->getClassName(),
|
||||
pSimObject->getClassName(),
|
||||
pContainerChildClass->getClassName() );
|
||||
|
||||
// NOTE: We can't delete the object as it may be referenced elsewhere!
|
||||
pChildSimObject = NULL;
|
||||
|
||||
// Skip.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Add child.
|
||||
pChildren->addTamlChild( pChildSimObject );
|
||||
|
||||
// Find Taml callbacks for child.
|
||||
TamlCallbacks* pChildCallbacks = dynamic_cast<TamlCallbacks*>( pChildSimObject );
|
||||
|
||||
// Do we have callbacks on the child?
|
||||
if ( pChildCallbacks != NULL )
|
||||
{
|
||||
// Yes, so perform callback.
|
||||
mpTaml->tamlAddParent( pChildCallbacks, pSimObject );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No, so parse custom element.
|
||||
parseCustomElement( pChildXmlElement, customProperties );
|
||||
}
|
||||
}
|
||||
while( pChildXmlNode != NULL );
|
||||
|
||||
// Call custom read.
|
||||
mpTaml->tamlCustomRead( pCallbacks, customProperties );
|
||||
}
|
||||
|
||||
// Are there any Taml callbacks?
|
||||
if ( pCallbacks != NULL )
|
||||
{
|
||||
// Yes, so call it.
|
||||
mpTaml->tamlPostRead( pCallbacks, customProperties );
|
||||
}
|
||||
|
||||
// Return object.
|
||||
return pSimObject;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlXmlReader::parseAttributes( TiXmlElement* pXmlElement, SimObject* pSimObject )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlReader_ParseAttributes);
|
||||
|
||||
// Sanity!
|
||||
AssertFatal( pSimObject != NULL, "Taml: Cannot parse attributes on a NULL object." );
|
||||
|
||||
// Iterate attributes.
|
||||
for ( TiXmlAttribute* pAttribute = pXmlElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->Next() )
|
||||
{
|
||||
// Insert attribute name.
|
||||
StringTableEntry attributeName = StringTable->insert( pAttribute->Name() );
|
||||
|
||||
// Ignore if this is a Taml attribute.
|
||||
if ( attributeName == tamlRefIdName ||
|
||||
attributeName == tamlRefToIdName ||
|
||||
attributeName == tamlNamedObjectName )
|
||||
continue;
|
||||
|
||||
// Set the field.
|
||||
pSimObject->setPrefixedDataField(attributeName, NULL, pAttribute->Value());
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlXmlReader::parseCustomElement( TiXmlElement* pXmlElement, TamlCustomNodes& customNodes )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlReader_ParseCustomElement);
|
||||
|
||||
// Is this a standard child element?
|
||||
const char* pPeriod = dStrchr( pXmlElement->Value(), '.' );
|
||||
|
||||
// Sanity!
|
||||
AssertFatal( pPeriod != NULL, "Parsing extended element but no period character found." );
|
||||
|
||||
// Fetch any custom XML node.
|
||||
TiXmlNode* pCustomXmlNode = pXmlElement->FirstChild();
|
||||
|
||||
// Finish is no XML node exists.
|
||||
if ( pCustomXmlNode == NULL )
|
||||
return;
|
||||
|
||||
// Yes, so add custom node.
|
||||
TamlCustomNode* pCustomNode = customNodes.addNode( pPeriod+1 );
|
||||
|
||||
do
|
||||
{
|
||||
// Fetch element.
|
||||
TiXmlElement* pCustomXmlElement = dynamic_cast<TiXmlElement*>( pCustomXmlNode );
|
||||
|
||||
// Move to next sibling.
|
||||
pCustomXmlNode = pCustomXmlNode->NextSibling();
|
||||
|
||||
// Skip if this is not an element.
|
||||
if ( pCustomXmlElement == NULL )
|
||||
continue;
|
||||
|
||||
// Parse custom node.
|
||||
parseCustomNode( pCustomXmlElement, pCustomNode );
|
||||
}
|
||||
while ( pCustomXmlNode != NULL );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlXmlReader::parseCustomNode( TiXmlElement* pXmlElement, TamlCustomNode* pCustomNode )
|
||||
{
|
||||
// Is the node a proxy object?
|
||||
if ( getTamlRefId( pXmlElement ) != 0 || getTamlRefToId( pXmlElement ) != 0 )
|
||||
{
|
||||
// Yes, so parse proxy object.
|
||||
SimObject* pProxyObject = parseElement( pXmlElement );
|
||||
|
||||
// Add child node.
|
||||
pCustomNode->addNode( pProxyObject );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Yes, so add child node.
|
||||
TamlCustomNode* pChildNode = pCustomNode->addNode( pXmlElement->Value() );
|
||||
|
||||
// Iterate attributes.
|
||||
for ( TiXmlAttribute* pAttribute = pXmlElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->Next() )
|
||||
{
|
||||
// Insert attribute name.
|
||||
StringTableEntry attributeName = StringTable->insert( pAttribute->Name() );
|
||||
|
||||
// Skip if a Taml reference attribute.
|
||||
if ( attributeName == tamlRefIdName || attributeName == tamlRefToIdName )
|
||||
continue;
|
||||
|
||||
// Add node field.
|
||||
pChildNode->addField( attributeName, pAttribute->Value() );
|
||||
}
|
||||
|
||||
// Fetch any element text.
|
||||
const char* pElementText = pXmlElement->GetText();
|
||||
|
||||
// Do we have any element text?
|
||||
if ( pElementText != NULL )
|
||||
{
|
||||
// Yes, so store it.
|
||||
pChildNode->setNodeText( pElementText );
|
||||
}
|
||||
|
||||
// Fetch any children.
|
||||
TiXmlNode* pChildXmlNode = pXmlElement->FirstChild();
|
||||
|
||||
// Do we have any element children?
|
||||
if ( pChildXmlNode != NULL )
|
||||
{
|
||||
do
|
||||
{
|
||||
// Yes, so fetch child element.
|
||||
TiXmlElement* pChildXmlElement = dynamic_cast<TiXmlElement*>( pChildXmlNode );
|
||||
|
||||
// Move to next sibling.
|
||||
pChildXmlNode = pChildXmlNode->NextSibling();
|
||||
|
||||
// Skip if this is not an element.
|
||||
if ( pChildXmlElement == NULL )
|
||||
continue;
|
||||
|
||||
// Parse custom node.
|
||||
parseCustomNode( pChildXmlElement, pChildNode );
|
||||
}
|
||||
while( pChildXmlNode != NULL );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
U32 TamlXmlReader::getTamlRefId( TiXmlElement* pXmlElement )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlReader_GetTamlRefId);
|
||||
|
||||
// Iterate attributes.
|
||||
for ( TiXmlAttribute* pAttribute = pXmlElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->Next() )
|
||||
{
|
||||
// Insert attribute name.
|
||||
StringTableEntry attributeName = StringTable->insert( pAttribute->Name() );
|
||||
|
||||
// Skip if not the correct attribute.
|
||||
if ( attributeName != tamlRefIdName )
|
||||
continue;
|
||||
|
||||
// Return it.
|
||||
return dAtoi( pAttribute->Value() );
|
||||
}
|
||||
|
||||
// Not found.
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
U32 TamlXmlReader::getTamlRefToId( TiXmlElement* pXmlElement )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlReader_GetTamlRefToId);
|
||||
|
||||
// Iterate attributes.
|
||||
for ( TiXmlAttribute* pAttribute = pXmlElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->Next() )
|
||||
{
|
||||
// Insert attribute name.
|
||||
StringTableEntry attributeName = StringTable->insert( pAttribute->Name() );
|
||||
|
||||
// Skip if not the correct attribute.
|
||||
if ( attributeName != tamlRefToIdName )
|
||||
continue;
|
||||
|
||||
// Return it.
|
||||
return dAtoi( pAttribute->Value() );
|
||||
}
|
||||
|
||||
// Not found.
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* TamlXmlReader::getTamlObjectName( TiXmlElement* pXmlElement )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlReader_GetTamlObjectName);
|
||||
|
||||
// Iterate attributes.
|
||||
for ( TiXmlAttribute* pAttribute = pXmlElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->Next() )
|
||||
{
|
||||
// Insert attribute name.
|
||||
StringTableEntry attributeName = StringTable->insert( pAttribute->Name() );
|
||||
|
||||
// Skip if not the correct attribute.
|
||||
if ( attributeName != tamlNamedObjectName )
|
||||
continue;
|
||||
|
||||
// Return it.
|
||||
return pAttribute->Value();
|
||||
}
|
||||
|
||||
// Not found.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
73
Engine/source/persistence/taml/xml/tamlXmlReader.h
Normal file
73
Engine/source/persistence/taml/xml/tamlXmlReader.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2013 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _TAML_XMLREADER_H_
|
||||
#define _TAML_XMLREADER_H_
|
||||
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
|
||||
#ifndef _TAML_H_
|
||||
#include "persistence/taml/taml.h"
|
||||
#endif
|
||||
|
||||
#ifndef TINYXML_INCLUDED
|
||||
#include "tinyXML/tinyxml.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @ingroup tamlGroup
|
||||
/// @see tamlGroup
|
||||
class TamlXmlReader
|
||||
{
|
||||
public:
|
||||
TamlXmlReader( Taml* pTaml ) :
|
||||
mpTaml( pTaml )
|
||||
{}
|
||||
|
||||
virtual ~TamlXmlReader() {}
|
||||
|
||||
/// Read.
|
||||
SimObject* read( FileStream& stream );
|
||||
|
||||
private:
|
||||
Taml* mpTaml;
|
||||
|
||||
typedef HashTable<SimObjectId, SimObject*> typeObjectReferenceHash;
|
||||
typeObjectReferenceHash mObjectReferenceMap;
|
||||
|
||||
private:
|
||||
void resetParse( void );
|
||||
|
||||
SimObject* parseElement( TiXmlElement* pXmlElement );
|
||||
void parseAttributes( TiXmlElement* pXmlElement, SimObject* pSimObject );
|
||||
void parseCustomElement( TiXmlElement* pXmlElement, TamlCustomNodes& pCustomNode );
|
||||
void parseCustomNode( TiXmlElement* pXmlElement, TamlCustomNode* pCustomNode );
|
||||
|
||||
U32 getTamlRefId( TiXmlElement* pXmlElement );
|
||||
U32 getTamlRefToId( TiXmlElement* pXmlElement );
|
||||
const char* getTamlObjectName( TiXmlElement* pXmlElement );
|
||||
};
|
||||
|
||||
#endif // _TAML_XMLREADER_H_
|
||||
301
Engine/source/persistence/taml/xml/tamlXmlWriter.cpp
Normal file
301
Engine/source/persistence/taml/xml/tamlXmlWriter.cpp
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2013 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "persistence/taml/xml/tamlXmlWriter.h"
|
||||
|
||||
// Debug Profiling.
|
||||
#include "platform/profiler.h"
|
||||
#include "persistence/taml/fsTinyxml.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool TamlXmlWriter::write( FileStream& stream, const TamlWriteNode* pTamlWriteNode )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlWriter_Write);
|
||||
|
||||
// Create document.
|
||||
fsTiXmlDocument xmlDocument;
|
||||
|
||||
// Compile the root element.
|
||||
TiXmlElement* pRootElement = compileElement( pTamlWriteNode );
|
||||
|
||||
// Fetch any TAML Schema file reference.
|
||||
const char* pTamlSchemaFile = Con::getVariable( TAML_SCHEMA_VARIABLE );
|
||||
|
||||
// Do we have a schema file reference?
|
||||
if ( pTamlSchemaFile != NULL && *pTamlSchemaFile != 0 )
|
||||
{
|
||||
// Yes, so add namespace attribute to root.
|
||||
pRootElement->SetAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
|
||||
|
||||
// Expand the file-path reference.
|
||||
char schemaFilePathBuffer[1024];
|
||||
Con::expandToolScriptFilename( schemaFilePathBuffer, sizeof(schemaFilePathBuffer), pTamlSchemaFile );
|
||||
|
||||
// Fetch the output path for the Taml file.
|
||||
char outputFileBuffer[1024];
|
||||
dSprintf( outputFileBuffer, sizeof(outputFileBuffer), "%s", mpTaml->getFilePathBuffer() );
|
||||
char* pFileStart = dStrrchr( outputFileBuffer, '/' );
|
||||
if ( pFileStart == NULL )
|
||||
*outputFileBuffer = 0;
|
||||
else
|
||||
*pFileStart = 0;
|
||||
|
||||
// Fetch the schema file-path relative to the output file.
|
||||
StringTableEntry relativeSchemaFilePath = Platform::makeRelativePathName( schemaFilePathBuffer, outputFileBuffer );
|
||||
|
||||
// Add schema location attribute to root.
|
||||
pRootElement->SetAttribute( "xsi:noNamespaceSchemaLocation", relativeSchemaFilePath );
|
||||
}
|
||||
|
||||
// Link the root element.
|
||||
xmlDocument.LinkEndChild( pRootElement );
|
||||
|
||||
// Save document to stream.
|
||||
return xmlDocument.SaveFile( stream );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
TiXmlElement* TamlXmlWriter::compileElement( const TamlWriteNode* pTamlWriteNode )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlWriter_CompileElement);
|
||||
|
||||
// Fetch object.
|
||||
SimObject* pSimObject = pTamlWriteNode->mpSimObject;
|
||||
|
||||
// Fetch element name.
|
||||
const char* pElementName = pSimObject->getClassName();
|
||||
|
||||
// Create element.
|
||||
TiXmlElement* pElement = new fsTiXmlElement( pElementName );
|
||||
|
||||
// Fetch reference Id.
|
||||
const U32 referenceId = pTamlWriteNode->mRefId;
|
||||
|
||||
// Do we have a reference Id?
|
||||
if ( referenceId != 0 )
|
||||
{
|
||||
// Yes, so set reference Id attribute.
|
||||
pElement->SetAttribute( tamlRefIdName, referenceId );
|
||||
}
|
||||
|
||||
// Do we have a reference to node?
|
||||
else if ( pTamlWriteNode->mRefToNode != NULL )
|
||||
{
|
||||
// Yes, so fetch reference to Id.
|
||||
const U32 referenceToId = pTamlWriteNode->mRefToNode->mRefId;
|
||||
|
||||
// Sanity!
|
||||
AssertFatal( referenceToId != 0, "Taml: Invalid reference to Id." );
|
||||
|
||||
// Set reference to Id attribute.
|
||||
pElement->SetAttribute( tamlRefToIdName, referenceToId );
|
||||
|
||||
// Finish because we're a reference to another object.
|
||||
return pElement;
|
||||
}
|
||||
|
||||
// Fetch object name.
|
||||
const char* pObjectName = pTamlWriteNode->mpObjectName;
|
||||
|
||||
// Do we have a name?
|
||||
if ( pObjectName != NULL )
|
||||
{
|
||||
// Yes, so set name attribute.
|
||||
pElement->SetAttribute( tamlNamedObjectName, pObjectName );
|
||||
}
|
||||
|
||||
// Compile attributes.
|
||||
compileAttributes( pElement, pTamlWriteNode );
|
||||
|
||||
// Fetch children.
|
||||
Vector<TamlWriteNode*>* pChildren = pTamlWriteNode->mChildren;
|
||||
|
||||
// Do we have any children?
|
||||
if ( pChildren )
|
||||
{
|
||||
// Yes, so iterate children.
|
||||
for( Vector<TamlWriteNode*>::iterator itr = pChildren->begin(); itr != pChildren->end(); ++itr )
|
||||
{
|
||||
// Write child element.
|
||||
pElement->LinkEndChild( compileElement( (*itr) ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Compile custom elements.
|
||||
compileCustomElements( pElement, pTamlWriteNode );
|
||||
|
||||
return pElement;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlXmlWriter::compileAttributes( TiXmlElement* pXmlElement, const TamlWriteNode* pTamlWriteNode )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlWriter_CompileAttributes);
|
||||
|
||||
// Fetch fields.
|
||||
const Vector<TamlWriteNode::FieldValuePair*>& fields = pTamlWriteNode->mFields;
|
||||
|
||||
// Ignore if no fields.
|
||||
if ( fields.size() == 0 )
|
||||
return;
|
||||
|
||||
// Iterate fields.
|
||||
for( Vector<TamlWriteNode::FieldValuePair*>::const_iterator itr = fields.begin(); itr != fields.end(); ++itr )
|
||||
{
|
||||
// Fetch field/value pair.
|
||||
TamlWriteNode::FieldValuePair* pFieldValue = (*itr);
|
||||
|
||||
// Set field attribute.
|
||||
pXmlElement->SetAttribute( pFieldValue->mName, pFieldValue->mpValue );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlXmlWriter::compileCustomElements( TiXmlElement* pXmlElement, const TamlWriteNode* pTamlWriteNode )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlXmlWriter_CompileCustomElements);
|
||||
|
||||
// Fetch custom nodes.
|
||||
const TamlCustomNodes& customNodes = pTamlWriteNode->mCustomNodes;
|
||||
|
||||
// Fetch custom nodes.
|
||||
const TamlCustomNodeVector& nodes = customNodes.getNodes();
|
||||
|
||||
// Finish if no custom nodes to process.
|
||||
if ( nodes.size() == 0 )
|
||||
return;
|
||||
|
||||
// Iterate custom nodes.
|
||||
for( TamlCustomNodeVector::const_iterator customNodesItr = nodes.begin(); customNodesItr != nodes.end(); ++customNodesItr )
|
||||
{
|
||||
// Fetch the custom node.
|
||||
TamlCustomNode* pCustomNode = *customNodesItr;
|
||||
|
||||
// Format extended element name.
|
||||
char extendedElementNameBuffer[256];
|
||||
dSprintf( extendedElementNameBuffer, sizeof(extendedElementNameBuffer), "%s.%s", pXmlElement->Value(), pCustomNode->getNodeName() );
|
||||
StringTableEntry extendedElementName = StringTable->insert( extendedElementNameBuffer );
|
||||
|
||||
// Create element.
|
||||
TiXmlElement* pExtendedPropertyElement = new fsTiXmlElement( extendedElementName );
|
||||
|
||||
// Fetch node children.
|
||||
const TamlCustomNodeVector& nodeChildren = pCustomNode->getChildren();
|
||||
|
||||
// Iterate children nodes.
|
||||
for( TamlCustomNodeVector::const_iterator childNodeItr = nodeChildren.begin(); childNodeItr != nodeChildren.end(); ++childNodeItr )
|
||||
{
|
||||
// Fetch child node.
|
||||
const TamlCustomNode* pChildNode = *childNodeItr;
|
||||
|
||||
// Compile the custom node.
|
||||
compileCustomNode( pExtendedPropertyElement, pChildNode );
|
||||
}
|
||||
|
||||
// Finish if the node is set to ignore if empty and it is empty.
|
||||
if ( pCustomNode->getIgnoreEmpty() && pExtendedPropertyElement->NoChildren() )
|
||||
{
|
||||
// Yes, so delete the extended element.
|
||||
delete pExtendedPropertyElement;
|
||||
pExtendedPropertyElement = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No, so add elementt as child.
|
||||
pXmlElement->LinkEndChild( pExtendedPropertyElement );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlXmlWriter::compileCustomNode( TiXmlElement* pXmlElement, const TamlCustomNode* pCustomNode )
|
||||
{
|
||||
// Finish if the node is set to ignore if empty and it is empty.
|
||||
if ( pCustomNode->getIgnoreEmpty() && pCustomNode->isEmpty() )
|
||||
return;
|
||||
|
||||
// Is the node a proxy object?
|
||||
if ( pCustomNode->isProxyObject() )
|
||||
{
|
||||
// Yes, so write the proxy object.
|
||||
pXmlElement->LinkEndChild( compileElement( pCustomNode->getProxyWriteNode() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
// Create element.
|
||||
TiXmlElement* pNodeElement = new fsTiXmlElement( pCustomNode->getNodeName() );
|
||||
|
||||
// Is there any node text?
|
||||
if ( !pCustomNode->getNodeTextField().isValueEmpty() )
|
||||
{
|
||||
// Yes, so add a text node.
|
||||
pNodeElement->LinkEndChild( new TiXmlText( pCustomNode->getNodeTextField().getFieldValue() ) );
|
||||
}
|
||||
|
||||
// Fetch fields.
|
||||
const TamlCustomFieldVector& fields = pCustomNode->getFields();
|
||||
|
||||
// Iterate fields.
|
||||
for ( TamlCustomFieldVector::const_iterator fieldItr = fields.begin(); fieldItr != fields.end(); ++fieldItr )
|
||||
{
|
||||
// Fetch field.
|
||||
const TamlCustomField* pField = *fieldItr;
|
||||
|
||||
// Set field.
|
||||
pNodeElement->SetAttribute( pField->getFieldName(), pField->getFieldValue() );
|
||||
}
|
||||
|
||||
// Fetch node children.
|
||||
const TamlCustomNodeVector& nodeChildren = pCustomNode->getChildren();
|
||||
|
||||
// Iterate children nodes.
|
||||
for( TamlCustomNodeVector::const_iterator childNodeItr = nodeChildren.begin(); childNodeItr != nodeChildren.end(); ++childNodeItr )
|
||||
{
|
||||
// Fetch child node.
|
||||
const TamlCustomNode* pChildNode = *childNodeItr;
|
||||
|
||||
// Compile the child node.
|
||||
compileCustomNode( pNodeElement, pChildNode );
|
||||
}
|
||||
|
||||
// Finish if the node is set to ignore if empty and it is empty (including fields).
|
||||
if ( pCustomNode->getIgnoreEmpty() && fields.size() == 0 && pNodeElement->NoChildren() )
|
||||
{
|
||||
// Yes, so delete the extended element.
|
||||
delete pNodeElement;
|
||||
pNodeElement = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add node element as child.
|
||||
pXmlElement->LinkEndChild( pNodeElement );
|
||||
}
|
||||
}
|
||||
59
Engine/source/persistence/taml/xml/tamlXmlWriter.h
Normal file
59
Engine/source/persistence/taml/xml/tamlXmlWriter.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2013 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _TAML_XMLWRITER_H_
|
||||
#define _TAML_XMLWRITER_H_
|
||||
|
||||
#ifndef _TAML_H_
|
||||
#include "persistence/taml/taml.h"
|
||||
#endif
|
||||
|
||||
#ifndef TINYXML_INCLUDED
|
||||
#include "tinyXML/tinyxml.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @ingroup tamlGroup
|
||||
/// @see tamlGroup
|
||||
class TamlXmlWriter
|
||||
{
|
||||
public:
|
||||
TamlXmlWriter( Taml* pTaml ) :
|
||||
mpTaml( pTaml )
|
||||
{}
|
||||
virtual ~TamlXmlWriter() {}
|
||||
|
||||
/// Write.
|
||||
bool write( FileStream& stream, const TamlWriteNode* pTamlWriteNode );
|
||||
|
||||
private:
|
||||
Taml* mpTaml;
|
||||
|
||||
private:
|
||||
TiXmlElement* compileElement( const TamlWriteNode* pTamlWriteNode );
|
||||
void compileAttributes( TiXmlElement* pXmlElement, const TamlWriteNode* pTamlWriteNode );
|
||||
void compileCustomElements( TiXmlElement* pXmlElement, const TamlWriteNode* pTamlWriteNode );
|
||||
void compileCustomNode( TiXmlElement* pXmlElement, const TamlCustomNode* pCustomNode );
|
||||
};
|
||||
|
||||
#endif // _TAML_XMLWRITER_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue