mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-06 05:50:31 +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
429
Engine/source/persistence/taml/binary/tamlBinaryReader.cpp
Normal file
429
Engine/source/persistence/taml/binary/tamlBinaryReader.cpp
Normal file
|
|
@ -0,0 +1,429 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/binary/tamlBinaryReader.h"
|
||||
|
||||
#ifndef _ZIPSUBSTREAM_H_
|
||||
#include "core/util/zip/zipSubStream.h"
|
||||
#endif
|
||||
|
||||
// Debug Profiling.
|
||||
#include "platform/profiler.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SimObject* TamlBinaryReader::read( FileStream& stream )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryReader_Read);
|
||||
|
||||
// Read Taml signature.
|
||||
StringTableEntry tamlSignature = stream.readSTString();
|
||||
|
||||
// Is the signature correct?
|
||||
if ( tamlSignature != StringTable->insert( TAML_SIGNATURE ) )
|
||||
{
|
||||
// Warn.
|
||||
Con::warnf("Taml: Cannot read binary file as signature is incorrect '%s'.", tamlSignature );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Read version Id.
|
||||
U32 versionId;
|
||||
stream.read( &versionId );
|
||||
|
||||
// Read compressed flag.
|
||||
bool compressed;
|
||||
stream.read( &compressed );
|
||||
|
||||
SimObject* pSimObject = NULL;
|
||||
|
||||
// Is the stream compressed?
|
||||
if ( compressed )
|
||||
{
|
||||
// Yes, so attach zip stream.
|
||||
ZipSubRStream zipStream;
|
||||
zipStream.attachStream( &stream );
|
||||
|
||||
// Parse element.
|
||||
pSimObject = parseElement( zipStream, versionId );
|
||||
|
||||
// Detach zip stream.
|
||||
zipStream.detachStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
// No, so parse element.
|
||||
pSimObject = parseElement( stream, versionId );
|
||||
}
|
||||
|
||||
return pSimObject;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlBinaryReader::resetParse( void )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryReader_ResetParse);
|
||||
|
||||
// Clear object reference map.
|
||||
mObjectReferenceMap.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SimObject* TamlBinaryReader::parseElement( Stream& stream, const U32 versionId )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryReader_ParseElement);
|
||||
|
||||
SimObject* pSimObject = NULL;
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
// Format the type location.
|
||||
char typeLocationBuffer[64];
|
||||
dSprintf( typeLocationBuffer, sizeof(typeLocationBuffer), "Taml [format='binary' offset=%u]", stream.getPosition() );
|
||||
#endif
|
||||
|
||||
// Fetch element name.
|
||||
StringTableEntry typeName = stream.readSTString();
|
||||
|
||||
// Fetch object name.
|
||||
StringTableEntry objectName = stream.readSTString();
|
||||
|
||||
// Read references.
|
||||
U32 tamlRefId;
|
||||
U32 tamlRefToId;
|
||||
stream.read( &tamlRefId );
|
||||
stream.read( &tamlRefToId );
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
// 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( stream, pSimObject, versionId );
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
// Parse custom elements.
|
||||
TamlCustomNodes customProperties;
|
||||
|
||||
// Parse children.
|
||||
parseChildren( stream, pCallbacks, pSimObject, versionId );
|
||||
|
||||
// Parse custom elements.
|
||||
parseCustomElements( stream, pCallbacks, customProperties, versionId );
|
||||
|
||||
// Are there any Taml callbacks?
|
||||
if ( pCallbacks != NULL )
|
||||
{
|
||||
// Yes, so call it.
|
||||
mpTaml->tamlPostRead( pCallbacks, customProperties );
|
||||
}
|
||||
|
||||
// Return object.
|
||||
return pSimObject;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlBinaryReader::parseAttributes( Stream& stream, SimObject* pSimObject, const U32 versionId )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryReader_ParseAttributes);
|
||||
|
||||
// Sanity!
|
||||
AssertFatal( pSimObject != NULL, "Taml: Cannot parse attributes on a NULL object." );
|
||||
|
||||
// Fetch attribute count.
|
||||
U32 attributeCount;
|
||||
stream.read( &attributeCount );
|
||||
|
||||
// Finish if no attributes.
|
||||
if ( attributeCount == 0 )
|
||||
return;
|
||||
|
||||
char valueBuffer[4096];
|
||||
|
||||
// Iterate attributes.
|
||||
for ( U32 index = 0; index < attributeCount; ++index )
|
||||
{
|
||||
// Fetch attribute.
|
||||
StringTableEntry attributeName = stream.readSTString();
|
||||
stream.readLongString( 4096, valueBuffer );
|
||||
|
||||
// We can assume this is a field for now.
|
||||
pSimObject->setPrefixedDataField(attributeName, NULL, valueBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlBinaryReader::parseChildren( Stream& stream, TamlCallbacks* pCallbacks, SimObject* pSimObject, const U32 versionId )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryReader_ParseChildren);
|
||||
|
||||
// Sanity!
|
||||
AssertFatal( pSimObject != NULL, "Taml: Cannot parse children on a NULL object." );
|
||||
|
||||
// Fetch children count.
|
||||
U32 childrenCount;
|
||||
stream.read( &childrenCount );
|
||||
|
||||
// Finish if no children.
|
||||
if ( childrenCount == 0 )
|
||||
return;
|
||||
|
||||
// Fetch the Taml children.
|
||||
TamlChildren* pChildren = dynamic_cast<TamlChildren*>( pSimObject );
|
||||
|
||||
// Is this a sim set?
|
||||
if ( pChildren == NULL )
|
||||
{
|
||||
// No, so warn.
|
||||
Con::warnf("Taml: Child element found under parent but object cannot have children." );
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch any container child class specifier.
|
||||
AbstractClassRep* pContainerChildClass = pSimObject->getClassRep()->getContainerChildClass( true );
|
||||
|
||||
// Iterate children.
|
||||
for ( U32 index = 0; index < childrenCount; ++ index )
|
||||
{
|
||||
// Parse child element.
|
||||
SimObject* pChildSimObject = parseElement( stream, versionId );
|
||||
|
||||
// Finish if child failed.
|
||||
if ( pChildSimObject == NULL )
|
||||
return;
|
||||
|
||||
// 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlBinaryReader::parseCustomElements( Stream& stream, TamlCallbacks* pCallbacks, TamlCustomNodes& customNodes, const U32 versionId )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryReader_ParseCustomElement);
|
||||
|
||||
// Read custom node count.
|
||||
U32 customNodeCount;
|
||||
stream.read( &customNodeCount );
|
||||
|
||||
// Finish if no custom nodes.
|
||||
if ( customNodeCount == 0 )
|
||||
return;
|
||||
|
||||
// Iterate custom nodes.
|
||||
for ( U32 nodeIndex = 0; nodeIndex < customNodeCount; ++nodeIndex )
|
||||
{
|
||||
//Read custom node name.
|
||||
StringTableEntry nodeName = stream.readSTString();
|
||||
|
||||
// Add custom node.
|
||||
TamlCustomNode* pCustomNode = customNodes.addNode( nodeName );
|
||||
|
||||
// Parse the custom node.
|
||||
parseCustomNode( stream, pCustomNode, versionId );
|
||||
}
|
||||
|
||||
// Do we have callbacks?
|
||||
if ( pCallbacks == NULL )
|
||||
{
|
||||
// No, so warn.
|
||||
Con::warnf( "Taml: Encountered custom data but object does not support custom data." );
|
||||
return;
|
||||
}
|
||||
|
||||
// Custom read callback.
|
||||
mpTaml->tamlCustomRead( pCallbacks, customNodes );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlBinaryReader::parseCustomNode( Stream& stream, TamlCustomNode* pCustomNode, const U32 versionId )
|
||||
{
|
||||
// Fetch if a proxy object.
|
||||
bool isProxyObject;
|
||||
stream.read( &isProxyObject );
|
||||
|
||||
// Is this a proxy object?
|
||||
if ( isProxyObject )
|
||||
{
|
||||
// Yes, so parse proxy object.
|
||||
SimObject* pProxyObject = parseElement( stream, versionId );
|
||||
|
||||
// Add child node.
|
||||
pCustomNode->addNode( pProxyObject );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// No, so read custom node name.
|
||||
StringTableEntry nodeName = stream.readSTString();
|
||||
|
||||
// Add child node.
|
||||
TamlCustomNode* pChildNode = pCustomNode->addNode( nodeName );
|
||||
|
||||
// Read child node text.
|
||||
char childNodeTextBuffer[MAX_TAML_NODE_FIELDVALUE_LENGTH];
|
||||
stream.readLongString( MAX_TAML_NODE_FIELDVALUE_LENGTH, childNodeTextBuffer );
|
||||
pChildNode->setNodeText( childNodeTextBuffer );
|
||||
|
||||
// Read child node count.
|
||||
U32 childNodeCount;
|
||||
stream.read( &childNodeCount );
|
||||
|
||||
// Do we have any children nodes?
|
||||
if ( childNodeCount > 0 )
|
||||
{
|
||||
// Yes, so parse children nodes.
|
||||
for( U32 childIndex = 0; childIndex < childNodeCount; ++childIndex )
|
||||
{
|
||||
// Parse child node.
|
||||
parseCustomNode( stream, pChildNode, versionId );
|
||||
}
|
||||
}
|
||||
|
||||
// Read child field count.
|
||||
U32 childFieldCount;
|
||||
stream.read( &childFieldCount );
|
||||
|
||||
// Do we have any child fields?
|
||||
if ( childFieldCount > 0 )
|
||||
{
|
||||
// Yes, so parse child fields.
|
||||
for( U32 childFieldIndex = 0; childFieldIndex < childFieldCount; ++childFieldIndex )
|
||||
{
|
||||
// Read field name.
|
||||
StringTableEntry fieldName = stream.readSTString();
|
||||
|
||||
// Read field value.
|
||||
char valueBuffer[MAX_TAML_NODE_FIELDVALUE_LENGTH];
|
||||
stream.readLongString( MAX_TAML_NODE_FIELDVALUE_LENGTH, valueBuffer );
|
||||
|
||||
// Add field.
|
||||
pChildNode->addField( fieldName, valueBuffer );
|
||||
}
|
||||
}
|
||||
}
|
||||
68
Engine/source/persistence/taml/binary/tamlBinaryReader.h
Normal file
68
Engine/source/persistence/taml/binary/tamlBinaryReader.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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_BINARYREADER_H_
|
||||
#define _TAML_BINARYREADER_H_
|
||||
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
|
||||
#ifndef _TAML_H_
|
||||
#include "persistence/taml/taml.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @ingroup tamlGroup
|
||||
/// @see tamlGroup
|
||||
class TamlBinaryReader
|
||||
{
|
||||
public:
|
||||
TamlBinaryReader( Taml* pTaml ) :
|
||||
mpTaml( pTaml )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~TamlBinaryReader() {}
|
||||
|
||||
/// Read.
|
||||
SimObject* read( FileStream& stream );
|
||||
|
||||
private:
|
||||
Taml* mpTaml;
|
||||
|
||||
typedef HashTable<SimObjectId, SimObject*> typeObjectReferenceHash;
|
||||
|
||||
typeObjectReferenceHash mObjectReferenceMap;
|
||||
|
||||
private:
|
||||
void resetParse( void );
|
||||
|
||||
SimObject* parseElement( Stream& stream, const U32 versionId );
|
||||
void parseAttributes( Stream& stream, SimObject* pSimObject, const U32 versionId );
|
||||
void parseChildren( Stream& stream, TamlCallbacks* pCallbacks, SimObject* pSimObject, const U32 versionId );
|
||||
void parseCustomElements( Stream& stream, TamlCallbacks* pCallbacks, TamlCustomNodes& customNodes, const U32 versionId );
|
||||
void parseCustomNode( Stream& stream, TamlCustomNode* pCustomNode, const U32 versionId );
|
||||
};
|
||||
|
||||
#endif // _TAML_BINARYREADER_H_
|
||||
297
Engine/source/persistence/taml/binary/tamlBinaryWriter.cpp
Normal file
297
Engine/source/persistence/taml/binary/tamlBinaryWriter.cpp
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/binary/tamlBinaryWriter.h"
|
||||
|
||||
#ifndef _ZIPSUBSTREAM_H_
|
||||
#include "core/util/zip/zipSubStream.h"
|
||||
#endif
|
||||
|
||||
// Debug Profiling.
|
||||
#include "platform/profiler.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool TamlBinaryWriter::write( FileStream& stream, const TamlWriteNode* pTamlWriteNode, const bool compressed )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryWriter_Write);
|
||||
|
||||
// Write Taml signature.
|
||||
stream.writeString( StringTable->insert( TAML_SIGNATURE ) );
|
||||
|
||||
// Write version Id.
|
||||
stream.write( mVersionId );
|
||||
|
||||
// Write compressed flag.
|
||||
stream.write( compressed );
|
||||
|
||||
// Are we compressed?
|
||||
if ( compressed )
|
||||
{
|
||||
// yes, so attach zip stream.
|
||||
ZipSubWStream zipStream;
|
||||
zipStream.attachStream( &stream );
|
||||
|
||||
// Write element.
|
||||
writeElement( zipStream, pTamlWriteNode );
|
||||
|
||||
// Detach zip stream.
|
||||
zipStream.detachStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
// No, so write element.
|
||||
writeElement( stream, pTamlWriteNode );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlBinaryWriter::writeElement( Stream& stream, const TamlWriteNode* pTamlWriteNode )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryWriter_WriteElement);
|
||||
|
||||
// Fetch object.
|
||||
SimObject* pSimObject = pTamlWriteNode->mpSimObject;
|
||||
|
||||
// Fetch element name.
|
||||
const char* pElementName = pSimObject->getClassName();
|
||||
|
||||
// Write element name.
|
||||
stream.writeString( pElementName );
|
||||
|
||||
// Fetch object name.
|
||||
const char* pObjectName = pTamlWriteNode->mpObjectName;
|
||||
|
||||
// Write object name.
|
||||
stream.writeString( pObjectName != NULL ? pObjectName : StringTable->EmptyString() );
|
||||
|
||||
// Fetch reference Id.
|
||||
const U32 tamlRefId = pTamlWriteNode->mRefId;
|
||||
|
||||
// Write reference Id.
|
||||
stream.write( tamlRefId );
|
||||
|
||||
// Do we have a reference to node?
|
||||
if ( pTamlWriteNode->mRefToNode != NULL )
|
||||
{
|
||||
// Yes, so fetch reference to Id.
|
||||
const U32 tamlRefToId = pTamlWriteNode->mRefToNode->mRefId;
|
||||
|
||||
// Sanity!
|
||||
AssertFatal( tamlRefToId != 0, "Taml: Invalid reference to Id." );
|
||||
|
||||
// Write reference to Id.
|
||||
stream.write( tamlRefToId );
|
||||
|
||||
// Finished.
|
||||
return;
|
||||
}
|
||||
|
||||
// No, so write no reference to Id.
|
||||
stream.write( 0 );
|
||||
|
||||
// Write attributes.
|
||||
writeAttributes( stream, pTamlWriteNode );
|
||||
|
||||
// Write children.
|
||||
writeChildren( stream, pTamlWriteNode );
|
||||
|
||||
// Write custom elements.
|
||||
writeCustomElements( stream, pTamlWriteNode );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlBinaryWriter::writeAttributes( Stream& stream, const TamlWriteNode* pTamlWriteNode )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryWriter_WriteAttributes);
|
||||
|
||||
// Fetch fields.
|
||||
const Vector<TamlWriteNode::FieldValuePair*>& fields = pTamlWriteNode->mFields;
|
||||
|
||||
// Write placeholder attribute count.
|
||||
stream.write( (U32)fields.size() );
|
||||
|
||||
// Finish 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);
|
||||
|
||||
// Write attribute.
|
||||
stream.writeString( pFieldValue->mName );
|
||||
stream.writeLongString( 4096, pFieldValue->mpValue );
|
||||
}
|
||||
}
|
||||
|
||||
void TamlBinaryWriter::writeChildren( Stream& stream, const TamlWriteNode* pTamlWriteNode )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryWriter_WriteChildren);
|
||||
|
||||
// Fetch children.
|
||||
Vector<TamlWriteNode*>* pChildren = pTamlWriteNode->mChildren;
|
||||
|
||||
// Do we have any children?
|
||||
if ( pChildren == NULL )
|
||||
{
|
||||
// No, so write no children.
|
||||
stream.write( (U32)0 );
|
||||
return;
|
||||
}
|
||||
|
||||
// Write children count.
|
||||
stream.write( (U32)pChildren->size() );
|
||||
|
||||
// Iterate children.
|
||||
for( Vector<TamlWriteNode*>::iterator itr = pChildren->begin(); itr != pChildren->end(); ++itr )
|
||||
{
|
||||
// Write child.
|
||||
writeElement( stream, (*itr) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlBinaryWriter::writeCustomElements( Stream& stream, const TamlWriteNode* pTamlWriteNode )
|
||||
{
|
||||
// Debug Profiling.
|
||||
PROFILE_SCOPE(TamlBinaryWriter_WriteCustomElements);
|
||||
|
||||
// Fetch custom nodes.
|
||||
const TamlCustomNodes& customNodes = pTamlWriteNode->mCustomNodes;
|
||||
|
||||
// Fetch custom nodes.
|
||||
const TamlCustomNodeVector& nodes = customNodes.getNodes();
|
||||
|
||||
// Write custom node count.
|
||||
stream.write( (U32)nodes.size() );
|
||||
|
||||
// Finish if there are no nodes.
|
||||
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;
|
||||
|
||||
// Write custom node name.
|
||||
stream.writeString( pCustomNode->getNodeName() );
|
||||
|
||||
// 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;
|
||||
|
||||
// Write the custom node.
|
||||
writeCustomNode( stream, pChildNode );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void TamlBinaryWriter::writeCustomNode( Stream& stream, const TamlCustomNode* pCustomNode )
|
||||
{
|
||||
// Is the node a proxy object?
|
||||
if ( pCustomNode->isProxyObject() )
|
||||
{
|
||||
// Yes, so flag as proxy object.
|
||||
stream.write( true );
|
||||
|
||||
// Write the element.
|
||||
writeElement( stream, pCustomNode->getProxyWriteNode() );
|
||||
return;
|
||||
}
|
||||
|
||||
// No, so flag as custom node.
|
||||
stream.write( false );
|
||||
|
||||
// Write custom node name.
|
||||
stream.writeString( pCustomNode->getNodeName() );
|
||||
|
||||
// Write custom node text.
|
||||
stream.writeLongString(MAX_TAML_NODE_FIELDVALUE_LENGTH, pCustomNode->getNodeTextField().getFieldValue());
|
||||
|
||||
// Fetch node children.
|
||||
const TamlCustomNodeVector& nodeChildren = pCustomNode->getChildren();
|
||||
|
||||
// Fetch child node count.
|
||||
const U32 childNodeCount = (U32)nodeChildren.size();
|
||||
|
||||
// Write custom node count.
|
||||
stream.write( childNodeCount );
|
||||
|
||||
// Do we have any children nodes.
|
||||
if ( childNodeCount > 0 )
|
||||
{
|
||||
// Yes, so iterate children nodes.
|
||||
for( TamlCustomNodeVector::const_iterator childNodeItr = nodeChildren.begin(); childNodeItr != nodeChildren.end(); ++childNodeItr )
|
||||
{
|
||||
// Fetch child node.
|
||||
const TamlCustomNode* pChildNode = *childNodeItr;
|
||||
|
||||
// Write the custom node.
|
||||
writeCustomNode( stream, pChildNode );
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch fields.
|
||||
const TamlCustomFieldVector& fields = pCustomNode->getFields();
|
||||
|
||||
// Fetch child field count.
|
||||
const U32 childFieldCount = (U32)fields.size();
|
||||
|
||||
// Write custom field count.
|
||||
stream.write( childFieldCount );
|
||||
|
||||
// Do we have any child fields?
|
||||
if ( childFieldCount > 0 )
|
||||
{
|
||||
// Yes, so iterate fields.
|
||||
for ( TamlCustomFieldVector::const_iterator fieldItr = fields.begin(); fieldItr != fields.end(); ++fieldItr )
|
||||
{
|
||||
// Fetch node field.
|
||||
const TamlCustomField* pField = *fieldItr;
|
||||
|
||||
// Write the node field.
|
||||
stream.writeString( pField->getFieldName() );
|
||||
stream.writeLongString( MAX_TAML_NODE_FIELDVALUE_LENGTH, pField->getFieldValue() );
|
||||
}
|
||||
}
|
||||
}
|
||||
59
Engine/source/persistence/taml/binary/tamlBinaryWriter.h
Normal file
59
Engine/source/persistence/taml/binary/tamlBinaryWriter.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_BINARYWRITER_H_
|
||||
#define _TAML_BINARYWRITER_H_
|
||||
|
||||
#ifndef _TAML_H_
|
||||
#include "persistence/taml/taml.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// @ingroup tamlGroup
|
||||
/// @see tamlGroup
|
||||
class TamlBinaryWriter
|
||||
{
|
||||
public:
|
||||
TamlBinaryWriter( Taml* pTaml ) :
|
||||
mpTaml( pTaml ),
|
||||
mVersionId(2)
|
||||
{
|
||||
}
|
||||
virtual ~TamlBinaryWriter() {}
|
||||
|
||||
/// Write.
|
||||
bool write( FileStream& stream, const TamlWriteNode* pTamlWriteNode, const bool compressed );
|
||||
|
||||
private:
|
||||
Taml* mpTaml;
|
||||
const U32 mVersionId;
|
||||
|
||||
private:
|
||||
void writeElement( Stream& stream, const TamlWriteNode* pTamlWriteNode );
|
||||
void writeAttributes( Stream& stream, const TamlWriteNode* pTamlWriteNode );
|
||||
void writeChildren( Stream& stream, const TamlWriteNode* pTamlWriteNode );
|
||||
void writeCustomElements( Stream& stream, const TamlWriteNode* pTamlWriteNode );
|
||||
void writeCustomNode( Stream& stream, const TamlCustomNode* pCustomNode );
|
||||
};
|
||||
|
||||
#endif // _TAML_BINARYWRITER_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue