diff --git a/Engine/source/console/simFieldDictionary.cpp b/Engine/source/console/simFieldDictionary.cpp index 2deb56bf9..f68a8689b 100644 --- a/Engine/source/console/simFieldDictionary.cpp +++ b/Engine/source/console/simFieldDictionary.cpp @@ -32,6 +32,10 @@ #include "console/consoleInternal.h" #include "core/frameAllocator.h" +SimFieldDictionary::Entry *SimFieldDictionary::smFreeList = NULL; + +static Chunker fieldChunker; + U32 SimFieldDictionary::getHashValue(StringTableEntry slotName) { return HashPointer(slotName) % HashTableSize; @@ -44,43 +48,58 @@ U32 SimFieldDictionary::getHashValue(const String& fieldName) SimFieldDictionary::Entry *SimFieldDictionary::addEntry(U32 bucket, StringTableEntry slotName, ConsoleBaseType* type, char* value) { - Entry ret; - ret.slotName = slotName; - ret.type = type; - ret.value = value; + Entry* ret; + if (smFreeList) + { + ret = smFreeList; + smFreeList = ret->next; + } + else + ret = fieldChunker.alloc(); + ret->next = mHashTable[bucket]; + ret->slotName = slotName; + ret->type = type; + ret->value = value; + + mHashTable[bucket] = ret; mNumFields++; mVersion++; - mHashTable[bucket].push_back(std::move(ret)); - return &mHashTable[bucket].back(); + return ret; } void SimFieldDictionary::freeEntry(SimFieldDictionary::Entry *ent) { - auto &vec = mHashTable[getHashValue(ent->slotName)]; + ent->next = smFreeList; + smFreeList = ent; - // Find the slot. - auto iter = std::find_if(vec.begin(), vec.end(), [&](const Entry &ref) -> bool { - return ref.slotName == ent->slotName; - }); - if (iter != vec.end()) - { - vec.erase(iter); - mNumFields--; - } + mNumFields--; } SimFieldDictionary::SimFieldDictionary() : mNumFields(0), mVersion(0) { - + dMemset(mHashTable, 0, sizeof(mHashTable)); } SimFieldDictionary::~SimFieldDictionary() { + for (U32 i = 0; i < HashTableSize; i++) + { + for (Entry *walk = mHashTable[i]; walk;) + { + Entry *temp = walk; + walk = temp->next; + if (temp->value) + dFree(temp->value); + freeEntry(temp); + } + } + + AssertFatal(mNumFields == 0, "Incorrect count on field dictionary"); } void SimFieldDictionary::setFieldType(StringTableEntry slotName, const char *typeString) @@ -100,12 +119,12 @@ void SimFieldDictionary::setFieldType(StringTableEntry slotName, ConsoleBaseType // If the field exists on the object, set the type U32 bucket = getHashValue(slotName); - for (Entry &ref : mHashTable[bucket]) + for (Entry *walk = mHashTable[bucket]; walk; walk = walk->next) { - if (ref.slotName == slotName) + if (walk->slotName == slotName) { // Found and type assigned, let's bail - ref.type = type; + walk->type = type; return; } } @@ -118,14 +137,9 @@ U32 SimFieldDictionary::getFieldType(StringTableEntry slotName) const { U32 bucket = getHashValue(slotName); - const std::vector &vec = mHashTable[bucket]; - size_t size = vec.size(); - for (size_t i = 0; i < size; ++i) - { - const Entry &ref = vec[i]; - if (ref.slotName == slotName) - return ref.type ? ref.type->getTypeID() : TypeString; - } + for (Entry *walk = mHashTable[bucket]; walk; walk = walk->next) + if (walk->slotName == slotName) + return walk->type ? walk->type->getTypeID() : TypeString; return TypeString; } @@ -134,13 +148,10 @@ SimFieldDictionary::Entry *SimFieldDictionary::findDynamicField(const String &f { U32 bucket = getHashValue(fieldName); - const std::vector &vec = mHashTable[bucket]; - size_t size = vec.size(); - for (size_t i = 0; i < size; ++i) + for (Entry *walk = mHashTable[bucket]; walk; walk = walk->next) { - const Entry &ref = vec[i]; - if (fieldName.equal(ref.slotName, String::NoCase)) - return const_cast(&ref); + if (fieldName.equal(walk->slotName, String::NoCase)) + return walk; } return NULL; @@ -150,13 +161,11 @@ SimFieldDictionary::Entry *SimFieldDictionary::findDynamicField(StringTableEntry { U32 bucket = getHashValue(fieldName); - const std::vector &vec = mHashTable[bucket]; - size_t size = vec.size(); - for (size_t i = 0; i < size; ++i) + for (Entry *walk = mHashTable[bucket]; walk; walk = walk->next) { - if (vec[i].slotName == fieldName) + if (walk->slotName == fieldName) { - return const_cast(&vec[i]); + return walk; } } @@ -167,43 +176,45 @@ SimFieldDictionary::Entry *SimFieldDictionary::findDynamicField(StringTableEntry void SimFieldDictionary::setFieldValue(StringTableEntry slotName, const char *value) { U32 bucket = getHashValue(slotName); + Entry **walk = &mHashTable[bucket]; + while (*walk && (*walk)->slotName != slotName) + walk = &((*walk)->next); - for (Entry &ref : mHashTable[bucket]) + Entry *field = *walk; + if (!value || !*value) { - if (ref.slotName == slotName) + if (field) { - if (!value || !*value) - { - mVersion++; + mVersion++; - if (ref.value) - dFree(ref.value); + if (field->value) + dFree(field->value); - freeEntry(&ref); - } - else - { - if (ref.value) - dFree(ref.value); - - ref.value = dStrdup(value); - } - - return; + *walk = field->next; + freeEntry(field); } } + else + { + if (field) + { + if (field->value) + dFree(field->value); - // no field, add entry. - addEntry(bucket, slotName, 0, dStrdup(value)); + field->value = dStrdup(value); + } + else + addEntry(bucket, slotName, 0, dStrdup(value)); + } } const char *SimFieldDictionary::getFieldValue(StringTableEntry slotName) { U32 bucket = getHashValue(slotName); - for (const Entry &ref : mHashTable[bucket]) - if (ref.slotName == slotName) - return ref.value; + for (Entry *walk = mHashTable[bucket]; walk; walk = walk->next) + if (walk->slotName == slotName) + return walk->value; return NULL; } @@ -214,41 +225,41 @@ void SimFieldDictionary::assignFrom(SimFieldDictionary *dict) for (U32 i = 0; i < HashTableSize; i++) { - for (const Entry &ref : mHashTable[i]) + for (Entry *walk = dict->mHashTable[i]; walk; walk = walk->next) { - setFieldValue(ref.slotName, ref.value); - setFieldType(ref.slotName, ref.type); + setFieldValue(walk->slotName, walk->value); + setFieldType(walk->slotName, walk->type); } } } static S32 QSORT_CALLBACK compareEntries(const void* a, const void* b) { - const SimFieldDictionary::Entry *fa = reinterpret_cast(a); - const SimFieldDictionary::Entry *fb = reinterpret_cast(b); + SimFieldDictionary::Entry *fa = *((SimFieldDictionary::Entry **)a); + SimFieldDictionary::Entry *fb = *((SimFieldDictionary::Entry **)b); return dStricmp(fa->slotName, fb->slotName); } void SimFieldDictionary::writeFields(SimObject *obj, Stream &stream, U32 tabStop) { const AbstractClassRep::FieldList &list = obj->getFieldList(); - Vector flist(__FILE__, __LINE__); + Vector flist(__FILE__, __LINE__); for (U32 i = 0; i < HashTableSize; i++) { - for (const Entry &walk : mHashTable[i]) + for (Entry *walk = mHashTable[i]; walk; walk = walk->next) { // make sure we haven't written this out yet: - U32 j; - for (j = 0; j < list.size(); j++) - if (list[j].pFieldname == walk.slotName) + U32 i; + for (i = 0; i < list.size(); i++) + if (list[i].pFieldname == walk->slotName) break; - if (j != list.size()) + if (i != list.size()) continue; - if (!obj->writeField(walk.slotName, walk.value)) + if (!obj->writeField(walk->slotName, walk->value)) continue; flist.push_back(walk); @@ -256,20 +267,20 @@ void SimFieldDictionary::writeFields(SimObject *obj, Stream &stream, U32 tabStop } // Sort Entries to prevent version control conflicts - dQsort(flist.address(), flist.size(), sizeof(Entry), compareEntries); + dQsort(flist.address(), flist.size(), sizeof(Entry *), compareEntries); // Save them out - for (const Entry &ref : flist) + for (Vector::iterator itr = flist.begin(); itr != flist.end(); itr++) { - U32 nBufferSize = (dStrlen(ref.value) * 2) + dStrlen(ref.slotName) + 16; + U32 nBufferSize = (dStrlen((*itr)->value) * 2) + dStrlen((*itr)->slotName) + 16; FrameTemp expandedBuffer(nBufferSize); stream.writeTabs(tabStop + 1); - const char *typeName = ref.type && ref.type->getTypeID() != TypeString ? ref.type->getTypeName() : ""; - dSprintf(expandedBuffer, nBufferSize, "%s%s%s = \"", typeName, *typeName ? " " : "", ref.slotName); - if (ref.value) - expandEscape((char*)expandedBuffer + dStrlen(expandedBuffer), ref.value); + const char *typeName = (*itr)->type && (*itr)->type->getTypeID() != TypeString ? (*itr)->type->getTypeName() : ""; + dSprintf(expandedBuffer, nBufferSize, "%s%s%s = \"", typeName, *typeName ? " " : "", (*itr)->slotName); + if ((*itr)->value) + expandEscape((char*)expandedBuffer + dStrlen(expandedBuffer), (*itr)->value); dStrcat(expandedBuffer, "\";\r\n"); stream.write(dStrlen(expandedBuffer), expandedBuffer); @@ -280,35 +291,35 @@ void SimFieldDictionary::printFields(SimObject *obj) { const AbstractClassRep::FieldList &list = obj->getFieldList(); char expandedBuffer[4096]; - Vector flist(__FILE__, __LINE__); + Vector flist(__FILE__, __LINE__); for (U32 i = 0; i < HashTableSize; i++) { - for (const Entry &walk : mHashTable[i]) + for (Entry *walk = mHashTable[i]; walk; walk = walk->next) { // make sure we haven't written this out yet: - U32 j; - for (j = 0; j < list.size(); j++) - if (list[i].pFieldname == walk.slotName) + U32 i; + for (i = 0; i < list.size(); i++) + if (list[i].pFieldname == walk->slotName) break; - if (j != list.size()) + if (i != list.size()) continue; flist.push_back(walk); } } - dQsort(flist.address(), flist.size(), sizeof(Entry), compareEntries); + dQsort(flist.address(), flist.size(), sizeof(Entry *), compareEntries); - for (const Entry &ref : flist) + for (Vector::iterator itr = flist.begin(); itr != flist.end(); itr++) { const char* type = "string"; - if (ref.type) - type = ref.type->getTypeClassName(); + if ((*itr)->type) + type = (*itr)->type->getTypeClassName(); - dSprintf(expandedBuffer, sizeof(expandedBuffer), " %s %s = \"", type, ref.slotName); - if (ref.value) - expandEscape(expandedBuffer + dStrlen(expandedBuffer), ref.value); + dSprintf(expandedBuffer, sizeof(expandedBuffer), " %s %s = \"", type, (*itr)->slotName); + if ((*itr)->value) + expandEscape(expandedBuffer + dStrlen(expandedBuffer), (*itr)->value); Con::printf("%s\"", expandedBuffer); } } @@ -332,44 +343,29 @@ SimFieldDictionary::Entry *SimFieldDictionary::operator[](U32 index) SimFieldDictionaryIterator::SimFieldDictionaryIterator(SimFieldDictionary * dictionary) { mDictionary = dictionary; - mHashIndex = 0; - mVecIndex = -1; // -1 since we immediately call operator++ - mEntry = NULL; + mHashIndex = -1; + mEntry = 0; operator++(); } SimFieldDictionary::Entry* SimFieldDictionaryIterator::operator++() { - if (!mDictionary || mHashIndex >= SimFieldDictionary::HashTableSize) - { - mEntry = NULL; - return NULL; - } + if (!mDictionary) + return(mEntry); - std::vector &vec = mDictionary->mHashTable[mHashIndex]; + if (mEntry) + mEntry = mEntry->next; - while (vec.size() == 0 && mHashIndex < (SimFieldDictionary::HashTableSize - 1)) - { - vec = mDictionary->mHashTable[++mHashIndex]; - mVecIndex = 0; - } + while (!mEntry && (mHashIndex < (SimFieldDictionary::HashTableSize - 1))) + mEntry = mDictionary->mHashTable[++mHashIndex]; - if (mVecIndex >= vec.size() || mHashIndex >= SimFieldDictionary::HashTableSize) - { - mEntry = NULL; - return NULL; - } - - mEntry = &vec[mVecIndex]; - ++mVecIndex; - return mEntry; + return(mEntry); } SimFieldDictionary::Entry* SimFieldDictionaryIterator::operator*() { - return mEntry; + return(mEntry); } - // A variation of the stock SimFieldDictionary::setFieldValue(), this method adds the // argument which, when true, prohibits the replacement of fields that // already have a value. @@ -389,13 +385,13 @@ void SimFieldDictionary::setFieldValue(StringTableEntry slotName, const char *va return; U32 bucket = getHashValue(slotName); - for (const Entry &walk : mHashTable[bucket]) - { - if (walk.slotName == slotName) - { - return; - } - } + Entry **walk = &mHashTable[bucket]; + while (*walk && (*walk)->slotName != slotName) + walk = &((*walk)->next); + + Entry *field = *walk; + if (field) + return; addEntry(bucket, slotName, type, dStrdup(value)); } @@ -417,22 +413,14 @@ void SimFieldDictionary::assignFrom(SimFieldDictionary *dict, const char* filter if (filter_len == 0) { for (U32 i = 0; i < HashTableSize; i++) - { - for (const Entry &walk : dict->mHashTable[i]) - { - setFieldValue(walk.slotName, walk.value, walk.type, no_replace); - } - } + for (Entry *walk = dict->mHashTable[i]; walk; walk = walk->next) + setFieldValue(walk->slotName, walk->value, walk->type, no_replace); } else { for (U32 i = 0; i < HashTableSize; i++) - { - for (const Entry &walk : dict->mHashTable[i]) - { - if (dStrncmp(walk.slotName, filter, filter_len) == 0) - setFieldValue(walk.slotName, walk.value, walk.type, no_replace); - } - } + for (Entry *walk = dict->mHashTable[i]; walk; walk = walk->next) + if (dStrncmp(walk->slotName, filter, filter_len) == 0) + setFieldValue(walk->slotName, walk->value, walk->type, no_replace); } } \ No newline at end of file diff --git a/Engine/source/console/simFieldDictionary.h b/Engine/source/console/simFieldDictionary.h index 4c9d86e4e..c89bd5b57 100644 --- a/Engine/source/console/simFieldDictionary.h +++ b/Engine/source/console/simFieldDictionary.h @@ -32,9 +32,6 @@ class ConsoleBaseType; class SimObject; -#include -#include - #include "core/stringTable.h" #include "core/stream/stream.h" @@ -54,17 +51,18 @@ public: StringTableEntry slotName; char *value; + Entry *next; ConsoleBaseType *type; }; enum { HashTableSize = 19 }; - //Entry *mHashTable[HashTableSize]; - - std::vector mHashTable[HashTableSize]; + Entry *mHashTable[HashTableSize]; private: + static Entry *smFreeList; + void freeEntry(Entry *entry); Entry* addEntry(U32 bucket, StringTableEntry slotName, ConsoleBaseType* type, char* value = 0); @@ -105,7 +103,6 @@ class SimFieldDictionaryIterator { SimFieldDictionary * mDictionary; S32 mHashIndex; - S32 mVecIndex; SimFieldDictionary::Entry * mEntry; public: @@ -115,4 +112,4 @@ public: }; -#endif // _SIMFIELDDICTIONARY_H_ +#endif // _SIMFIELDDICTIONARY_H_ \ No newline at end of file diff --git a/Engine/source/persistence/taml/taml.cpp b/Engine/source/persistence/taml/taml.cpp index 762edcb94..f364ed0ce 100644 --- a/Engine/source/persistence/taml/taml.cpp +++ b/Engine/source/persistence/taml/taml.cpp @@ -82,635 +82,637 @@ //----------------------------------------------------------------------------- -IMPLEMENT_CONOBJECT( Taml ); +IMPLEMENT_CONOBJECT(Taml); //----------------------------------------------------------------------------- -StringTableEntry tamlRefIdName = StringTable->insert( "TamlId" ); -StringTableEntry tamlRefToIdName = StringTable->insert( "TamlRefId" ); -StringTableEntry tamlNamedObjectName = StringTable->insert( "Name" ); +StringTableEntry tamlRefIdName = StringTable->insert("TamlId"); +StringTableEntry tamlRefToIdName = StringTable->insert("TamlRefId"); +StringTableEntry tamlNamedObjectName = StringTable->insert("Name"); //----------------------------------------------------------------------------- typedef Taml::TamlFormatMode _TamlFormatMode; -ImplementEnumType( _TamlFormatMode, +ImplementEnumType(_TamlFormatMode, "") - { Taml::XmlFormat, "xml" }, - { Taml::BinaryFormat, "binary" }//, - //{ Taml::JSONFormat, "json" } -EndImplementEnumType; - -//----------------------------------------------------------------------------- - -Taml::TamlFormatMode Taml::getFormatModeEnum(const char* label) { - // Search for Mnemonic. - for (U32 i = 0; i < (sizeof(__TamlFormatMode::_sEnums) / sizeof(EnumTable::Value)); i++) - { - if( dStricmp(__TamlFormatMode::_sEnumTable[i].getName(), label) == 0) - return (TamlFormatMode)__TamlFormatMode::_sEnumTable[i].getInt(); - } + Taml::XmlFormat, "xml" +}, +{ Taml::BinaryFormat, "binary" }//, + //{ Taml::JSONFormat, "json" } + EndImplementEnumType; - // Warn. - Con::warnf( "Taml::getFormatModeEnum() - Invalid format of '%s'.", label ); + //----------------------------------------------------------------------------- - return Taml::InvalidFormat; -} + Taml::TamlFormatMode Taml::getFormatModeEnum(const char* label) + { + // Search for Mnemonic. + for (U32 i = 0; i < (sizeof(__TamlFormatMode::_sEnums) / sizeof(EnumTable::Value)); i++) + { + if (dStricmp(__TamlFormatMode::_sEnumTable[i].getName(), label) == 0) + return (TamlFormatMode)__TamlFormatMode::_sEnumTable[i].getInt(); + } -//----------------------------------------------------------------------------- + // Warn. + Con::warnf("Taml::getFormatModeEnum() - Invalid format of '%s'.", label); -const char* Taml::getFormatModeDescription(const Taml::TamlFormatMode formatMode) -{ - // Search for Mnemonic. - for (U32 i = 0; i < (sizeof(__TamlFormatMode::_sEnums) / sizeof(EnumTable::Value)); i++) - { - if( __TamlFormatMode::_sEnumTable[i].getInt() == (S32)formatMode ) - return __TamlFormatMode::_sEnumTable[i].getName(); - } + return Taml::InvalidFormat; + } - // Warn. - Con::warnf( "Taml::getFormatModeDescription() - Invalid format mode." ); + //----------------------------------------------------------------------------- - return StringTable->EmptyString(); -} + const char* Taml::getFormatModeDescription(const Taml::TamlFormatMode formatMode) + { + // Search for Mnemonic. + for (U32 i = 0; i < (sizeof(__TamlFormatMode::_sEnums) / sizeof(EnumTable::Value)); i++) + { + if (__TamlFormatMode::_sEnumTable[i].getInt() == (S32)formatMode) + return __TamlFormatMode::_sEnumTable[i].getName(); + } -//----------------------------------------------------------------------------- + // Warn. + Con::warnf("Taml::getFormatModeDescription() - Invalid format mode."); -// The string-table-entries are set to string literals below because Taml is used in a static scope and the string-table cannot currently be used like that. -Taml::Taml() : - mFormatMode(XmlFormat), - mJSONStrict( true ), - mBinaryCompression(true), - mWriteDefaults(false), - mAutoFormatXmlExtension("taml"), - mAutoFormat(true), - mProgenitorUpdate(true), - mAutoFormatBinaryExtension("baml"), - mAutoFormatJSONExtension("json") -{ - // Reset the file-path buffer. - mFilePathBuffer[0] = 0; -} + return StringTable->EmptyString(); + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -void Taml::initPersistFields() -{ - // Call parent. - Parent::initPersistFields(); + // The string-table-entries are set to string literals below because Taml is used in a static scope and the string-table cannot currently be used like that. + Taml::Taml() : + mFormatMode(XmlFormat), + mJSONStrict(true), + mBinaryCompression(true), + mWriteDefaults(false), + mAutoFormatXmlExtension("taml"), + mAutoFormat(true), + mProgenitorUpdate(true), + mAutoFormatBinaryExtension("baml"), + mAutoFormatJSONExtension("json") + { + // Reset the file-path buffer. + mFilePathBuffer[0] = 0; + } - addField("Format", TYPEID<_TamlFormatMode>(), Offset(mFormatMode, Taml), "The read/write format that should be used."); - addField("JSONStrict", TypeBool, Offset(mBinaryCompression, Taml), "Whether to write JSON that is strictly compatible with RFC4627 or not.\n"); - addField("BinaryCompression", TypeBool, Offset(mBinaryCompression, Taml), "Whether ZIP compression is used on binary formatting or not.\n"); - addField("WriteDefaults", TypeBool, Offset(mWriteDefaults, Taml), "Whether to write static fields that are at their default or not.\n"); - addField("ProgenitorUpdate", TypeBool, Offset(mProgenitorUpdate, Taml), "Whether to update each type instances file-progenitor or not.\n"); - addField("AutoFormat", TypeBool, Offset(mAutoFormat, Taml), "Whether the format type is automatically determined by the filename extension or not.\n"); - addField("AutoFormatXmlExtension", TypeString, Offset(mAutoFormatXmlExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the XML format.\n"); - addField("AutoFormatBinaryExtension", TypeString, Offset(mAutoFormatBinaryExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the BINARY format.\n"); - addField("AutoFormatJSONExtension", TypeString, Offset(mAutoFormatJSONExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the JSON format.\n"); -} + //----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- + void Taml::initPersistFields() + { + // Call parent. + Parent::initPersistFields(); -bool Taml::onAdd() -{ - // Call parent. - if ( !Parent::onAdd() ) - return false; + addField("Format", TYPEID<_TamlFormatMode>(), Offset(mFormatMode, Taml), "The read/write format that should be used."); + addField("JSONStrict", TypeBool, Offset(mBinaryCompression, Taml), "Whether to write JSON that is strictly compatible with RFC4627 or not.\n"); + addField("BinaryCompression", TypeBool, Offset(mBinaryCompression, Taml), "Whether ZIP compression is used on binary formatting or not.\n"); + addField("WriteDefaults", TypeBool, Offset(mWriteDefaults, Taml), "Whether to write static fields that are at their default or not.\n"); + addField("ProgenitorUpdate", TypeBool, Offset(mProgenitorUpdate, Taml), "Whether to update each type instances file-progenitor or not.\n"); + addField("AutoFormat", TypeBool, Offset(mAutoFormat, Taml), "Whether the format type is automatically determined by the filename extension or not.\n"); + addField("AutoFormatXmlExtension", TypeString, Offset(mAutoFormatXmlExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the XML format.\n"); + addField("AutoFormatBinaryExtension", TypeString, Offset(mAutoFormatBinaryExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the BINARY format.\n"); + addField("AutoFormatJSONExtension", TypeString, Offset(mAutoFormatJSONExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the JSON format.\n"); + } - // Set JSON strict mode. - mJSONStrict = Con::getBoolVariable( TAML_JSON_STRICT_VARIBLE, true ); + //----------------------------------------------------------------------------- - // Reset the compilation. - resetCompilation(); + bool Taml::onAdd() + { + // Call parent. + if (!Parent::onAdd()) + return false; - return true; -} + // Set JSON strict mode. + mJSONStrict = Con::getBoolVariable(TAML_JSON_STRICT_VARIBLE, true); -//----------------------------------------------------------------------------- + // Reset the compilation. + resetCompilation(); -void Taml::onRemove() -{ - // Reset the compilation. - resetCompilation(); + return true; + } - // Call parent. - Parent::onRemove(); -} + //----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- + void Taml::onRemove() + { + // Reset the compilation. + resetCompilation(); -bool Taml::write( SimObject* pSimObject, const char* pFilename ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_Write); + // Call parent. + Parent::onRemove(); + } - // Sanity! - AssertFatal( pSimObject != NULL, "Cannot write a NULL object." ); - AssertFatal( pFilename != NULL, "Cannot write to a NULL filename." ); + //----------------------------------------------------------------------------- - // Expand the file-name into the file-path buffer. - Con::expandToolScriptFilename( mFilePathBuffer, sizeof(mFilePathBuffer), pFilename ); + bool Taml::write(SimObject* pSimObject, const char* pFilename) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_Write); - FileStream stream; + // Sanity! + AssertFatal(pSimObject != NULL, "Cannot write a NULL object."); + AssertFatal(pFilename != NULL, "Cannot write to a NULL filename."); - // File opened? - if ( !stream.open( mFilePathBuffer, Torque::FS::File::Write ) ) - { - // No, so warn. - Con::warnf("Taml::writeFile() - Could not open filename '%s' for write.", mFilePathBuffer ); - return false; - } + // Expand the file-name into the file-path buffer. + Con::expandToolScriptFilename(mFilePathBuffer, sizeof(mFilePathBuffer), pFilename); - // Get the file auto-format mode. - const TamlFormatMode formatMode = getFileAutoFormatMode( mFilePathBuffer ); + FileStream stream; - // Reset the compilation. - resetCompilation(); + // File opened? + if (!stream.open(mFilePathBuffer, Torque::FS::File::Write)) + { + // No, so warn. + Con::warnf("Taml::writeFile() - Could not open filename '%s' for write.", mFilePathBuffer); + return false; + } - // Write object. - const bool status = write( stream, pSimObject, formatMode ); + // Get the file auto-format mode. + const TamlFormatMode formatMode = getFileAutoFormatMode(mFilePathBuffer); - // Close file. - stream.close(); + // Reset the compilation. + resetCompilation(); - // Reset the compilation. - resetCompilation(); + // Write object. + const bool status = write(stream, pSimObject, formatMode); - return status; -} + // Close file. + stream.close(); -//----------------------------------------------------------------------------- + // Reset the compilation. + resetCompilation(); -SimObject* Taml::read( const char* pFilename ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_Read); + return status; + } - // Sanity! - AssertFatal( pFilename != NULL, "Cannot read from a NULL filename." ); + //----------------------------------------------------------------------------- - // Expand the file-name into the file-path buffer. - Con::expandToolScriptFilename( mFilePathBuffer, sizeof(mFilePathBuffer), pFilename ); + SimObject* Taml::read(const char* pFilename) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_Read); - FileStream stream; + // Sanity! + AssertFatal(pFilename != NULL, "Cannot read from a NULL filename."); - // File opened? - if ( !stream.open( mFilePathBuffer, Torque::FS::File::Read ) ) - { - // No, so warn. - Con::warnf("Taml::read() - Could not open filename '%s' for read.", mFilePathBuffer ); - return NULL; - } + // Expand the file-name into the file-path buffer. + Con::expandToolScriptFilename(mFilePathBuffer, sizeof(mFilePathBuffer), pFilename); - // Get the file auto-format mode. - const TamlFormatMode formatMode = getFileAutoFormatMode( mFilePathBuffer ); + FileStream stream; - // Reset the compilation. - resetCompilation(); + // File opened? + if (!stream.open(mFilePathBuffer, Torque::FS::File::Read)) + { + // No, so warn. + Con::warnf("Taml::read() - Could not open filename '%s' for read.", mFilePathBuffer); + return NULL; + } - // Write object. - SimObject* pSimObject = read( stream, formatMode ); + // Get the file auto-format mode. + const TamlFormatMode formatMode = getFileAutoFormatMode(mFilePathBuffer); - // Close file. - stream.close(); + // Reset the compilation. + resetCompilation(); - // Reset the compilation. - resetCompilation(); + // Write object. + SimObject* pSimObject = read(stream, formatMode); - // Did we generate an object? - if ( pSimObject == NULL ) - { - // No, so warn. - Con::warnf( "Taml::read() - Failed to load an object from the file '%s'.", mFilePathBuffer ); - } - else - { - pSimObject->onPostAdd(); - } + // Close file. + stream.close(); - return pSimObject; -} + // Reset the compilation. + resetCompilation(); -//----------------------------------------------------------------------------- + // Did we generate an object? + if (pSimObject == NULL) + { + // No, so warn. + Con::warnf("Taml::read() - Failed to load an object from the file '%s'.", mFilePathBuffer); + } + else + { + pSimObject->onPostAdd(); + } -bool Taml::write( FileStream& stream, SimObject* pSimObject, const TamlFormatMode formatMode ) -{ - // Sanity! - AssertFatal( pSimObject != NULL, "Cannot write a NULL object." ); + return pSimObject; + } - // Compile nodes. - TamlWriteNode* pRootNode = compileObject( pSimObject ); + //----------------------------------------------------------------------------- - // Format appropriately. - switch( formatMode ) - { - /// Xml. - case XmlFormat: - { - // Create writer. - TamlXmlWriter writer( this ); - // Write. - return writer.write( stream, pRootNode ); - } + bool Taml::write(FileStream& stream, SimObject* pSimObject, const TamlFormatMode formatMode) + { + // Sanity! + AssertFatal(pSimObject != NULL, "Cannot write a NULL object."); - /// Binary. - case BinaryFormat: - { - // Create writer. - TamlBinaryWriter writer( this ); + // Compile nodes. + TamlWriteNode* pRootNode = compileObject(pSimObject); - // Write. - return writer.write( stream, pRootNode, mBinaryCompression ); - } + // Format appropriately. + switch (formatMode) + { + /// Xml. + case XmlFormat: + { + // Create writer. + TamlXmlWriter writer(this); + // Write. + return writer.write(stream, pRootNode); + } - /// JSON. - case JSONFormat: - { - // Create writer. - //TamlJSONWriter writer( this ); + /// Binary. + case BinaryFormat: + { + // Create writer. + TamlBinaryWriter writer(this); - // Write. - //return writer.write( stream, pRootNode ); - return NULL; - } + // Write. + return writer.write(stream, pRootNode, mBinaryCompression); + } - /// Invalid. - case InvalidFormat: - { - // Warn. - Con::warnf("Taml::write() - Cannot write, invalid format."); + /// JSON. + case JSONFormat: + { + // Create writer. + //TamlJSONWriter writer( this ); + + // Write. + //return writer.write( stream, pRootNode ); + return NULL; + } + + /// Invalid. + case InvalidFormat: + { + // Warn. + Con::warnf("Taml::write() - Cannot write, invalid format."); + return false; + } + } + + // Warn. + Con::warnf("Taml::write() - Unknown format."); + return false; + } + + //----------------------------------------------------------------------------- + + SimObject* Taml::read(FileStream& stream, const TamlFormatMode formatMode) + { + // Format appropriately. + switch (formatMode) + { + /// Xml. + case XmlFormat: + { + // Create reader. + TamlXmlReader reader(this); + + // Read. + return reader.read(stream); + } + + /// Binary. + case BinaryFormat: + { + // Create reader. + TamlBinaryReader reader(this); + + // Read. + return reader.read(stream); + } + + /// JSON. + case JSONFormat: + { + // Create reader. + //TamlJSONReader reader( this ); + + // Read. + //return reader.read( stream ); + return NULL; + } + + /// Invalid. + case InvalidFormat: + { + // Warn. + Con::warnf("Taml::read() - Cannot read, invalid format."); + return NULL; + } + } + + // Warn. + Con::warnf("Taml::read() - Unknown format."); + return NULL; + } + + //----------------------------------------------------------------------------- + + bool Taml::parse(const char* pFilename, TamlVisitor& visitor) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_Parse); + + // Sanity! + AssertFatal(pFilename != NULL, "Taml::parse() - Cannot parse a NULL filename."); + + // Fetch format mode. + const TamlFormatMode formatMode = getFileAutoFormatMode(pFilename); + + // Handle format mode appropriately. + switch (formatMode) + { + case XmlFormat: + { + // Parse with the visitor. + TamlXmlParser parser; + + // Are property changes needed but not supported? + if (visitor.wantsPropertyChanges() && !parser.canChangeProperty()) + { + // Yes, so warn. + Con::warnf("Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a specified visitor requires property changes which are not supported by the parser.", getFormatModeDescription(formatMode), pFilename); return false; - } - } + } - // Warn. - Con::warnf("Taml::write() - Unknown format."); - return false; -} + return parser.accept(pFilename, visitor); + } -//----------------------------------------------------------------------------- + case JSONFormat: + { + // Parse with the visitor. + /*TamlJSONParser parser; -SimObject* Taml::read( FileStream& stream, const TamlFormatMode formatMode ) -{ - // Format appropriately. - switch( formatMode ) - { - /// Xml. - case XmlFormat: - { - // Create reader. - TamlXmlReader reader( this ); + // Are property changes needed but not supported? + if ( visitor.wantsPropertyChanges() && !parser.canChangeProperty() ) + { + // Yes, so warn. + Con::warnf( "Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a specified visitor requires property changes which are not supported by the parser.", getFormatModeDescription(formatMode), pFilename ); + return false; + } - // Read. - return reader.read( stream ); - } + return parser.accept( pFilename, visitor ); */ + return false; + } - /// Binary. - case BinaryFormat: - { - // Create reader. - TamlBinaryReader reader( this ); + case BinaryFormat: + default: + break; + } - // Read. - return reader.read( stream ); - } + // Warn. + Con::warnf("Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a required parser is not available.", getFormatModeDescription(formatMode), pFilename); + return false; + } - /// JSON. - case JSONFormat: - { - // Create reader. - //TamlJSONReader reader( this ); + //----------------------------------------------------------------------------- - // Read. - //return reader.read( stream ); - return NULL; - } - - /// Invalid. - case InvalidFormat: - { - // Warn. - Con::warnf("Taml::read() - Cannot read, invalid format."); - return NULL; - } - } + void Taml::resetCompilation(void) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_ResetCompilation); - // Warn. - Con::warnf("Taml::read() - Unknown format."); - return NULL; -} + // Clear compiled nodes. + for (typeNodeVector::iterator itr = mCompiledNodes.begin(); itr != mCompiledNodes.end(); ++itr) + { + // Fetch node. + TamlWriteNode* pNode = (*itr); -//----------------------------------------------------------------------------- + // Reset node. + pNode->resetNode(); -bool Taml::parse( const char* pFilename, TamlVisitor& visitor ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_Parse); + // Delete node. + delete pNode; + } + mCompiledNodes.clear(); - // Sanity! - AssertFatal( pFilename != NULL, "Taml::parse() - Cannot parse a NULL filename." ); + // Clear compiled objects. + mCompiledObjects.clear(); - // Fetch format mode. - const TamlFormatMode formatMode = getFileAutoFormatMode( pFilename ); + // Reset master node Id. + mMasterNodeId = 0; + } - // Handle format mode appropriately. - switch( formatMode ) - { - case XmlFormat: - { - // Parse with the visitor. - TamlXmlParser parser; + //----------------------------------------------------------------------------- - // Are property changes needed but not supported? - if ( visitor.wantsPropertyChanges() && !parser.canChangeProperty() ) - { - // Yes, so warn. - Con::warnf( "Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a specified visitor requires property changes which are not supported by the parser.", getFormatModeDescription(formatMode), pFilename ); - return false; - } + Taml::TamlFormatMode Taml::getFileAutoFormatMode(const char* pFilename) + { + // Sanity! + AssertFatal(pFilename != NULL, "Taml::getFileAutoFormatMode() - Cannot auto-format using a NULL filename."); - return parser.accept( pFilename, visitor ); - } + // Is auto-format active? + if (mAutoFormat) + { + // Yes, so fetch the extension lengths. + const U32 xmlExtensionLength = dStrlen(mAutoFormatXmlExtension); + const U32 binaryExtensionLength = dStrlen(mAutoFormatBinaryExtension); + const U32 jsonExtensionLength = dStrlen(mAutoFormatJSONExtension); - case JSONFormat: - { - // Parse with the visitor. - /*TamlJSONParser parser; + // Fetch filename length. + const U32 filenameLength = dStrlen(pFilename); - // Are property changes needed but not supported? - if ( visitor.wantsPropertyChanges() && !parser.canChangeProperty() ) - { - // Yes, so warn. - Con::warnf( "Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a specified visitor requires property changes which are not supported by the parser.", getFormatModeDescription(formatMode), pFilename ); - return false; - } + // Fetch end of filename, + const char* pEndOfFilename = pFilename + filenameLength; - return parser.accept( pFilename, visitor ); */ - return false; - } - - case BinaryFormat: - default: - break; - } - - // Warn. - Con::warnf( "Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a required parser is not available.", getFormatModeDescription(formatMode), pFilename ); - return false; -} - -//----------------------------------------------------------------------------- - -void Taml::resetCompilation( void ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_ResetCompilation); - - // Clear compiled nodes. - for( typeNodeVector::iterator itr = mCompiledNodes.begin(); itr != mCompiledNodes.end(); ++itr ) - { - // Fetch node. - TamlWriteNode* pNode = (*itr); - - // Reset node. - pNode->resetNode(); - - // Delete node. - delete pNode; - } - mCompiledNodes.clear(); - - // Clear compiled objects. - mCompiledObjects.clear(); - - // Reset master node Id. - mMasterNodeId = 0; -} - -//----------------------------------------------------------------------------- - -Taml::TamlFormatMode Taml::getFileAutoFormatMode( const char* pFilename ) -{ - // Sanity! - AssertFatal( pFilename != NULL, "Taml::getFileAutoFormatMode() - Cannot auto-format using a NULL filename." ); - - // Is auto-format active? - if ( mAutoFormat ) - { - // Yes, so fetch the extension lengths. - const U32 xmlExtensionLength = dStrlen( mAutoFormatXmlExtension ); - const U32 binaryExtensionLength = dStrlen( mAutoFormatBinaryExtension ); - const U32 jsonExtensionLength = dStrlen( mAutoFormatJSONExtension ); - - // Fetch filename length. - const U32 filenameLength = dStrlen( pFilename ); - - // Fetch end of filename, - const char* pEndOfFilename = pFilename + filenameLength; - - // Check for the XML format. - if ( xmlExtensionLength <= filenameLength && dStricmp( pEndOfFilename - xmlExtensionLength, mAutoFormatXmlExtension ) == 0 ) + // Check for the XML format. + if (xmlExtensionLength <= filenameLength && dStricmp(pEndOfFilename - xmlExtensionLength, mAutoFormatXmlExtension) == 0) return Taml::XmlFormat; - // Check for the Binary format. - if ( binaryExtensionLength <= filenameLength && dStricmp( pEndOfFilename - xmlExtensionLength, mAutoFormatBinaryExtension ) == 0 ) - return Taml::BinaryFormat; + // Check for the Binary format. + if (binaryExtensionLength <= filenameLength && dStricmp(pEndOfFilename - xmlExtensionLength, mAutoFormatBinaryExtension) == 0) + return Taml::BinaryFormat; - // Check for the XML format. - if ( jsonExtensionLength <= filenameLength && dStricmp( pEndOfFilename - jsonExtensionLength, mAutoFormatJSONExtension ) == 0 ) + // Check for the XML format. + if (jsonExtensionLength <= filenameLength && dStricmp(pEndOfFilename - jsonExtensionLength, mAutoFormatJSONExtension) == 0) return Taml::JSONFormat; - } + } - // Use the explicitly specified format mode. - return mFormatMode; -} + // Use the explicitly specified format mode. + return mFormatMode; + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -TamlWriteNode* Taml::compileObject( SimObject* pSimObject, const bool forceId ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompileObject); + TamlWriteNode* Taml::compileObject(SimObject* pSimObject, const bool forceId) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompileObject); - // Sanity! - AssertFatal( pSimObject != NULL, "Taml::compileObject() - Cannot compile a NULL object." ); + // Sanity! + AssertFatal(pSimObject != NULL, "Taml::compileObject() - Cannot compile a NULL object."); - // Fetch object Id. - const SimObjectId objectId = pSimObject->getId(); + // Fetch object Id. + const SimObjectId objectId = pSimObject->getId(); - // Find a previously compiled node. - typeCompiledHash::Iterator compiledItr = mCompiledObjects.find( objectId ); + // Find a previously compiled node. + typeCompiledHash::Iterator compiledItr = mCompiledObjects.find(objectId); - // Have we already compiled this? - if ( compiledItr != mCompiledObjects.end() ) - { - // Yes, so sanity! - AssertFatal( mCompiledNodes.size() != 0, "Taml::compileObject() - Found a compiled node at the root." ); + // Have we already compiled this? + if (compiledItr != mCompiledObjects.end()) + { + // Yes, so sanity! + AssertFatal(mCompiledNodes.size() != 0, "Taml::compileObject() - Found a compiled node at the root."); - // Yes, so fetch node. - TamlWriteNode* compiledNode = compiledItr->value; + // Yes, so fetch node. + TamlWriteNode* compiledNode = compiledItr->value; - // Is a reference Id already present? - if ( compiledNode->mRefId == 0 ) - { + // Is a reference Id already present? + if (compiledNode->mRefId == 0) + { // No, so allocate one. compiledNode->mRefId = ++mMasterNodeId; - } + } - // Create write node. - TamlWriteNode* pNewNode = new TamlWriteNode(); - pNewNode->set( pSimObject ); + // Create write node. + TamlWriteNode* pNewNode = new TamlWriteNode(); + pNewNode->set(pSimObject); - // Set reference node. - pNewNode->mRefToNode = compiledNode; + // Set reference node. + pNewNode->mRefToNode = compiledNode; - // Push new node. - mCompiledNodes.push_back( pNewNode ); + // Push new node. + mCompiledNodes.push_back(pNewNode); - return pNewNode; - } + return pNewNode; + } - // No, so create write node. - TamlWriteNode* pNewNode = new TamlWriteNode(); - pNewNode->set( pSimObject ); + // No, so create write node. + TamlWriteNode* pNewNode = new TamlWriteNode(); + pNewNode->set(pSimObject); - // Is an Id being forced for this object? - if ( forceId ) - { - // Yes, so allocate one. - pNewNode->mRefId = ++mMasterNodeId; - } + // Is an Id being forced for this object? + if (forceId) + { + // Yes, so allocate one. + pNewNode->mRefId = ++mMasterNodeId; + } - // Push new node. - mCompiledNodes.push_back( pNewNode ); + // Push new node. + mCompiledNodes.push_back(pNewNode); - // Insert compiled object. - mCompiledObjects.insertUnique( objectId, pNewNode ); + // Insert compiled object. + mCompiledObjects.insertUnique(objectId, pNewNode); - // Are there any Taml callbacks? - if ( pNewNode->mpTamlCallbacks != NULL ) - { - // Yes, so call it. - tamlPreWrite( pNewNode->mpTamlCallbacks ); - } + // Are there any Taml callbacks? + if (pNewNode->mpTamlCallbacks != NULL) + { + // Yes, so call it. + tamlPreWrite(pNewNode->mpTamlCallbacks); + } - // Compile static and dynamic fields. - compileStaticFields( pNewNode ); - compileDynamicFields( pNewNode ); + // Compile static and dynamic fields. + compileStaticFields(pNewNode); + compileDynamicFields(pNewNode); - // Compile children. - compileChildren( pNewNode ); + // Compile children. + compileChildren(pNewNode); - // Compile custom state. - compileCustomState( pNewNode ); + // Compile custom state. + compileCustomState(pNewNode); - // Are there any Taml callbacks? - if ( pNewNode->mpTamlCallbacks != NULL ) - { - // Yes, so call it. - tamlPostWrite( pNewNode->mpTamlCallbacks ); - } + // Are there any Taml callbacks? + if (pNewNode->mpTamlCallbacks != NULL) + { + // Yes, so call it. + tamlPostWrite(pNewNode->mpTamlCallbacks); + } - return pNewNode; -} + return pNewNode; + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -void Taml::compileStaticFields( TamlWriteNode* pTamlWriteNode ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompileStaticFields); + void Taml::compileStaticFields(TamlWriteNode* pTamlWriteNode) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompileStaticFields); - // Sanity! - AssertFatal( pTamlWriteNode != NULL, "Cannot compile static fields on a NULL node." ); - AssertFatal( pTamlWriteNode->mpSimObject != NULL, "Cannot compile static fields on a node with no object." ); + // Sanity! + AssertFatal(pTamlWriteNode != NULL, "Cannot compile static fields on a NULL node."); + AssertFatal(pTamlWriteNode->mpSimObject != NULL, "Cannot compile static fields on a node with no object."); - // Fetch object. - SimObject* pSimObject = pTamlWriteNode->mpSimObject; + // Fetch object. + SimObject* pSimObject = pTamlWriteNode->mpSimObject; - // Fetch field list. - const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList(); + // Fetch field list. + const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList(); - // Fetch field count. - const U32 fieldCount = fieldList.size(); + // Fetch field count. + const U32 fieldCount = fieldList.size(); - // Iterate fields. - U8 arrayDepth = 0; - TamlCustomNode* currentArrayNode; - for( U32 index = 0; index < fieldCount; ++index ) - { - // Fetch field. - const AbstractClassRep::Field* pField = &fieldList[index]; + // Iterate fields. + U8 arrayDepth = 0; + TamlCustomNode* currentArrayNode; + for (U32 index = 0; index < fieldCount; ++index) + { + // Fetch field. + const AbstractClassRep::Field* pField = &fieldList[index]; - // Ignore if field not appropriate. - if( pField->type == AbstractClassRep::DeprecatedFieldType || + // Ignore if field not appropriate. + if (pField->type == AbstractClassRep::DeprecatedFieldType || pField->type == AbstractClassRep::StartGroupFieldType || - pField->type == AbstractClassRep::EndGroupFieldType ) + pField->type == AbstractClassRep::EndGroupFieldType) continue; - if( pField->type == AbstractClassRep::StartArrayFieldType ) - { - TamlCustomNodes& pCustomNodes = pTamlWriteNode->mCustomNodes; - currentArrayNode = pCustomNodes.addNode(pField->pGroupname); - for(U16 idx = 0; idx < pField->elementCount; idx++) - currentArrayNode->addNode(pField->pFieldname); - arrayDepth++; - continue; - } + if (pField->type == AbstractClassRep::StartArrayFieldType) + { + TamlCustomNodes& pCustomNodes = pTamlWriteNode->mCustomNodes; + currentArrayNode = pCustomNodes.addNode(pField->pGroupname); + for (U16 idx = 0; idx < pField->elementCount; idx++) + currentArrayNode->addNode(pField->pFieldname); + arrayDepth++; + continue; + } - if( pField->type == AbstractClassRep::EndArrayFieldType ) - { - arrayDepth--; - continue; - } + if (pField->type == AbstractClassRep::EndArrayFieldType) + { + arrayDepth--; + continue; + } - if(arrayDepth == 0 && pField->elementCount > 1) - { - TamlCustomNodes& pCustomNodes = pTamlWriteNode->mCustomNodes; - char* niceFieldName = const_cast(pField->pFieldname); - niceFieldName[0] = dToupper(niceFieldName[0]); - String str_niceFieldName = String(niceFieldName); - currentArrayNode = pCustomNodes.addNode(str_niceFieldName + "s"); - for(U16 idx = 0; idx < pField->elementCount; idx++) - currentArrayNode->addNode(str_niceFieldName); - } + if (arrayDepth == 0 && pField->elementCount > 1) + { + TamlCustomNodes& pCustomNodes = pTamlWriteNode->mCustomNodes; + char* niceFieldName = const_cast(pField->pFieldname); + niceFieldName[0] = dToupper(niceFieldName[0]); + String str_niceFieldName = String(niceFieldName); + currentArrayNode = pCustomNodes.addNode(str_niceFieldName + "s"); + for (U16 idx = 0; idx < pField->elementCount; idx++) + currentArrayNode->addNode(str_niceFieldName); + } - // Fetch fieldname. - StringTableEntry fieldName = StringTable->insert( pField->pFieldname ); + // Fetch fieldname. + StringTableEntry fieldName = StringTable->insert(pField->pFieldname); - // Fetch element count. - const U32 elementCount = pField->elementCount; + // Fetch element count. + const U32 elementCount = pField->elementCount; - // Skip if the field should not be written. - // For now, we only deal with non-array fields. - if ( elementCount == 1 && - pField->setDataFn != NULL && - ( !getWriteDefaults() && pField->writeDataFn( pSimObject, fieldName ) == false) ) + // Skip if the field should not be written. + // For now, we only deal with non-array fields. + if (elementCount == 1 && + pField->setDataFn != NULL && + (!getWriteDefaults() && pField->writeDataFn(pSimObject, fieldName) == false)) continue; - // Iterate elements. - for( U32 elementIndex = 0; elementIndex < elementCount; ++elementIndex ) - { + // Iterate elements. + for (U32 elementIndex = 0; elementIndex < elementCount; ++elementIndex) + { char indexBuffer[8]; - dSprintf( indexBuffer, 8, "%d", elementIndex ); + dSprintf(indexBuffer, 8, "%d", elementIndex); // Fetch object field value. const char* pFieldValue = pSimObject->getPrefixedDataField(fieldName, indexBuffer); - if(!pFieldValue) + if (!pFieldValue) pFieldValue = StringTable->EmptyString(); - if(pField->type == TypeBool) + if (pField->type == TypeBool) pFieldValue = dAtob(pFieldValue) ? "true" : "false"; - U32 nBufferSize = dStrlen( pFieldValue ) + 1; - FrameTemp valueCopy( nBufferSize ); - dStrcpy( (char *)valueCopy, pFieldValue ); + U32 nBufferSize = dStrlen(pFieldValue) + 1; + FrameTemp valueCopy(nBufferSize); + dStrcpy((char *)valueCopy, pFieldValue); // Skip if field should not be written. if (!pSimObject->writeField(fieldName, valueCopy)) - continue; + continue; // Reassign field value. pFieldValue = valueCopy; @@ -719,657 +721,660 @@ void Taml::compileStaticFields( TamlWriteNode* pTamlWriteNode ) char fnBuf[1024]; if ((S32)pField->type == TypeFilename) { - Con::collapseScriptFilename( fnBuf, 1024, pFieldValue ); - pFieldValue = fnBuf; + Con::collapseScriptFilename(fnBuf, 1024, pFieldValue); + pFieldValue = fnBuf; } // Save field/value. - if(arrayDepth > 0 || pField->elementCount > 1) + if (arrayDepth > 0 || pField->elementCount > 1) currentArrayNode->getChildren()[elementIndex]->addField(fieldName, pFieldValue); else { - TamlWriteNode::FieldValuePair* pFieldValuePair = new TamlWriteNode::FieldValuePair( fieldName, pFieldValue ); - pTamlWriteNode->mFields.push_back( pFieldValuePair ); + TamlWriteNode::FieldValuePair* pFieldValuePair = new TamlWriteNode::FieldValuePair(fieldName, pFieldValue); + pTamlWriteNode->mFields.push_back(pFieldValuePair); } - } - } -} + } + } + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -static S32 QSORT_CALLBACK compareFieldEntries(const void* a,const void* b) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompareFieldEntries); + static S32 QSORT_CALLBACK compareFieldEntries(const void* a, const void* b) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompareFieldEntries); - SimFieldDictionary::Entry *fa = *((SimFieldDictionary::Entry **)a); - SimFieldDictionary::Entry *fb = *((SimFieldDictionary::Entry **)b); - return dStricmp(fa->slotName, fb->slotName); -} + SimFieldDictionary::Entry *fa = *((SimFieldDictionary::Entry **)a); + SimFieldDictionary::Entry *fb = *((SimFieldDictionary::Entry **)b); + return dStricmp(fa->slotName, fb->slotName); + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -void Taml::compileDynamicFields( TamlWriteNode* pTamlWriteNode ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompileDynamicFields); + void Taml::compileDynamicFields(TamlWriteNode* pTamlWriteNode) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompileDynamicFields); - // Sanity! - AssertFatal( pTamlWriteNode != NULL, "Cannot compile dynamic fields on a NULL node." ); - AssertFatal( pTamlWriteNode->mpSimObject != NULL, "Cannot compile dynamic fields on a node with no object." ); + // Sanity! + AssertFatal(pTamlWriteNode != NULL, "Cannot compile dynamic fields on a NULL node."); + AssertFatal(pTamlWriteNode->mpSimObject != NULL, "Cannot compile dynamic fields on a node with no object."); - // Fetch object. - SimObject* pSimObject = pTamlWriteNode->mpSimObject; + // Fetch object. + SimObject* pSimObject = pTamlWriteNode->mpSimObject; - // Fetch field dictionary. - SimFieldDictionary* pFieldDictionary = pSimObject->getFieldDictionary(); + // Fetch field dictionary. + SimFieldDictionary* pFieldDictionary = pSimObject->getFieldDictionary(); - // Ignore if not writing dynamic fields. - if ( !pFieldDictionary || !pSimObject->getCanSaveDynamicFields() ) - return; + // Ignore if not writing dynamic fields. + if (!pFieldDictionary || !pSimObject->getCanSaveDynamicFields()) + return; - // Fetch field list. - const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList(); + // Fetch field list. + const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList(); - // Fetch field count. - const U32 fieldCount = fieldList.size(); + // Fetch field count. + const U32 fieldCount = fieldList.size(); - Vector dynamicFieldList(__FILE__, __LINE__); + Vector dynamicFieldList(__FILE__, __LINE__); - // Ensure the dynamic field doesn't conflict with static field. - for( U32 hashIndex = 0; hashIndex < SimFieldDictionary::HashTableSize; ++hashIndex ) - { - for (const SimFieldDictionary::Entry &pEntry : pFieldDictionary->mHashTable[hashIndex]) - { + // Ensure the dynamic field doesn't conflict with static field. + for (U32 hashIndex = 0; hashIndex < SimFieldDictionary::HashTableSize; ++hashIndex) + { + for (SimFieldDictionary::Entry* pEntry = pFieldDictionary->mHashTable[hashIndex]; pEntry; pEntry = pEntry->next) + { // Iterate static fields. U32 fieldIndex; - for( fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex ) + for (fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex) { - if (fieldList[fieldIndex].pFieldname == pEntry.slotName) - break; + if (fieldList[fieldIndex].pFieldname == pEntry->slotName) + break; } // Skip if found. - if( fieldIndex != (U32)fieldList.size() ) - continue; + if (fieldIndex != (U32)fieldList.size()) + continue; // Skip if not writing field. - if (!pSimObject->writeField(pEntry.slotName, pEntry.value)) - continue; + if (!pSimObject->writeField(pEntry->slotName, pEntry->value)) + continue; - dynamicFieldList.push_back( pEntry ); - } - } + dynamicFieldList.push_back(pEntry); + } + } - // Sort Entries to prevent version control conflicts - if ( dynamicFieldList.size() > 1 ) - dQsort(dynamicFieldList.address(), dynamicFieldList.size(), sizeof(SimFieldDictionary::Entry), compareFieldEntries); + // Sort Entries to prevent version control conflicts + if (dynamicFieldList.size() > 1) + dQsort(dynamicFieldList.address(), dynamicFieldList.size(), sizeof(SimFieldDictionary::Entry*), compareFieldEntries); - // Save the fields. - for (const SimFieldDictionary::Entry &pEntry : dynamicFieldList) - { - // Save field/value. - TamlWriteNode::FieldValuePair* pFieldValuePair = new TamlWriteNode::FieldValuePair(pEntry.slotName, pEntry.value); - pTamlWriteNode->mFields.push_back(pFieldValuePair); - } -} + // Save the fields. + for (Vector::iterator entryItr = dynamicFieldList.begin(); entryItr != dynamicFieldList.end(); ++entryItr) + { + // Fetch entry. + SimFieldDictionary::Entry* pEntry = *entryItr; -//----------------------------------------------------------------------------- + // Save field/value. + TamlWriteNode::FieldValuePair* pFieldValuePair = new TamlWriteNode::FieldValuePair(pEntry->slotName, pEntry->value); + pTamlWriteNode->mFields.push_back(pFieldValuePair); + } + } -void Taml::compileChildren( TamlWriteNode* pTamlWriteNode ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompileChildren); + //----------------------------------------------------------------------------- - // Sanity! - AssertFatal( pTamlWriteNode != NULL, "Cannot compile children on a NULL node." ); - AssertFatal( pTamlWriteNode->mpSimObject != NULL, "Cannot compile children on a node with no object." ); + void Taml::compileChildren(TamlWriteNode* pTamlWriteNode) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompileChildren); - // Fetch object. - SimObject* pSimObject = pTamlWriteNode->mpSimObject; + // Sanity! + AssertFatal(pTamlWriteNode != NULL, "Cannot compile children on a NULL node."); + AssertFatal(pTamlWriteNode->mpSimObject != NULL, "Cannot compile children on a node with no object."); - // Fetch the Taml children. - TamlChildren* pChildren = dynamic_cast( pSimObject ); + // Fetch object. + SimObject* pSimObject = pTamlWriteNode->mpSimObject; - // Finish if object does not contain Taml children. - if ( pChildren == NULL || pChildren->getTamlChildCount() == 0 ) - return; + // Fetch the Taml children. + TamlChildren* pChildren = dynamic_cast(pSimObject); - // Create children vector. - pTamlWriteNode->mChildren = new typeNodeVector(); + // Finish if object does not contain Taml children. + if (pChildren == NULL || pChildren->getTamlChildCount() == 0) + return; - // Fetch the child count. - const U32 childCount = pChildren->getTamlChildCount(); + // Create children vector. + pTamlWriteNode->mChildren = new typeNodeVector(); - // Iterate children. - for ( U32 childIndex = 0; childIndex < childCount; childIndex++ ) - { - // Compile object. - TamlWriteNode* pChildTamlWriteNode = compileObject( pChildren->getTamlChild(childIndex) ); + // Fetch the child count. + const U32 childCount = pChildren->getTamlChildCount(); - // Save node. - pTamlWriteNode->mChildren->push_back( pChildTamlWriteNode ); - } -} + // Iterate children. + for (U32 childIndex = 0; childIndex < childCount; childIndex++) + { + // Compile object. + TamlWriteNode* pChildTamlWriteNode = compileObject(pChildren->getTamlChild(childIndex)); -//----------------------------------------------------------------------------- + // Save node. + pTamlWriteNode->mChildren->push_back(pChildTamlWriteNode); + } + } -void Taml::compileCustomState( TamlWriteNode* pTamlWriteNode ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompileCustomProperties); + //----------------------------------------------------------------------------- - // Sanity! - AssertFatal( pTamlWriteNode != NULL, "Cannot compile custom state on a NULL node." ); - AssertFatal( pTamlWriteNode->mpSimObject != NULL, "Cannot compile custom state on a node with no object." ); + void Taml::compileCustomState(TamlWriteNode* pTamlWriteNode) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompileCustomProperties); - // Fetch the custom node on the write node. - TamlCustomNodes& customNodes = pTamlWriteNode->mCustomNodes; + // Sanity! + AssertFatal(pTamlWriteNode != NULL, "Cannot compile custom state on a NULL node."); + AssertFatal(pTamlWriteNode->mpSimObject != NULL, "Cannot compile custom state on a node with no object."); - // Are there any Taml callbacks? - if ( pTamlWriteNode->mpTamlCallbacks != NULL ) - { - // Yes, so call it. - tamlCustomWrite( pTamlWriteNode->mpTamlCallbacks, customNodes ); - } + // Fetch the custom node on the write node. + TamlCustomNodes& customNodes = pTamlWriteNode->mCustomNodes; - // Fetch custom nodes. - const TamlCustomNodeVector& nodes = customNodes.getNodes(); + // Are there any Taml callbacks? + if (pTamlWriteNode->mpTamlCallbacks != NULL) + { + // Yes, so call it. + tamlCustomWrite(pTamlWriteNode->mpTamlCallbacks, customNodes); + } - // Finish if no custom nodes to process. - if ( nodes.size() == 0 ) - return; - - // Iterate custom properties. - for( TamlCustomNodeVector::const_iterator customNodesItr = nodes.begin(); customNodesItr != nodes.end(); ++customNodesItr ) - { - // Fetch the custom node. - TamlCustomNode* pCustomNode = *customNodesItr; + // Fetch custom nodes. + const TamlCustomNodeVector& nodes = customNodes.getNodes(); - // Compile custom node state. - compileCustomNodeState( pCustomNode ); - } -} + // Finish if no custom nodes to process. + if (nodes.size() == 0) + return; -//----------------------------------------------------------------------------- + // Iterate custom properties. + for (TamlCustomNodeVector::const_iterator customNodesItr = nodes.begin(); customNodesItr != nodes.end(); ++customNodesItr) + { + // Fetch the custom node. + TamlCustomNode* pCustomNode = *customNodesItr; -void Taml::compileCustomNodeState( TamlCustomNode* pCustomNode ) -{ - // Sanity! - AssertFatal( pCustomNode != NULL, "Taml: Cannot compile NULL custom node state." ); + // Compile custom node state. + compileCustomNodeState(pCustomNode); + } + } - // Fetch children. - const TamlCustomNodeVector& children = pCustomNode->getChildren(); + //----------------------------------------------------------------------------- - // Fetch proxy object. - SimObject* pProxyObject = pCustomNode->getProxyObject(false); + void Taml::compileCustomNodeState(TamlCustomNode* pCustomNode) + { + // Sanity! + AssertFatal(pCustomNode != NULL, "Taml: Cannot compile NULL custom node state."); - // Do we have a proxy object? - if ( pProxyObject != NULL ) - { - // Yes, so sanity! - AssertFatal( children.size() == 0, "Taml: Cannot compile a proxy object on a custom node that has children." ); + // Fetch children. + const TamlCustomNodeVector& children = pCustomNode->getChildren(); - // Yes, so compile it. - // NOTE: We force an Id for custom compiled objects so we guarantee an Id. The reason for this is fairly - // weak in that the XML parser currently has no way of distinguishing between a compiled object node - // and a custom node. If the node has an Id or an Id-Ref then it's obviously an object and should be parsed as such. - pCustomNode->setWriteNode( compileObject( pProxyObject, true ) ); - return; - } + // Fetch proxy object. + SimObject* pProxyObject = pCustomNode->getProxyObject(false); - // Finish if no children. - if ( children.size() == 0 ) - return; + // Do we have a proxy object? + if (pProxyObject != NULL) + { + // Yes, so sanity! + AssertFatal(children.size() == 0, "Taml: Cannot compile a proxy object on a custom node that has children."); - // Iterate children. - for( TamlCustomNodeVector::const_iterator childItr = children.begin(); childItr != children.end(); ++childItr ) - { - // Fetch shape node. - TamlCustomNode* pChildNode = *childItr; + // Yes, so compile it. + // NOTE: We force an Id for custom compiled objects so we guarantee an Id. The reason for this is fairly + // weak in that the XML parser currently has no way of distinguishing between a compiled object node + // and a custom node. If the node has an Id or an Id-Ref then it's obviously an object and should be parsed as such. + pCustomNode->setWriteNode(compileObject(pProxyObject, true)); + return; + } - // Compile the child. - compileCustomNodeState( pChildNode ); - } -} + // Finish if no children. + if (children.size() == 0) + return; -//----------------------------------------------------------------------------- + // Iterate children. + for (TamlCustomNodeVector::const_iterator childItr = children.begin(); childItr != children.end(); ++childItr) + { + // Fetch shape node. + TamlCustomNode* pChildNode = *childItr; -SimObject* Taml::createType( StringTableEntry typeName, const Taml* pTaml, const char* pProgenitorSuffix ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CreateType); + // Compile the child. + compileCustomNodeState(pChildNode); + } + } - typedef HashTable typeClassHash; - static typeClassHash mClassMap; + //----------------------------------------------------------------------------- - // Sanity! - AssertFatal( typeName != NULL, "Taml: Type cannot be NULL" ); + SimObject* Taml::createType(StringTableEntry typeName, const Taml* pTaml, const char* pProgenitorSuffix) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CreateType); - // Find type. - typeClassHash::Iterator typeItr = mClassMap.find( typeName ); + typedef HashTable typeClassHash; + static typeClassHash mClassMap; - // Found type? - if ( typeItr == mClassMap.end() ) - { - // No, so find type. - AbstractClassRep* pClassRep = AbstractClassRep::getClassList(); - while( pClassRep ) - { + // Sanity! + AssertFatal(typeName != NULL, "Taml: Type cannot be NULL"); + + // Find type. + typeClassHash::Iterator typeItr = mClassMap.find(typeName); + + // Found type? + if (typeItr == mClassMap.end()) + { + // No, so find type. + AbstractClassRep* pClassRep = AbstractClassRep::getClassList(); + while (pClassRep) + { // Is this the type? - if( dStricmp( pClassRep->getClassName(), typeName ) == 0 ) + if (dStricmp(pClassRep->getClassName(), typeName) == 0) { - // Yes, so insert it. - typeItr = mClassMap.insertUnique( typeName, pClassRep ); - break; + // Yes, so insert it. + typeItr = mClassMap.insertUnique(typeName, pClassRep); + break; } // Next type. pClassRep = pClassRep->getNextClass(); - } + } - // Did we find the type? - if ( typeItr == mClassMap.end() ) - { + // Did we find the type? + if (typeItr == mClassMap.end()) + { // No, so warn and fail. - Con::warnf( "Taml: Failed to create type '%s' as such a registered type could not be found.", typeName ); + Con::warnf("Taml: Failed to create type '%s' as such a registered type could not be found.", typeName); return NULL; - } - } + } + } - // Create the object. - ConsoleObject* pConsoleObject = typeItr->value->create(); + // Create the object. + ConsoleObject* pConsoleObject = typeItr->value->create(); - // NOTE: It is important that we don't register the object here as many objects rely on the fact that - // fields are set prior to the object being registered. Registering here will invalid those assumptions. + // NOTE: It is important that we don't register the object here as many objects rely on the fact that + // fields are set prior to the object being registered. Registering here will invalid those assumptions. - // Fetch the SimObject. - SimObject* pSimObject = dynamic_cast( pConsoleObject ); + // Fetch the SimObject. + SimObject* pSimObject = dynamic_cast(pConsoleObject); - // Was it a SimObject? - if ( pSimObject == NULL ) - { - // No, so warn. - Con::warnf( "Taml: Failed to create type '%s' as it is not a SimObject.", typeName ); + // Was it a SimObject? + if (pSimObject == NULL) + { + // No, so warn. + Con::warnf("Taml: Failed to create type '%s' as it is not a SimObject.", typeName); - // Destroy object and fail. - delete pConsoleObject; - return NULL; - } + // Destroy object and fail. + delete pConsoleObject; + return NULL; + } - // Are we updating the file-progenitor? - if ( pTaml->getProgenitorUpdate() ) - { - // Yes, so do we have a progenitor suffix? - if ( pProgenitorSuffix == NULL ) - { + // Are we updating the file-progenitor? + if (pTaml->getProgenitorUpdate()) + { + // Yes, so do we have a progenitor suffix? + if (pProgenitorSuffix == NULL) + { // No, so just set it to the progenitor file. - pSimObject->setProgenitorFile( pTaml->getFilePathBuffer() ); - } - else - { + pSimObject->setProgenitorFile(pTaml->getFilePathBuffer()); + } + else + { // Yes, so format the progenitor buffer. char progenitorBuffer[2048]; - dSprintf( progenitorBuffer, sizeof(progenitorBuffer), "%s,%s", pTaml->getFilePathBuffer(), pProgenitorSuffix ); + dSprintf(progenitorBuffer, sizeof(progenitorBuffer), "%s,%s", pTaml->getFilePathBuffer(), pProgenitorSuffix); // Set the progenitor file. - pSimObject->setProgenitorFile( progenitorBuffer ); - } - } + pSimObject->setProgenitorFile(progenitorBuffer); + } + } - return pSimObject; -} + return pSimObject; + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -bool Taml::generateTamlSchema() -{ - // Fetch any TAML Schema file reference. - const char* pTamlSchemaFile = Con::getVariable( TAML_SCHEMA_VARIABLE ); + bool Taml::generateTamlSchema() + { + // 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 ) - { - // No, so warn. - Con::warnf( "Taml::generateTamlSchema() - Cannot write a TAML schema as no schema variable is set ('%s').", TAML_SCHEMA_VARIABLE ); - return false; - } + // Do we have a schema file reference? + if (pTamlSchemaFile == NULL || *pTamlSchemaFile == 0) + { + // No, so warn. + Con::warnf("Taml::generateTamlSchema() - Cannot write a TAML schema as no schema variable is set ('%s').", TAML_SCHEMA_VARIABLE); + return false; + } - // Expand the file-name into the file-path buffer. - char filePathBuffer[1024]; - Con::expandToolScriptFilename( filePathBuffer, sizeof(filePathBuffer), pTamlSchemaFile ); + // Expand the file-name into the file-path buffer. + char filePathBuffer[1024]; + Con::expandToolScriptFilename(filePathBuffer, sizeof(filePathBuffer), pTamlSchemaFile); - FileStream stream; + FileStream stream; - // File opened? - /*if ( !stream.open( filePathBuffer, Torque::FS::File::Write ) ) - { - // No, so warn. - Con::warnf("Taml::GenerateTamlSchema() - Could not open filename '%s' for write.", filePathBuffer ); - return false; - }*/ + // File opened? + /*if ( !stream.open( filePathBuffer, Torque::FS::File::Write ) ) + { + // No, so warn. + Con::warnf("Taml::GenerateTamlSchema() - Could not open filename '%s' for write.", filePathBuffer ); + return false; + }*/ - // Create document. - TiXmlDocument schemaDocument; + // Create document. + TiXmlDocument schemaDocument; - // Add declaration. - TiXmlDeclaration schemaDeclaration( "1.0", "iso-8859-1", "no" ); - schemaDocument.InsertEndChild( schemaDeclaration ); + // Add declaration. + TiXmlDeclaration schemaDeclaration("1.0", "iso-8859-1", "no"); + schemaDocument.InsertEndChild(schemaDeclaration); - // Add schema element. - TiXmlElement* pSchemaElement = new TiXmlElement( "xs:schema" ); - pSchemaElement->SetAttribute( "xmlns:xs", "http://www.w3.org/2001/XMLSchema" ); - schemaDocument.LinkEndChild( pSchemaElement ); + // Add schema element. + TiXmlElement* pSchemaElement = new TiXmlElement("xs:schema"); + pSchemaElement->SetAttribute("xmlns:xs", "http://www.w3.org/2001/XMLSchema"); + schemaDocument.LinkEndChild(pSchemaElement); - // Fetch class-rep root. - AbstractClassRep* pRootType = AbstractClassRep::getClassList(); + // Fetch class-rep root. + AbstractClassRep* pRootType = AbstractClassRep::getClassList(); - // Fetch SimObject class rep. - AbstractClassRep* pSimObjectType = AbstractClassRep::findClassRep( "SimObject" ); - // Sanity! - AssertFatal( pSimObjectType != NULL, "Taml::GenerateTamlSchema() - Could not find SimObject class rep." ); + // Fetch SimObject class rep. + AbstractClassRep* pSimObjectType = AbstractClassRep::findClassRep("SimObject"); + // Sanity! + AssertFatal(pSimObjectType != NULL, "Taml::GenerateTamlSchema() - Could not find SimObject class rep."); - // Reset scratch state. - char buffer[1024]; - HashTable childGroups; + // Reset scratch state. + char buffer[1024]; + HashTable childGroups; - // ************************************************************* - // Generate console type elements. - // ************************************************************* + // ************************************************************* + // Generate console type elements. + // ************************************************************* - // Vector2. - TiXmlComment* pVector2Comment = new TiXmlComment( "Vector2 Console Type" ); - pSchemaElement->LinkEndChild( pVector2Comment ); - TiXmlElement* pVector2TypeElement = new TiXmlElement( "xs:simpleType" ); - pVector2TypeElement->SetAttribute( "name", "Vector2_ConsoleType" ); - pSchemaElement->LinkEndChild( pVector2TypeElement ); - TiXmlElement* pVector2ElementA = new TiXmlElement( "xs:restriction" ); - pVector2ElementA->SetAttribute( "base", "xs:string" ); - pVector2TypeElement->LinkEndChild( pVector2ElementA ); - TiXmlElement* pVector2ElementB = new TiXmlElement( "xs:pattern" ); - pVector2ElementB->SetAttribute( "value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b" ); - pVector2ElementA->LinkEndChild( pVector2ElementB ); + // Vector2. + TiXmlComment* pVector2Comment = new TiXmlComment("Vector2 Console Type"); + pSchemaElement->LinkEndChild(pVector2Comment); + TiXmlElement* pVector2TypeElement = new TiXmlElement("xs:simpleType"); + pVector2TypeElement->SetAttribute("name", "Vector2_ConsoleType"); + pSchemaElement->LinkEndChild(pVector2TypeElement); + TiXmlElement* pVector2ElementA = new TiXmlElement("xs:restriction"); + pVector2ElementA->SetAttribute("base", "xs:string"); + pVector2TypeElement->LinkEndChild(pVector2ElementA); + TiXmlElement* pVector2ElementB = new TiXmlElement("xs:pattern"); + pVector2ElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b"); + pVector2ElementA->LinkEndChild(pVector2ElementB); - // Point2F. - TiXmlComment* pPoint2FComment = new TiXmlComment( "Point2F Console Type" ); - pSchemaElement->LinkEndChild( pPoint2FComment ); - TiXmlElement* pPoint2FTypeElement = new TiXmlElement( "xs:simpleType" ); - pPoint2FTypeElement->SetAttribute( "name", "Point2F_ConsoleType" ); - pSchemaElement->LinkEndChild( pPoint2FTypeElement ); - TiXmlElement* pPoint2FElementA = new TiXmlElement( "xs:restriction" ); - pPoint2FElementA->SetAttribute( "base", "xs:string" ); - pPoint2FTypeElement->LinkEndChild( pPoint2FElementA ); - TiXmlElement* pPoint2FElementB = new TiXmlElement( "xs:pattern" ); - pPoint2FElementB->SetAttribute( "value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b" ); - pPoint2FElementA->LinkEndChild( pPoint2FElementB ); + // Point2F. + TiXmlComment* pPoint2FComment = new TiXmlComment("Point2F Console Type"); + pSchemaElement->LinkEndChild(pPoint2FComment); + TiXmlElement* pPoint2FTypeElement = new TiXmlElement("xs:simpleType"); + pPoint2FTypeElement->SetAttribute("name", "Point2F_ConsoleType"); + pSchemaElement->LinkEndChild(pPoint2FTypeElement); + TiXmlElement* pPoint2FElementA = new TiXmlElement("xs:restriction"); + pPoint2FElementA->SetAttribute("base", "xs:string"); + pPoint2FTypeElement->LinkEndChild(pPoint2FElementA); + TiXmlElement* pPoint2FElementB = new TiXmlElement("xs:pattern"); + pPoint2FElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b"); + pPoint2FElementA->LinkEndChild(pPoint2FElementB); - // Point2I. - TiXmlComment* pPoint2IComment = new TiXmlComment( "Point2I Console Type" ); - pSchemaElement->LinkEndChild( pPoint2IComment ); - TiXmlElement* pPoint2ITypeElement = new TiXmlElement( "xs:simpleType" ); - pPoint2ITypeElement->SetAttribute( "name", "Point2I_ConsoleType" ); - pSchemaElement->LinkEndChild( pPoint2ITypeElement ); - TiXmlElement* pPoint2IElementA = new TiXmlElement( "xs:restriction" ); - pPoint2IElementA->SetAttribute( "base", "xs:string" ); - pPoint2ITypeElement->LinkEndChild( pPoint2IElementA ); - TiXmlElement* pPoint2IElementB = new TiXmlElement( "xs:pattern" ); - pPoint2IElementB->SetAttribute( "value", "[-]?[0-9]* [-]?[0-9]*" ); - pPoint2IElementA->LinkEndChild( pPoint2IElementB ); + // Point2I. + TiXmlComment* pPoint2IComment = new TiXmlComment("Point2I Console Type"); + pSchemaElement->LinkEndChild(pPoint2IComment); + TiXmlElement* pPoint2ITypeElement = new TiXmlElement("xs:simpleType"); + pPoint2ITypeElement->SetAttribute("name", "Point2I_ConsoleType"); + pSchemaElement->LinkEndChild(pPoint2ITypeElement); + TiXmlElement* pPoint2IElementA = new TiXmlElement("xs:restriction"); + pPoint2IElementA->SetAttribute("base", "xs:string"); + pPoint2ITypeElement->LinkEndChild(pPoint2IElementA); + TiXmlElement* pPoint2IElementB = new TiXmlElement("xs:pattern"); + pPoint2IElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]*"); + pPoint2IElementA->LinkEndChild(pPoint2IElementB); - // b2AABB. - TiXmlComment* pb2AABBComment = new TiXmlComment( "b2AABB Console Type" ); - pSchemaElement->LinkEndChild( pb2AABBComment ); - TiXmlElement* pb2AABBTypeElement = new TiXmlElement( "xs:simpleType" ); - pb2AABBTypeElement->SetAttribute( "name", "b2AABB_ConsoleType" ); - pSchemaElement->LinkEndChild( pb2AABBTypeElement ); - TiXmlElement* pb2AABBElementA = new TiXmlElement( "xs:restriction" ); - pb2AABBElementA->SetAttribute( "base", "xs:string" ); - pb2AABBTypeElement->LinkEndChild( pb2AABBElementA ); - TiXmlElement* pb2AABBElementB = new TiXmlElement( "xs:pattern" ); - pb2AABBElementB->SetAttribute( "value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b" ); - pb2AABBElementA->LinkEndChild( pb2AABBElementB ); + // b2AABB. + TiXmlComment* pb2AABBComment = new TiXmlComment("b2AABB Console Type"); + pSchemaElement->LinkEndChild(pb2AABBComment); + TiXmlElement* pb2AABBTypeElement = new TiXmlElement("xs:simpleType"); + pb2AABBTypeElement->SetAttribute("name", "b2AABB_ConsoleType"); + pSchemaElement->LinkEndChild(pb2AABBTypeElement); + TiXmlElement* pb2AABBElementA = new TiXmlElement("xs:restriction"); + pb2AABBElementA->SetAttribute("base", "xs:string"); + pb2AABBTypeElement->LinkEndChild(pb2AABBElementA); + TiXmlElement* pb2AABBElementB = new TiXmlElement("xs:pattern"); + pb2AABBElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b"); + pb2AABBElementA->LinkEndChild(pb2AABBElementB); - // RectI. - TiXmlComment* pRectIComment = new TiXmlComment( "RectI Console Type" ); - pSchemaElement->LinkEndChild( pRectIComment ); - TiXmlElement* pRectITypeElement = new TiXmlElement( "xs:simpleType" ); - pRectITypeElement->SetAttribute( "name", "RectI_ConsoleType" ); - pSchemaElement->LinkEndChild( pRectITypeElement ); - TiXmlElement* pRectIElementA = new TiXmlElement( "xs:restriction" ); - pRectIElementA->SetAttribute( "base", "xs:string" ); - pRectITypeElement->LinkEndChild( pRectIElementA ); - TiXmlElement* pRectIElementB = new TiXmlElement( "xs:pattern" ); - pRectIElementB->SetAttribute( "value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*" ); - pRectIElementA->LinkEndChild( pRectIElementB ); + // RectI. + TiXmlComment* pRectIComment = new TiXmlComment("RectI Console Type"); + pSchemaElement->LinkEndChild(pRectIComment); + TiXmlElement* pRectITypeElement = new TiXmlElement("xs:simpleType"); + pRectITypeElement->SetAttribute("name", "RectI_ConsoleType"); + pSchemaElement->LinkEndChild(pRectITypeElement); + TiXmlElement* pRectIElementA = new TiXmlElement("xs:restriction"); + pRectIElementA->SetAttribute("base", "xs:string"); + pRectITypeElement->LinkEndChild(pRectIElementA); + TiXmlElement* pRectIElementB = new TiXmlElement("xs:pattern"); + pRectIElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*"); + pRectIElementA->LinkEndChild(pRectIElementB); - // RectF. - TiXmlComment* pRectFComment = new TiXmlComment( "RectF Console Type" ); - pSchemaElement->LinkEndChild( pRectFComment ); - TiXmlElement* pRectFTypeElement = new TiXmlElement( "xs:simpleType" ); - pRectFTypeElement->SetAttribute( "name", "RectF_ConsoleType" ); - pSchemaElement->LinkEndChild( pRectFTypeElement ); - TiXmlElement* pRectFElementA = new TiXmlElement( "xs:restriction" ); - pRectFElementA->SetAttribute( "base", "xs:string" ); - pRectFTypeElement->LinkEndChild( pRectFElementA ); - TiXmlElement* pRectFElementB = new TiXmlElement( "xs:pattern" ); - pRectFElementB->SetAttribute( "value", "(\\b[-]?(b[0-9]+)?\\.)?[0-9]+\\b" ); - pRectFElementA->LinkEndChild( pRectFElementB ); + // RectF. + TiXmlComment* pRectFComment = new TiXmlComment("RectF Console Type"); + pSchemaElement->LinkEndChild(pRectFComment); + TiXmlElement* pRectFTypeElement = new TiXmlElement("xs:simpleType"); + pRectFTypeElement->SetAttribute("name", "RectF_ConsoleType"); + pSchemaElement->LinkEndChild(pRectFTypeElement); + TiXmlElement* pRectFElementA = new TiXmlElement("xs:restriction"); + pRectFElementA->SetAttribute("base", "xs:string"); + pRectFTypeElement->LinkEndChild(pRectFElementA); + TiXmlElement* pRectFElementB = new TiXmlElement("xs:pattern"); + pRectFElementB->SetAttribute("value", "(\\b[-]?(b[0-9]+)?\\.)?[0-9]+\\b"); + pRectFElementA->LinkEndChild(pRectFElementB); - // AssetId. - TiXmlComment* pAssetIdComment = new TiXmlComment("AssetId Console Type"); - pSchemaElement->LinkEndChild(pAssetIdComment); - TiXmlElement* pAssetIdTypeElement = new TiXmlElement("xs:simpleType"); - pAssetIdTypeElement->SetAttribute("name", "AssetId_ConsoleType"); - pSchemaElement->LinkEndChild(pAssetIdTypeElement); - TiXmlElement* pAssetIdElementA = new TiXmlElement("xs:restriction"); - pAssetIdElementA->SetAttribute("base", "xs:string"); - pAssetIdTypeElement->LinkEndChild(pAssetIdElementA); - TiXmlElement* pAssetIdElementB = new TiXmlElement("xs:pattern"); - dSprintf(buffer, sizeof(buffer), "(%s)?\\b[a-zA-Z0-9]+\\b%s\\b[a-zA-Z0-9]+\\b", ASSET_ID_FIELD_PREFIX, ASSET_SCOPE_TOKEN); - pAssetIdElementB->SetAttribute("value", buffer); - pAssetIdElementA->LinkEndChild(pAssetIdElementB); + // AssetId. + TiXmlComment* pAssetIdComment = new TiXmlComment("AssetId Console Type"); + pSchemaElement->LinkEndChild(pAssetIdComment); + TiXmlElement* pAssetIdTypeElement = new TiXmlElement("xs:simpleType"); + pAssetIdTypeElement->SetAttribute("name", "AssetId_ConsoleType"); + pSchemaElement->LinkEndChild(pAssetIdTypeElement); + TiXmlElement* pAssetIdElementA = new TiXmlElement("xs:restriction"); + pAssetIdElementA->SetAttribute("base", "xs:string"); + pAssetIdTypeElement->LinkEndChild(pAssetIdElementA); + TiXmlElement* pAssetIdElementB = new TiXmlElement("xs:pattern"); + dSprintf(buffer, sizeof(buffer), "(%s)?\\b[a-zA-Z0-9]+\\b%s\\b[a-zA-Z0-9]+\\b", ASSET_ID_FIELD_PREFIX, ASSET_SCOPE_TOKEN); + pAssetIdElementB->SetAttribute("value", buffer); + pAssetIdElementA->LinkEndChild(pAssetIdElementB); - // Color Enums. - TiXmlComment* pColorEnumsComment = new TiXmlComment( "Color Enums" ); - pSchemaElement->LinkEndChild( pColorEnumsComment ); - TiXmlElement* pColorEnumsTypeElement = new TiXmlElement( "xs:simpleType" ); - pColorEnumsTypeElement->SetAttribute( "name", "Color_Enums" ); - pSchemaElement->LinkEndChild( pColorEnumsTypeElement ); - TiXmlElement* pColorEnumsRestrictionElement = new TiXmlElement( "xs:restriction" ); - pColorEnumsRestrictionElement->SetAttribute( "base", "xs:string" ); - pColorEnumsTypeElement->LinkEndChild( pColorEnumsRestrictionElement ); - const S32 ColorEnumsCount = StockColor::getCount(); - for( S32 index = 0; index < ColorEnumsCount; ++index ) - { - // Add enumeration element. - TiXmlElement* pColorEnumsAttributeEnumerationElement = new TiXmlElement( "xs:enumeration" ); - pColorEnumsAttributeEnumerationElement->SetAttribute( "value", StockColor::getColorItem(index)->getColorName() ); - pColorEnumsRestrictionElement->LinkEndChild( pColorEnumsAttributeEnumerationElement ); - } + // Color Enums. + TiXmlComment* pColorEnumsComment = new TiXmlComment("Color Enums"); + pSchemaElement->LinkEndChild(pColorEnumsComment); + TiXmlElement* pColorEnumsTypeElement = new TiXmlElement("xs:simpleType"); + pColorEnumsTypeElement->SetAttribute("name", "Color_Enums"); + pSchemaElement->LinkEndChild(pColorEnumsTypeElement); + TiXmlElement* pColorEnumsRestrictionElement = new TiXmlElement("xs:restriction"); + pColorEnumsRestrictionElement->SetAttribute("base", "xs:string"); + pColorEnumsTypeElement->LinkEndChild(pColorEnumsRestrictionElement); + const S32 ColorEnumsCount = StockColor::getCount(); + for (S32 index = 0; index < ColorEnumsCount; ++index) + { + // Add enumeration element. + TiXmlElement* pColorEnumsAttributeEnumerationElement = new TiXmlElement("xs:enumeration"); + pColorEnumsAttributeEnumerationElement->SetAttribute("value", StockColor::getColorItem(index)->getColorName()); + pColorEnumsRestrictionElement->LinkEndChild(pColorEnumsAttributeEnumerationElement); + } - // LinearColorF. - TiXmlComment* pColorFValuesComment = new TiXmlComment( "LinearColorF Values" ); - pSchemaElement->LinkEndChild( pColorFValuesComment ); - TiXmlElement* pColorFValuesTypeElement = new TiXmlElement( "xs:simpleType" ); - pColorFValuesTypeElement->SetAttribute( "name", "ColorF_Values" ); - pSchemaElement->LinkEndChild( pColorFValuesTypeElement ); - TiXmlElement* pColorFValuesElementA = new TiXmlElement( "xs:restriction" ); - pColorFValuesElementA->SetAttribute( "base", "xs:string" ); - pColorFValuesTypeElement->LinkEndChild( pColorFValuesElementA ); - TiXmlElement* pColorFValuesElementB = new TiXmlElement( "xs:pattern" ); - pColorFValuesElementB->SetAttribute( "value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b" ); - pColorFValuesElementA->LinkEndChild( pColorFValuesElementB ); + // LinearColorF. + TiXmlComment* pColorFValuesComment = new TiXmlComment("LinearColorF Values"); + pSchemaElement->LinkEndChild(pColorFValuesComment); + TiXmlElement* pColorFValuesTypeElement = new TiXmlElement("xs:simpleType"); + pColorFValuesTypeElement->SetAttribute("name", "ColorF_Values"); + pSchemaElement->LinkEndChild(pColorFValuesTypeElement); + TiXmlElement* pColorFValuesElementA = new TiXmlElement("xs:restriction"); + pColorFValuesElementA->SetAttribute("base", "xs:string"); + pColorFValuesTypeElement->LinkEndChild(pColorFValuesElementA); + TiXmlElement* pColorFValuesElementB = new TiXmlElement("xs:pattern"); + pColorFValuesElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b"); + pColorFValuesElementA->LinkEndChild(pColorFValuesElementB); - TiXmlComment* pColorFComment = new TiXmlComment( "LinearColorF Console Type" ); - pSchemaElement->LinkEndChild( pColorFComment ); - TiXmlElement* pColorFTypeElement = new TiXmlElement( "xs:simpleType" ); - pColorFTypeElement->SetAttribute( "name", "ColorF_ConsoleType" ); - pSchemaElement->LinkEndChild( pColorFTypeElement ); - TiXmlElement* pColorFUnionElement = new TiXmlElement( "xs:union" ); - pColorFUnionElement->SetAttribute( "memberTypes", "ColorF_Values Color_Enums" ); - pColorFTypeElement->LinkEndChild( pColorFUnionElement ); + TiXmlComment* pColorFComment = new TiXmlComment("LinearColorF Console Type"); + pSchemaElement->LinkEndChild(pColorFComment); + TiXmlElement* pColorFTypeElement = new TiXmlElement("xs:simpleType"); + pColorFTypeElement->SetAttribute("name", "ColorF_ConsoleType"); + pSchemaElement->LinkEndChild(pColorFTypeElement); + TiXmlElement* pColorFUnionElement = new TiXmlElement("xs:union"); + pColorFUnionElement->SetAttribute("memberTypes", "ColorF_Values Color_Enums"); + pColorFTypeElement->LinkEndChild(pColorFUnionElement); - // ColorI. - TiXmlComment* pColorIValuesComment = new TiXmlComment( "ColorI Values" ); - pSchemaElement->LinkEndChild( pColorIValuesComment ); - TiXmlElement* pColorIValuesTypeElement = new TiXmlElement( "xs:simpleType" ); - pColorIValuesTypeElement->SetAttribute( "name", "ColorI_Values" ); - pSchemaElement->LinkEndChild( pColorIValuesTypeElement ); - TiXmlElement* pColorIValuesElementA = new TiXmlElement( "xs:restriction" ); - pColorIValuesElementA->SetAttribute( "base", "xs:string" ); - pColorIValuesTypeElement->LinkEndChild( pColorIValuesElementA ); - TiXmlElement* pColorIValuesElementB = new TiXmlElement( "xs:pattern" ); - pColorIValuesElementB->SetAttribute( "value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*" ); - pColorIValuesElementA->LinkEndChild( pColorIValuesElementB ); + // ColorI. + TiXmlComment* pColorIValuesComment = new TiXmlComment("ColorI Values"); + pSchemaElement->LinkEndChild(pColorIValuesComment); + TiXmlElement* pColorIValuesTypeElement = new TiXmlElement("xs:simpleType"); + pColorIValuesTypeElement->SetAttribute("name", "ColorI_Values"); + pSchemaElement->LinkEndChild(pColorIValuesTypeElement); + TiXmlElement* pColorIValuesElementA = new TiXmlElement("xs:restriction"); + pColorIValuesElementA->SetAttribute("base", "xs:string"); + pColorIValuesTypeElement->LinkEndChild(pColorIValuesElementA); + TiXmlElement* pColorIValuesElementB = new TiXmlElement("xs:pattern"); + pColorIValuesElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*"); + pColorIValuesElementA->LinkEndChild(pColorIValuesElementB); - TiXmlComment* pColorIComment = new TiXmlComment( "ColorI Console Type" ); - pSchemaElement->LinkEndChild( pColorIComment ); - TiXmlElement* pColorITypeElement = new TiXmlElement( "xs:simpleType" ); - pColorITypeElement->SetAttribute( "name", "ColorI_ConsoleType" ); - pSchemaElement->LinkEndChild( pColorITypeElement ); - TiXmlElement* pColorIUnionElement = new TiXmlElement( "xs:union" ); - pColorIUnionElement->SetAttribute( "memberTypes", "ColorI_Values Color_Enums" ); - pColorITypeElement->LinkEndChild( pColorIUnionElement ); + TiXmlComment* pColorIComment = new TiXmlComment("ColorI Console Type"); + pSchemaElement->LinkEndChild(pColorIComment); + TiXmlElement* pColorITypeElement = new TiXmlElement("xs:simpleType"); + pColorITypeElement->SetAttribute("name", "ColorI_ConsoleType"); + pSchemaElement->LinkEndChild(pColorITypeElement); + TiXmlElement* pColorIUnionElement = new TiXmlElement("xs:union"); + pColorIUnionElement->SetAttribute("memberTypes", "ColorI_Values Color_Enums"); + pColorITypeElement->LinkEndChild(pColorIUnionElement); - // ************************************************************* - // Generate engine type elements. - // ************************************************************* + // ************************************************************* + // Generate engine type elements. + // ************************************************************* - // Generate the engine type elements. - TiXmlComment* pComment = new TiXmlComment( "Type Elements" ); - pSchemaElement->LinkEndChild( pComment ); - for ( AbstractClassRep* pType = pRootType; pType != NULL; pType = pType->getNextClass() ) - { - // Add type. - TiXmlElement* pTypeElement = new TiXmlElement( "xs:element" ); - pTypeElement->SetAttribute( "name", pType->getClassName() ); - dSprintf( buffer, sizeof(buffer), "%s_Type", pType->getClassName() ); - pTypeElement->SetAttribute( "type", buffer ); - pSchemaElement->LinkEndChild( pTypeElement ); - } + // Generate the engine type elements. + TiXmlComment* pComment = new TiXmlComment("Type Elements"); + pSchemaElement->LinkEndChild(pComment); + for (AbstractClassRep* pType = pRootType; pType != NULL; pType = pType->getNextClass()) + { + // Add type. + TiXmlElement* pTypeElement = new TiXmlElement("xs:element"); + pTypeElement->SetAttribute("name", pType->getClassName()); + dSprintf(buffer, sizeof(buffer), "%s_Type", pType->getClassName()); + pTypeElement->SetAttribute("type", buffer); + pSchemaElement->LinkEndChild(pTypeElement); + } - // ************************************************************* - // Generate the engine complex types. - // ************************************************************* - for ( AbstractClassRep* pType = pRootType; pType != NULL; pType = pType->getNextClass() ) - { - // Add complex type comment. - dSprintf( buffer, sizeof(buffer), " %s Type ", pType->getClassName() ); - TiXmlComment* pComment = new TiXmlComment( buffer ); - pSchemaElement->LinkEndChild( pComment ); + // ************************************************************* + // Generate the engine complex types. + // ************************************************************* + for (AbstractClassRep* pType = pRootType; pType != NULL; pType = pType->getNextClass()) + { + // Add complex type comment. + dSprintf(buffer, sizeof(buffer), " %s Type ", pType->getClassName()); + TiXmlComment* pComment = new TiXmlComment(buffer); + pSchemaElement->LinkEndChild(pComment); - // Add complex type. - TiXmlElement* pComplexTypeElement = new TiXmlElement( "xs:complexType" ); - dSprintf( buffer, sizeof(buffer), "%s_Type", pType->getClassName() ); - pComplexTypeElement->SetAttribute( "name", buffer ); - pSchemaElement->LinkEndChild( pComplexTypeElement ); + // Add complex type. + TiXmlElement* pComplexTypeElement = new TiXmlElement("xs:complexType"); + dSprintf(buffer, sizeof(buffer), "%s_Type", pType->getClassName()); + pComplexTypeElement->SetAttribute("name", buffer); + pSchemaElement->LinkEndChild(pComplexTypeElement); - // Add sequence. - TiXmlElement* pSequenceElement = new TiXmlElement( "xs:sequence" ); - pComplexTypeElement->LinkEndChild( pSequenceElement ); + // Add sequence. + TiXmlElement* pSequenceElement = new TiXmlElement("xs:sequence"); + pComplexTypeElement->LinkEndChild(pSequenceElement); - // Fetch container child class. - AbstractClassRep* pContainerChildClass = pType->getContainerChildClass( true ); + // Fetch container child class. + AbstractClassRep* pContainerChildClass = pType->getContainerChildClass(true); - // Is the type allowed children? - if ( pContainerChildClass != NULL ) - { + // Is the type allowed children? + if (pContainerChildClass != NULL) + { // Yes, so add choice element. - TiXmlElement* pChoiceElement = new TiXmlElement( "xs:choice" ); - pChoiceElement->SetAttribute( "minOccurs", 0 ); - pChoiceElement->SetAttribute( "maxOccurs", "unbounded" ); - pSequenceElement->LinkEndChild( pChoiceElement ); + TiXmlElement* pChoiceElement = new TiXmlElement("xs:choice"); + pChoiceElement->SetAttribute("minOccurs", 0); + pChoiceElement->SetAttribute("maxOccurs", "unbounded"); + pSequenceElement->LinkEndChild(pChoiceElement); // Find child group. - HashTable::Iterator childGroupItr = childGroups.find( pContainerChildClass ); + HashTable::Iterator childGroupItr = childGroups.find(pContainerChildClass); // Does the group exist? - if ( childGroupItr == childGroups.end() ) + if (childGroupItr == childGroups.end()) { - // No, so format group name. - dSprintf( buffer, sizeof(buffer), "%s_ChildrenTypes", pContainerChildClass->getClassName() ); + // No, so format group name. + dSprintf(buffer, sizeof(buffer), "%s_ChildrenTypes", pContainerChildClass->getClassName()); - // Insert into child group hash. - childGroupItr = childGroups.insertUnique( pContainerChildClass, StringTable->insert( buffer ) ); + // Insert into child group hash. + childGroupItr = childGroups.insertUnique(pContainerChildClass, StringTable->insert(buffer)); - // Add the group. - TiXmlElement* pChildrenGroupElement = new TiXmlElement( "xs:group" ); - pChildrenGroupElement->SetAttribute( "name", buffer ); - pSchemaElement->LinkEndChild( pChildrenGroupElement ); + // Add the group. + TiXmlElement* pChildrenGroupElement = new TiXmlElement("xs:group"); + pChildrenGroupElement->SetAttribute("name", buffer); + pSchemaElement->LinkEndChild(pChildrenGroupElement); - // Add choice element. - TiXmlElement* pChildreGroupChoiceElement = new TiXmlElement( "xs:choice" ); - pChildrenGroupElement->LinkEndChild( pChildreGroupChoiceElement ); + // Add choice element. + TiXmlElement* pChildreGroupChoiceElement = new TiXmlElement("xs:choice"); + pChildrenGroupElement->LinkEndChild(pChildreGroupChoiceElement); - // Add choice members. - for ( AbstractClassRep* pChoiceType = pRootType; pChoiceType != NULL; pChoiceType = pChoiceType->getNextClass() ) - { - // Skip if not derived from the container child class. - if ( !pChoiceType->isClass( pContainerChildClass ) ) - continue; + // Add choice members. + for (AbstractClassRep* pChoiceType = pRootType; pChoiceType != NULL; pChoiceType = pChoiceType->getNextClass()) + { + // Skip if not derived from the container child class. + if (!pChoiceType->isClass(pContainerChildClass)) + continue; - // Add choice member. - TiXmlElement* pChildrenMemberElement = new TiXmlElement( "xs:element" ); - pChildrenMemberElement->SetAttribute( "name", pChoiceType->getClassName() ); - dSprintf( buffer, sizeof(buffer), "%s_Type", pChoiceType->getClassName() ); - pChildrenMemberElement->SetAttribute( "type", buffer ); - pChildreGroupChoiceElement->LinkEndChild( pChildrenMemberElement ); - } + // Add choice member. + TiXmlElement* pChildrenMemberElement = new TiXmlElement("xs:element"); + pChildrenMemberElement->SetAttribute("name", pChoiceType->getClassName()); + dSprintf(buffer, sizeof(buffer), "%s_Type", pChoiceType->getClassName()); + pChildrenMemberElement->SetAttribute("type", buffer); + pChildreGroupChoiceElement->LinkEndChild(pChildrenMemberElement); + } } // Reference the child group. - TiXmlElement* pChoiceGroupReferenceElement = new TiXmlElement( "xs:group" ); - pChoiceGroupReferenceElement->SetAttribute( "ref", childGroupItr->value ); - pChoiceGroupReferenceElement->SetAttribute( "minOccurs", 0 ); - pChoiceElement->LinkEndChild( pChoiceGroupReferenceElement ); - } + TiXmlElement* pChoiceGroupReferenceElement = new TiXmlElement("xs:group"); + pChoiceGroupReferenceElement->SetAttribute("ref", childGroupItr->value); + pChoiceGroupReferenceElement->SetAttribute("minOccurs", 0); + pChoiceElement->LinkEndChild(pChoiceGroupReferenceElement); + } - // Generate the custom Taml schema. - for ( AbstractClassRep* pCustomSchemaType = pType; pCustomSchemaType != NULL; pCustomSchemaType = pCustomSchemaType->getParentClass() ) - { + // Generate the custom Taml schema. + for (AbstractClassRep* pCustomSchemaType = pType; pCustomSchemaType != NULL; pCustomSchemaType = pCustomSchemaType->getParentClass()) + { // Fetch the types custom TAML schema function. AbstractClassRep::WriteCustomTamlSchema customSchemaFn = pCustomSchemaType->getCustomTamlSchema(); // Skip if no function avilable. - if ( customSchemaFn == NULL ) - continue; + if (customSchemaFn == NULL) + continue; // Call schema generation function. - customSchemaFn( pType, pSequenceElement ); - } + customSchemaFn(pType, pSequenceElement); + } - // Generate field attribute group. - TiXmlElement* pFieldAttributeGroupElement = new TiXmlElement( "xs:attributeGroup" ); - dSprintf( buffer, sizeof(buffer), "%s_Fields", pType->getClassName() ); - pFieldAttributeGroupElement->SetAttribute( "name", buffer ); - pSchemaElement->LinkEndChild( pFieldAttributeGroupElement ); + // Generate field attribute group. + TiXmlElement* pFieldAttributeGroupElement = new TiXmlElement("xs:attributeGroup"); + dSprintf(buffer, sizeof(buffer), "%s_Fields", pType->getClassName()); + pFieldAttributeGroupElement->SetAttribute("name", buffer); + pSchemaElement->LinkEndChild(pFieldAttributeGroupElement); - // Fetch field list. - const AbstractClassRep::FieldList& fields = pType->mFieldList; + // Fetch field list. + const AbstractClassRep::FieldList& fields = pType->mFieldList; - // Fetcj field count. - const S32 fieldCount = fields.size(); + // Fetcj field count. + const S32 fieldCount = fields.size(); - // Iterate static fields (in reverse as most types are organized from the root-fields up). - for( S32 index = fieldCount-1; index > 0; --index ) - { + // Iterate static fields (in reverse as most types are organized from the root-fields up). + for (S32 index = fieldCount - 1; index > 0; --index) + { // Fetch field. const AbstractClassRep::Field& field = fields[index]; // Skip if not a data field. - if( field.type == AbstractClassRep::DeprecatedFieldType || - field.type == AbstractClassRep::StartGroupFieldType || - field.type == AbstractClassRep::EndGroupFieldType ) - continue; + if (field.type == AbstractClassRep::DeprecatedFieldType || + field.type == AbstractClassRep::StartGroupFieldType || + field.type == AbstractClassRep::EndGroupFieldType) + continue; // Skip if the field root is not this type. - if ( pType->findFieldRoot( field.pFieldname ) != pType ) - continue; + if (pType->findFieldRoot(field.pFieldname) != pType) + continue; // Add attribute element. - TiXmlElement* pAttributeElement = new TiXmlElement( "xs:attribute" ); - pAttributeElement->SetAttribute( "name", field.pFieldname ); + TiXmlElement* pAttributeElement = new TiXmlElement("xs:attribute"); + pAttributeElement->SetAttribute("name", field.pFieldname); // Handle the console type appropriately. const S32 fieldType = (S32)field.type; @@ -1378,168 +1383,168 @@ bool Taml::generateTamlSchema() // Is the field an enumeration? if ( fieldType == TypeEnum ) { - // Yes, so add attribute type. - TiXmlElement* pAttributeSimpleTypeElement = new TiXmlElement( "xs:simpleType" ); - pAttributeElement->LinkEndChild( pAttributeSimpleTypeElement ); + // Yes, so add attribute type. + TiXmlElement* pAttributeSimpleTypeElement = new TiXmlElement( "xs:simpleType" ); + pAttributeElement->LinkEndChild( pAttributeSimpleTypeElement ); - // Add restriction element. - TiXmlElement* pAttributeRestrictionElement = new TiXmlElement( "xs:restriction" ); - pAttributeRestrictionElement->SetAttribute( "base", "xs:string" ); - pAttributeSimpleTypeElement->LinkEndChild( pAttributeRestrictionElement ); + // Add restriction element. + TiXmlElement* pAttributeRestrictionElement = new TiXmlElement( "xs:restriction" ); + pAttributeRestrictionElement->SetAttribute( "base", "xs:string" ); + pAttributeSimpleTypeElement->LinkEndChild( pAttributeRestrictionElement ); - // Yes, so fetch enumeration count. - const S32 enumCount = field.table->size; + // Yes, so fetch enumeration count. + const S32 enumCount = field.table->size; - // Iterate enumeration. - for( S32 index = 0; index < enumCount; ++index ) - { - // Add enumeration element. - TiXmlElement* pAttributeEnumerationElement = new TiXmlElement( "xs:enumeration" ); - pAttributeEnumerationElement->SetAttribute( "value", field.table->table[index].label ); - pAttributeRestrictionElement->LinkEndChild( pAttributeEnumerationElement ); - } + // Iterate enumeration. + for( S32 index = 0; index < enumCount; ++index ) + { + // Add enumeration element. + TiXmlElement* pAttributeEnumerationElement = new TiXmlElement( "xs:enumeration" ); + pAttributeEnumerationElement->SetAttribute( "value", field.table->table[index].label ); + pAttributeRestrictionElement->LinkEndChild( pAttributeEnumerationElement ); + } } else {*/ - // No, so assume it's a string type initially. - const char* pFieldTypeDescription = "xs:string"; + // No, so assume it's a string type initially. + const char* pFieldTypeDescription = "xs:string"; - // Handle known types. - if( fieldType == TypeF32 ) - { - pFieldTypeDescription = "xs:float"; - } - else if( fieldType == TypeS8 || fieldType == TypeS32 ) - { - pFieldTypeDescription = "xs:int"; - } - else if( fieldType == TypeBool || fieldType == TypeFlag ) - { - pFieldTypeDescription = "xs:boolean"; - } - else if( fieldType == TypePoint2F ) - { - pFieldTypeDescription = "Point2F_ConsoleType"; - } - else if( fieldType == TypePoint2I ) - { - pFieldTypeDescription = "Point2I_ConsoleType"; - } - else if( fieldType == TypeRectI ) - { - pFieldTypeDescription = "RectI_ConsoleType"; - } - else if( fieldType == TypeRectF ) - { - pFieldTypeDescription = "RectF_ConsoleType"; - } - else if( fieldType == TypeColorF ) - { - pFieldTypeDescription = "ColorF_ConsoleType"; - } - else if( fieldType == TypeColorI ) - { - pFieldTypeDescription = "ColorI_ConsoleType"; - } - else if (fieldType == TypeAssetId/* || - fieldType == TypeImageAssetPtr || - fieldType == TypeAnimationAssetPtr || - fieldType == TypeAudioAssetPtr*/) - { - pFieldTypeDescription = "AssetId_ConsoleType"; - } + // Handle known types. + if (fieldType == TypeF32) + { + pFieldTypeDescription = "xs:float"; + } + else if (fieldType == TypeS8 || fieldType == TypeS32) + { + pFieldTypeDescription = "xs:int"; + } + else if (fieldType == TypeBool || fieldType == TypeFlag) + { + pFieldTypeDescription = "xs:boolean"; + } + else if (fieldType == TypePoint2F) + { + pFieldTypeDescription = "Point2F_ConsoleType"; + } + else if (fieldType == TypePoint2I) + { + pFieldTypeDescription = "Point2I_ConsoleType"; + } + else if (fieldType == TypeRectI) + { + pFieldTypeDescription = "RectI_ConsoleType"; + } + else if (fieldType == TypeRectF) + { + pFieldTypeDescription = "RectF_ConsoleType"; + } + else if (fieldType == TypeColorF) + { + pFieldTypeDescription = "ColorF_ConsoleType"; + } + else if (fieldType == TypeColorI) + { + pFieldTypeDescription = "ColorI_ConsoleType"; + } + else if (fieldType == TypeAssetId/* || + fieldType == TypeImageAssetPtr || + fieldType == TypeAnimationAssetPtr || + fieldType == TypeAudioAssetPtr*/) + { + pFieldTypeDescription = "AssetId_ConsoleType"; + } - // Set attribute type. - pAttributeElement->SetAttribute( "type", pFieldTypeDescription ); + // Set attribute type. + pAttributeElement->SetAttribute("type", pFieldTypeDescription); //} - pAttributeElement->SetAttribute( "use", "optional" ); - pFieldAttributeGroupElement->LinkEndChild( pAttributeElement ); - } + pAttributeElement->SetAttribute("use", "optional"); + pFieldAttributeGroupElement->LinkEndChild(pAttributeElement); + } - // Is this the SimObject Type? - if ( pType == pSimObjectType ) - { + // Is this the SimObject Type? + if (pType == pSimObjectType) + { // Yes, so add reserved Taml field attributes here... // Add Taml "Name" attribute element. - TiXmlElement* pNameAttributeElement = new TiXmlElement( "xs:attribute" ); - pNameAttributeElement->SetAttribute( "name", tamlNamedObjectName ); - pNameAttributeElement->SetAttribute( "type", "xs:normalizedString" ); - pFieldAttributeGroupElement->LinkEndChild( pNameAttributeElement ); + TiXmlElement* pNameAttributeElement = new TiXmlElement("xs:attribute"); + pNameAttributeElement->SetAttribute("name", tamlNamedObjectName); + pNameAttributeElement->SetAttribute("type", "xs:normalizedString"); + pFieldAttributeGroupElement->LinkEndChild(pNameAttributeElement); // Add Taml "TamlId" attribute element. - TiXmlElement* pTamlIdAttributeElement = new TiXmlElement( "xs:attribute" ); - pTamlIdAttributeElement->SetAttribute( "name", tamlRefIdName ); - pTamlIdAttributeElement->SetAttribute( "type", "xs:nonNegativeInteger" ); - pFieldAttributeGroupElement->LinkEndChild( pTamlIdAttributeElement ); + TiXmlElement* pTamlIdAttributeElement = new TiXmlElement("xs:attribute"); + pTamlIdAttributeElement->SetAttribute("name", tamlRefIdName); + pTamlIdAttributeElement->SetAttribute("type", "xs:nonNegativeInteger"); + pFieldAttributeGroupElement->LinkEndChild(pTamlIdAttributeElement); // Add Taml "TamlRefId" attribute element. - TiXmlElement* pTamlRefIdAttributeElement = new TiXmlElement( "xs:attribute" ); - pTamlRefIdAttributeElement->SetAttribute( "name", tamlRefToIdName ); - pTamlRefIdAttributeElement->SetAttribute( "type", "xs:nonNegativeInteger" ); - pFieldAttributeGroupElement->LinkEndChild( pTamlRefIdAttributeElement ); - } + TiXmlElement* pTamlRefIdAttributeElement = new TiXmlElement("xs:attribute"); + pTamlRefIdAttributeElement->SetAttribute("name", tamlRefToIdName); + pTamlRefIdAttributeElement->SetAttribute("type", "xs:nonNegativeInteger"); + pFieldAttributeGroupElement->LinkEndChild(pTamlRefIdAttributeElement); + } - // Add attribute group types. - for ( AbstractClassRep* pAttributeGroupsType = pType; pAttributeGroupsType != NULL; pAttributeGroupsType = pAttributeGroupsType->getParentClass() ) - { - TiXmlElement* pFieldAttributeGroupRefElement = new TiXmlElement( "xs:attributeGroup" ); - dSprintf( buffer, sizeof(buffer), "%s_Fields", pAttributeGroupsType->getClassName() ); - pFieldAttributeGroupRefElement->SetAttribute( "ref", buffer ); - pComplexTypeElement->LinkEndChild( pFieldAttributeGroupRefElement ); - } + // Add attribute group types. + for (AbstractClassRep* pAttributeGroupsType = pType; pAttributeGroupsType != NULL; pAttributeGroupsType = pAttributeGroupsType->getParentClass()) + { + TiXmlElement* pFieldAttributeGroupRefElement = new TiXmlElement("xs:attributeGroup"); + dSprintf(buffer, sizeof(buffer), "%s_Fields", pAttributeGroupsType->getClassName()); + pFieldAttributeGroupRefElement->SetAttribute("ref", buffer); + pComplexTypeElement->LinkEndChild(pFieldAttributeGroupRefElement); + } - // Add "any" attribute element (dynamic fields). - TiXmlElement* pAnyAttributeElement = new TiXmlElement( "xs:anyAttribute" ); - pAnyAttributeElement->SetAttribute( "processContents", "skip" ); - pComplexTypeElement->LinkEndChild( pAnyAttributeElement ); - } + // Add "any" attribute element (dynamic fields). + TiXmlElement* pAnyAttributeElement = new TiXmlElement("xs:anyAttribute"); + pAnyAttributeElement->SetAttribute("processContents", "skip"); + pComplexTypeElement->LinkEndChild(pAnyAttributeElement); + } - // Write the schema document. - schemaDocument.SaveFile( filePathBuffer ); + // Write the schema document. + schemaDocument.SaveFile(filePathBuffer); - // Close file. - stream.close(); + // Close file. + stream.close(); - return true; -} + return true; + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -void Taml::WriteUnrestrictedCustomTamlSchema( const char* pCustomNodeName, const AbstractClassRep* pClassRep, TiXmlElement* pParentElement ) -{ - // Sanity! - AssertFatal( pCustomNodeName != NULL, "Taml::WriteDefaultCustomTamlSchema() - Node name cannot be NULL." ); - AssertFatal( pClassRep != NULL, "Taml::WriteDefaultCustomTamlSchema() - ClassRep cannot be NULL." ); - AssertFatal( pParentElement != NULL, "Taml::WriteDefaultCustomTamlSchema() - Parent Element cannot be NULL." ); + void Taml::WriteUnrestrictedCustomTamlSchema(const char* pCustomNodeName, const AbstractClassRep* pClassRep, TiXmlElement* pParentElement) + { + // Sanity! + AssertFatal(pCustomNodeName != NULL, "Taml::WriteDefaultCustomTamlSchema() - Node name cannot be NULL."); + AssertFatal(pClassRep != NULL, "Taml::WriteDefaultCustomTamlSchema() - ClassRep cannot be NULL."); + AssertFatal(pParentElement != NULL, "Taml::WriteDefaultCustomTamlSchema() - Parent Element cannot be NULL."); - char buffer[1024]; + char buffer[1024]; - // Add custom type element. - TiXmlElement* pCustomElement = new TiXmlElement( "xs:element" ); - dSprintf( buffer, sizeof(buffer), "%s.%s", pClassRep->getClassName(), pCustomNodeName ); - pCustomElement->SetAttribute( "name", buffer ); - pCustomElement->SetAttribute( "minOccurs", 0 ); - pCustomElement->SetAttribute( "maxOccurs", 1 ); - pParentElement->LinkEndChild( pCustomElement ); + // Add custom type element. + TiXmlElement* pCustomElement = new TiXmlElement("xs:element"); + dSprintf(buffer, sizeof(buffer), "%s.%s", pClassRep->getClassName(), pCustomNodeName); + pCustomElement->SetAttribute("name", buffer); + pCustomElement->SetAttribute("minOccurs", 0); + pCustomElement->SetAttribute("maxOccurs", 1); + pParentElement->LinkEndChild(pCustomElement); - // Add complex type element. - TiXmlElement* pComplexTypeElement = new TiXmlElement( "xs:complexType" ); - pCustomElement->LinkEndChild( pComplexTypeElement ); + // Add complex type element. + TiXmlElement* pComplexTypeElement = new TiXmlElement("xs:complexType"); + pCustomElement->LinkEndChild(pComplexTypeElement); - // Add choice element. - TiXmlElement* pChoiceElement = new TiXmlElement( "xs:choice" ); - pChoiceElement->SetAttribute( "minOccurs", 0 ); - pChoiceElement->SetAttribute( "maxOccurs", "unbounded" ); - pComplexTypeElement->LinkEndChild( pChoiceElement ); + // Add choice element. + TiXmlElement* pChoiceElement = new TiXmlElement("xs:choice"); + pChoiceElement->SetAttribute("minOccurs", 0); + pChoiceElement->SetAttribute("maxOccurs", "unbounded"); + pComplexTypeElement->LinkEndChild(pChoiceElement); - // Add sequence element. - TiXmlElement* pSequenceElement = new TiXmlElement( "xs:sequence" ); - pChoiceElement->LinkEndChild( pSequenceElement ); + // Add sequence element. + TiXmlElement* pSequenceElement = new TiXmlElement("xs:sequence"); + pChoiceElement->LinkEndChild(pSequenceElement); - // Add "any" element. - TiXmlElement* pAnyElement = new TiXmlElement( "xs:any" ); - pAnyElement->SetAttribute( "processContents", "skip" ); - pSequenceElement->LinkEndChild( pAnyElement ); -} + // Add "any" element. + TiXmlElement* pAnyElement = new TiXmlElement("xs:any"); + pAnyElement->SetAttribute("processContents", "skip"); + pSequenceElement->LinkEndChild(pAnyElement); + } \ No newline at end of file