|
@@ -42,17 +42,17 @@
|
|
|
#include "persistence/taml/binary/tamlBinaryReader.h"
|
|
|
#endif
|
|
|
|
|
|
-/*#ifndef _TAML_JSONWRITER_H_
|
|
|
-#include "taml/json/tamlJSONWriter.h"
|
|
|
+#ifndef _TAML_JSONWRITER_H_
|
|
|
+#include "persistence/taml/json/tamlJSONWriter.h"
|
|
|
#endif
|
|
|
|
|
|
#ifndef _TAML_JSONREADER_H_
|
|
|
-#include "taml/json/tamlJSONReader.h"
|
|
|
+#include "persistence/taml/json/tamlJSONReader.h"
|
|
|
#endif
|
|
|
|
|
|
#ifndef _TAML_JSONPARSER_H_
|
|
|
-#include "taml/json/tamlJSONParser.h"
|
|
|
-#endif*/
|
|
|
+#include "persistence/taml/json/tamlJSONParser.h"
|
|
|
+#endif
|
|
|
|
|
|
#ifndef _FRAMEALLOCATOR_H_
|
|
|
#include "core/frameAllocator.h"
|
|
@@ -94,1587 +94,1582 @@ StringTableEntry tamlNamedObjectName = StringTable->insert("Name");
|
|
|
|
|
|
typedef Taml::TamlFormatMode _TamlFormatMode;
|
|
|
ImplementEnumType(_TamlFormatMode,
|
|
|
- "")
|
|
|
-{
|
|
|
- Taml::XmlFormat, "xml"
|
|
|
-},
|
|
|
-{ Taml::BinaryFormat, "binary" }//,
|
|
|
- //{ Taml::JSONFormat, "json" }
|
|
|
- EndImplementEnumType;
|
|
|
+"")
|
|
|
+ { Taml::XmlFormat, "xml" },
|
|
|
+ { Taml::BinaryFormat, "binary" },
|
|
|
+ { Taml::JSONFormat, "json" }
|
|
|
+EndImplementEnumType;
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- Taml::TamlFormatMode Taml::getFormatModeEnum(const char* label)
|
|
|
+Taml::TamlFormatMode Taml::getFormatModeEnum(const char* label)
|
|
|
+{
|
|
|
+ // Search for Mnemonic.
|
|
|
+ for (U32 i = 0; i < (sizeof(__TamlFormatMode::_sEnums) / sizeof(EnumTable::Value)); i++)
|
|
|
{
|
|
|
- // 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();
|
|
|
- }
|
|
|
+ if (dStricmp(__TamlFormatMode::_sEnumTable[i].getName(), label) == 0)
|
|
|
+ return (TamlFormatMode)__TamlFormatMode::_sEnumTable[i].getInt();
|
|
|
+ }
|
|
|
|
|
|
- // Warn.
|
|
|
- Con::warnf("Taml::getFormatModeEnum() - Invalid format of '%s'.", label);
|
|
|
+ // Warn.
|
|
|
+ Con::warnf("Taml::getFormatModeEnum() - Invalid format of '%s'.", label);
|
|
|
|
|
|
- return Taml::InvalidFormat;
|
|
|
- }
|
|
|
+ return Taml::InvalidFormat;
|
|
|
+}
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- const char* Taml::getFormatModeDescription(const Taml::TamlFormatMode formatMode)
|
|
|
+const char* Taml::getFormatModeDescription(const Taml::TamlFormatMode formatMode)
|
|
|
+{
|
|
|
+ // Search for Mnemonic.
|
|
|
+ for (U32 i = 0; i < (sizeof(__TamlFormatMode::_sEnums) / sizeof(EnumTable::Value)); i++)
|
|
|
{
|
|
|
- // 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();
|
|
|
- }
|
|
|
+ if (__TamlFormatMode::_sEnumTable[i].getInt() == (S32)formatMode)
|
|
|
+ return __TamlFormatMode::_sEnumTable[i].getName();
|
|
|
+ }
|
|
|
|
|
|
- // Warn.
|
|
|
- Con::warnf("Taml::getFormatModeDescription() - Invalid format mode.");
|
|
|
+ // Warn.
|
|
|
+ Con::warnf("Taml::getFormatModeDescription() - Invalid format mode.");
|
|
|
|
|
|
- return StringTable->EmptyString();
|
|
|
- }
|
|
|
+ return StringTable->EmptyString();
|
|
|
+}
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
-
|
|
|
- // 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() :
|
|
|
- mMasterNodeId(0),
|
|
|
- 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;
|
|
|
- }
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+// 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() :
|
|
|
+ mMasterNodeId(0),
|
|
|
+ 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;
|
|
|
+}
|
|
|
|
|
|
- void Taml::initPersistFields()
|
|
|
- {
|
|
|
- docsURL;
|
|
|
- // Call parent.
|
|
|
- Parent::initPersistFields();
|
|
|
-
|
|
|
- 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()
|
|
|
+{
|
|
|
+ docsURL;
|
|
|
+ // Call parent.
|
|
|
+ Parent::initPersistFields();
|
|
|
+
|
|
|
+ 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");
|
|
|
+}
|
|
|
|
|
|
- bool Taml::onAdd()
|
|
|
- {
|
|
|
- // Call parent.
|
|
|
- if (!Parent::onAdd())
|
|
|
- return false;
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // Set JSON strict mode.
|
|
|
- mJSONStrict = Con::getBoolVariable(TAML_JSON_STRICT_VARIBLE, true);
|
|
|
+bool Taml::onAdd()
|
|
|
+{
|
|
|
+ // Call parent.
|
|
|
+ if (!Parent::onAdd())
|
|
|
+ return false;
|
|
|
|
|
|
- // Reset the compilation.
|
|
|
- resetCompilation();
|
|
|
+ // Set JSON strict mode.
|
|
|
+ mJSONStrict = Con::getBoolVariable(TAML_JSON_STRICT_VARIBLE, true);
|
|
|
|
|
|
- return true;
|
|
|
- }
|
|
|
+ // Reset the compilation.
|
|
|
+ resetCompilation();
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+ return true;
|
|
|
+}
|
|
|
|
|
|
- void Taml::onRemove()
|
|
|
- {
|
|
|
- // Reset the compilation.
|
|
|
- resetCompilation();
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // Call parent.
|
|
|
- Parent::onRemove();
|
|
|
- }
|
|
|
+void Taml::onRemove()
|
|
|
+{
|
|
|
+ // Reset the compilation.
|
|
|
+ resetCompilation();
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+ // Call parent.
|
|
|
+ Parent::onRemove();
|
|
|
+}
|
|
|
|
|
|
- bool Taml::write(SimObject* pSimObject, const char* pFilename)
|
|
|
- {
|
|
|
- // Debug Profiling.
|
|
|
- PROFILE_SCOPE(Taml_Write);
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // Sanity!
|
|
|
- AssertFatal(pSimObject != NULL, "Cannot write a NULL object.");
|
|
|
- AssertFatal(pFilename != NULL, "Cannot write to a NULL filename.");
|
|
|
+bool Taml::write(SimObject* pSimObject, const char* pFilename)
|
|
|
+{
|
|
|
+ // Debug Profiling.
|
|
|
+ PROFILE_SCOPE(Taml_Write);
|
|
|
+
|
|
|
+ // 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 unless we're a secure VFS
|
|
|
+ // Expand the file-name into the file-path buffer unless we're a secure VFS
|
|
|
#ifndef TORQUE_SECURE_VFS
|
|
|
- Con::expandToolScriptFilename(mFilePathBuffer, sizeof(mFilePathBuffer), pFilename);
|
|
|
+ Con::expandToolScriptFilename(mFilePathBuffer, sizeof(mFilePathBuffer), pFilename);
|
|
|
#else
|
|
|
- dMemset(mFilePathBuffer, 0x00, sizeof(mFilePathBuffer));
|
|
|
- dMemcpy(mFilePathBuffer, pFilename, dStrlen(pFilename));
|
|
|
+ dMemset(mFilePathBuffer, 0x00, sizeof(mFilePathBuffer));
|
|
|
+ dMemcpy(mFilePathBuffer, pFilename, dStrlen(pFilename));
|
|
|
#endif
|
|
|
|
|
|
- FileStream stream;
|
|
|
+ FileStream stream;
|
|
|
|
|
|
- // 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;
|
|
|
- }
|
|
|
-
|
|
|
- // Get the file auto-format mode.
|
|
|
- const TamlFormatMode formatMode = getFileAutoFormatMode(mFilePathBuffer);
|
|
|
+ // 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;
|
|
|
+ }
|
|
|
|
|
|
- // Reset the compilation.
|
|
|
- resetCompilation();
|
|
|
+ // Get the file auto-format mode.
|
|
|
+ const TamlFormatMode formatMode = getFileAutoFormatMode(mFilePathBuffer);
|
|
|
|
|
|
- // Write object.
|
|
|
- const bool status = write(stream, pSimObject, formatMode);
|
|
|
+ // Reset the compilation.
|
|
|
+ resetCompilation();
|
|
|
|
|
|
- // Close file.
|
|
|
- stream.close();
|
|
|
+ // Write object.
|
|
|
+ const bool status = write(stream, pSimObject, formatMode);
|
|
|
|
|
|
- // Reset the compilation.
|
|
|
- resetCompilation();
|
|
|
+ // Close file.
|
|
|
+ stream.close();
|
|
|
|
|
|
- return status;
|
|
|
- }
|
|
|
+ // Reset the compilation.
|
|
|
+ resetCompilation();
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+ return status;
|
|
|
+}
|
|
|
|
|
|
- SimObject* Taml::read(const char* pFilename)
|
|
|
- {
|
|
|
- // Debug Profiling.
|
|
|
- PROFILE_SCOPE(Taml_Read);
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // Sanity!
|
|
|
- AssertFatal(pFilename != NULL, "Cannot read from a NULL filename.");
|
|
|
+SimObject* Taml::read(const char* pFilename)
|
|
|
+{
|
|
|
+ // Debug Profiling.
|
|
|
+ PROFILE_SCOPE(Taml_Read);
|
|
|
|
|
|
- // Expand the file-name into the file-path buffer.
|
|
|
- Con::expandScriptFilename(mFilePathBuffer, sizeof(mFilePathBuffer), pFilename);
|
|
|
+ // Sanity!
|
|
|
+ AssertFatal(pFilename != NULL, "Cannot read from a NULL filename.");
|
|
|
|
|
|
- FileStream stream;
|
|
|
+ // Expand the file-name into the file-path buffer.
|
|
|
+ Con::expandScriptFilename(mFilePathBuffer, sizeof(mFilePathBuffer), pFilename);
|
|
|
|
|
|
- // 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;
|
|
|
- }
|
|
|
+ FileStream stream;
|
|
|
|
|
|
- // Get the file auto-format mode.
|
|
|
- const TamlFormatMode formatMode = getFileAutoFormatMode(mFilePathBuffer);
|
|
|
+ // 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;
|
|
|
+ }
|
|
|
|
|
|
- // Reset the compilation.
|
|
|
- resetCompilation();
|
|
|
+ // Get the file auto-format mode.
|
|
|
+ const TamlFormatMode formatMode = getFileAutoFormatMode(mFilePathBuffer);
|
|
|
|
|
|
- // Write object.
|
|
|
- SimObject* pSimObject = read(stream, formatMode);
|
|
|
+ // Reset the compilation.
|
|
|
+ resetCompilation();
|
|
|
|
|
|
- // Close file.
|
|
|
- stream.close();
|
|
|
+ // Write object.
|
|
|
+ SimObject* pSimObject = read(stream, formatMode);
|
|
|
|
|
|
- // Reset the compilation.
|
|
|
- resetCompilation();
|
|
|
+ // Close file.
|
|
|
+ stream.close();
|
|
|
|
|
|
- // 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();
|
|
|
- }
|
|
|
+ // Reset the compilation.
|
|
|
+ resetCompilation();
|
|
|
|
|
|
- return pSimObject;
|
|
|
+ // 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();
|
|
|
}
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+ return pSimObject;
|
|
|
+}
|
|
|
|
|
|
- bool Taml::write(FileStream& stream, SimObject* pSimObject, const TamlFormatMode formatMode)
|
|
|
- {
|
|
|
- // Sanity!
|
|
|
- AssertFatal(pSimObject != NULL, "Cannot write a NULL object.");
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // Compile nodes.
|
|
|
- TamlWriteNode* pRootNode = compileObject(pSimObject);
|
|
|
+bool Taml::write(FileStream& stream, SimObject* pSimObject, const TamlFormatMode formatMode)
|
|
|
+{
|
|
|
+ // Sanity!
|
|
|
+ AssertFatal(pSimObject != NULL, "Cannot write a NULL object.");
|
|
|
|
|
|
- // Format appropriately.
|
|
|
- switch (formatMode)
|
|
|
- {
|
|
|
- /// Xml.
|
|
|
- case XmlFormat:
|
|
|
- {
|
|
|
- // Create writer.
|
|
|
- TamlXmlWriter writer(this);
|
|
|
- // Write.
|
|
|
- return writer.write(stream, pRootNode);
|
|
|
- }
|
|
|
+ // Compile nodes.
|
|
|
+ TamlWriteNode* pRootNode = compileObject(pSimObject);
|
|
|
|
|
|
- /// Binary.
|
|
|
- case BinaryFormat:
|
|
|
- {
|
|
|
- // Create writer.
|
|
|
- TamlBinaryWriter writer(this);
|
|
|
+ // Format appropriately.
|
|
|
+ switch (formatMode)
|
|
|
+ {
|
|
|
+ /// Xml.
|
|
|
+ case XmlFormat:
|
|
|
+ {
|
|
|
+ // Create writer.
|
|
|
+ TamlXmlWriter writer(this);
|
|
|
+ // Write.
|
|
|
+ return writer.write(stream, pRootNode);
|
|
|
+ }
|
|
|
|
|
|
- // Write.
|
|
|
- return writer.write(stream, pRootNode, mBinaryCompression);
|
|
|
- }
|
|
|
+ /// Binary.
|
|
|
+ case BinaryFormat:
|
|
|
+ {
|
|
|
+ // Create writer.
|
|
|
+ TamlBinaryWriter writer(this);
|
|
|
|
|
|
- /// JSON.
|
|
|
- case JSONFormat:
|
|
|
- {
|
|
|
- // Create writer.
|
|
|
- //TamlJSONWriter writer( this );
|
|
|
+ // Write.
|
|
|
+ return writer.write(stream, pRootNode, mBinaryCompression);
|
|
|
+ }
|
|
|
|
|
|
- // Write.
|
|
|
- //return writer.write( stream, pRootNode );
|
|
|
- return false;
|
|
|
- }
|
|
|
+ /// JSON.
|
|
|
+ case JSONFormat:
|
|
|
+ {
|
|
|
+ // Create writer.
|
|
|
+ TamlJSONWriter writer( this );
|
|
|
|
|
|
- /// Invalid.
|
|
|
- case InvalidFormat:
|
|
|
- {
|
|
|
- // Warn.
|
|
|
- Con::warnf("Taml::write() - Cannot write, invalid format.");
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
+ // Write.
|
|
|
+ return writer.write( stream, pRootNode );
|
|
|
+ }
|
|
|
|
|
|
+ /// Invalid.
|
|
|
+ case InvalidFormat:
|
|
|
+ {
|
|
|
// Warn.
|
|
|
- Con::warnf("Taml::write() - Unknown format.");
|
|
|
+ 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);
|
|
|
- }
|
|
|
+SimObject* Taml::read(FileStream& stream, const TamlFormatMode formatMode)
|
|
|
+{
|
|
|
+ // Format appropriately.
|
|
|
+ switch (formatMode)
|
|
|
+ {
|
|
|
+ /// Xml.
|
|
|
+ case XmlFormat:
|
|
|
+ {
|
|
|
+ // Create reader.
|
|
|
+ TamlXmlReader reader(this);
|
|
|
|
|
|
- /// Binary.
|
|
|
- case BinaryFormat:
|
|
|
- {
|
|
|
- // Create reader.
|
|
|
- TamlBinaryReader reader(this);
|
|
|
+ // Read.
|
|
|
+ return reader.read(stream);
|
|
|
+ }
|
|
|
|
|
|
- // Read.
|
|
|
- return reader.read(stream);
|
|
|
- }
|
|
|
+ /// Binary.
|
|
|
+ case BinaryFormat:
|
|
|
+ {
|
|
|
+ // Create reader.
|
|
|
+ TamlBinaryReader reader(this);
|
|
|
|
|
|
- /// JSON.
|
|
|
- case JSONFormat:
|
|
|
- {
|
|
|
- // Create reader.
|
|
|
- //TamlJSONReader reader( this );
|
|
|
+ // Read.
|
|
|
+ return reader.read(stream);
|
|
|
+ }
|
|
|
|
|
|
- // Read.
|
|
|
- //return reader.read( stream );
|
|
|
- return NULL;
|
|
|
- }
|
|
|
+ /// JSON.
|
|
|
+ case JSONFormat:
|
|
|
+ {
|
|
|
+ // Create reader.
|
|
|
+ TamlJSONReader reader( this );
|
|
|
|
|
|
- /// Invalid.
|
|
|
- case InvalidFormat:
|
|
|
- {
|
|
|
- // Warn.
|
|
|
- Con::warnf("Taml::read() - Cannot read, invalid format.");
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- }
|
|
|
+ // Read.
|
|
|
+ return reader.read( stream );
|
|
|
+ }
|
|
|
|
|
|
+ /// Invalid.
|
|
|
+ case InvalidFormat:
|
|
|
+ {
|
|
|
// Warn.
|
|
|
- Con::warnf("Taml::read() - Unknown format.");
|
|
|
+ Con::warnf("Taml::read() - Cannot read, invalid format.");
|
|
|
return NULL;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
-
|
|
|
- bool Taml::parse(const char* pFilename, TamlVisitor& visitor)
|
|
|
- {
|
|
|
- // Debug Profiling.
|
|
|
- PROFILE_SCOPE(Taml_Parse);
|
|
|
+ // Warn.
|
|
|
+ Con::warnf("Taml::read() - Unknown format.");
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
|
|
|
- // Sanity!
|
|
|
- AssertFatal(pFilename != NULL, "Taml::parse() - Cannot parse a NULL filename.");
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // Fetch format mode.
|
|
|
- const TamlFormatMode formatMode = getFileAutoFormatMode(pFilename);
|
|
|
+bool Taml::parse(const char* pFilename, TamlVisitor& visitor)
|
|
|
+{
|
|
|
+ // Debug Profiling.
|
|
|
+ PROFILE_SCOPE(Taml_Parse);
|
|
|
|
|
|
- // Handle format mode appropriately.
|
|
|
- switch (formatMode)
|
|
|
- {
|
|
|
- case XmlFormat:
|
|
|
- {
|
|
|
- // Parse with the visitor.
|
|
|
- TamlXmlParser parser;
|
|
|
+ // Sanity!
|
|
|
+ AssertFatal(pFilename != NULL, "Taml::parse() - Cannot parse a NULL filename.");
|
|
|
|
|
|
- // 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 format mode.
|
|
|
+ const TamlFormatMode formatMode = getFileAutoFormatMode(pFilename);
|
|
|
|
|
|
- return parser.accept(pFilename, visitor);
|
|
|
- }
|
|
|
+ // Handle format mode appropriately.
|
|
|
+ switch (formatMode)
|
|
|
+ {
|
|
|
+ case XmlFormat:
|
|
|
+ {
|
|
|
+ // Parse with the visitor.
|
|
|
+ TamlXmlParser parser;
|
|
|
|
|
|
- case JSONFormat:
|
|
|
+ // Are property changes needed but not supported?
|
|
|
+ if (visitor.wantsPropertyChanges() && !parser.canChangeProperty())
|
|
|
{
|
|
|
- // Parse with the visitor.
|
|
|
- /*TamlJSONParser 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 );
|
|
|
+ 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;
|
|
|
- }
|
|
|
-
|
|
|
- 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;
|
|
|
+ return parser.accept(pFilename, visitor);
|
|
|
}
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
-
|
|
|
- void Taml::resetCompilation(void)
|
|
|
+ case JSONFormat:
|
|
|
{
|
|
|
- // Debug Profiling.
|
|
|
- PROFILE_SCOPE(Taml_ResetCompilation);
|
|
|
+ // Parse with the visitor.
|
|
|
+ TamlJSONParser parser;
|
|
|
|
|
|
- // Clear compiled nodes.
|
|
|
- for (typeNodeVector::iterator itr = mCompiledNodes.begin(); itr != mCompiledNodes.end(); ++itr)
|
|
|
+ // Are property changes needed but not supported?
|
|
|
+ if ( visitor.wantsPropertyChanges() && !parser.canChangeProperty() )
|
|
|
{
|
|
|
- // Fetch node.
|
|
|
- TamlWriteNode* pNode = (*itr);
|
|
|
-
|
|
|
- // Reset node.
|
|
|
- pNode->resetNode();
|
|
|
-
|
|
|
- // Delete node.
|
|
|
- delete pNode;
|
|
|
+ // 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;
|
|
|
}
|
|
|
- mCompiledNodes.clear();
|
|
|
|
|
|
- // Clear compiled objects.
|
|
|
- mCompiledObjects.clear();
|
|
|
+ return parser.accept( pFilename, visitor );
|
|
|
+ }
|
|
|
|
|
|
- // Reset master node Id.
|
|
|
- mMasterNodeId = 0;
|
|
|
+ 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;
|
|
|
+}
|
|
|
|
|
|
- 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);
|
|
|
+void Taml::resetCompilation(void)
|
|
|
+{
|
|
|
+ // Debug Profiling.
|
|
|
+ PROFILE_SCOPE(Taml_ResetCompilation);
|
|
|
|
|
|
- // Fetch filename length.
|
|
|
- const U32 filenameLength = dStrlen(pFilename);
|
|
|
+ // Clear compiled nodes.
|
|
|
+ for (typeNodeVector::iterator itr = mCompiledNodes.begin(); itr != mCompiledNodes.end(); ++itr)
|
|
|
+ {
|
|
|
+ // Fetch node.
|
|
|
+ TamlWriteNode* pNode = (*itr);
|
|
|
|
|
|
- // Fetch end of filename,
|
|
|
- const char* pEndOfFilename = pFilename + filenameLength;
|
|
|
+ // Reset node.
|
|
|
+ pNode->resetNode();
|
|
|
|
|
|
- // Check for the XML format.
|
|
|
- if (xmlExtensionLength <= filenameLength && dStricmp(pEndOfFilename - xmlExtensionLength, mAutoFormatXmlExtension) == 0)
|
|
|
- return Taml::XmlFormat;
|
|
|
+ // Delete node.
|
|
|
+ delete pNode;
|
|
|
+ }
|
|
|
+ mCompiledNodes.clear();
|
|
|
|
|
|
- // Check for the Binary format.
|
|
|
- if (binaryExtensionLength <= filenameLength && dStricmp(pEndOfFilename - xmlExtensionLength, mAutoFormatBinaryExtension) == 0)
|
|
|
- return Taml::BinaryFormat;
|
|
|
+ // Clear compiled objects.
|
|
|
+ mCompiledObjects.clear();
|
|
|
|
|
|
- // Check for the XML format.
|
|
|
- if (jsonExtensionLength <= filenameLength && dStricmp(pEndOfFilename - jsonExtensionLength, mAutoFormatJSONExtension) == 0)
|
|
|
- return Taml::JSONFormat;
|
|
|
- }
|
|
|
+ // Reset master node Id.
|
|
|
+ mMasterNodeId = 0;
|
|
|
+}
|
|
|
|
|
|
- // Use the explicitly specified format mode.
|
|
|
- return mFormatMode;
|
|
|
- }
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+Taml::TamlFormatMode Taml::getFileAutoFormatMode(const char* pFilename)
|
|
|
+{
|
|
|
+ // Sanity!
|
|
|
+ AssertFatal(pFilename != NULL, "Taml::getFileAutoFormatMode() - Cannot auto-format using a NULL filename.");
|
|
|
|
|
|
- TamlWriteNode* Taml::compileObject(SimObject* pSimObject, const bool forceId)
|
|
|
+ // Is auto-format active?
|
|
|
+ if (mAutoFormat)
|
|
|
{
|
|
|
- // Debug Profiling.
|
|
|
- PROFILE_SCOPE(Taml_CompileObject);
|
|
|
+ // Yes, so fetch the extension lengths.
|
|
|
+ const U32 xmlExtensionLength = dStrlen(mAutoFormatXmlExtension);
|
|
|
+ const U32 binaryExtensionLength = dStrlen(mAutoFormatBinaryExtension);
|
|
|
+ const U32 jsonExtensionLength = dStrlen(mAutoFormatJSONExtension);
|
|
|
|
|
|
- // Sanity!
|
|
|
- AssertFatal(pSimObject != NULL, "Taml::compileObject() - Cannot compile a NULL object.");
|
|
|
+ // Fetch filename length.
|
|
|
+ const U32 filenameLength = dStrlen(pFilename);
|
|
|
|
|
|
- // Fetch object Id.
|
|
|
- const SimObjectId objectId = pSimObject->getId();
|
|
|
+ // Fetch end of filename,
|
|
|
+ const char* pEndOfFilename = pFilename + filenameLength;
|
|
|
|
|
|
- // Find a previously compiled node.
|
|
|
- typeCompiledHash::Iterator compiledItr = mCompiledObjects.find(objectId);
|
|
|
+ // Check for the XML format.
|
|
|
+ if (xmlExtensionLength <= filenameLength && dStricmp(pEndOfFilename - xmlExtensionLength, mAutoFormatXmlExtension) == 0)
|
|
|
+ return Taml::XmlFormat;
|
|
|
|
|
|
- // 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.");
|
|
|
+ // Check for the Binary format.
|
|
|
+ if (binaryExtensionLength <= filenameLength && dStricmp(pEndOfFilename - xmlExtensionLength, mAutoFormatBinaryExtension) == 0)
|
|
|
+ return Taml::BinaryFormat;
|
|
|
|
|
|
- // Yes, so fetch node.
|
|
|
- TamlWriteNode* compiledNode = compiledItr->value;
|
|
|
+ // Check for the XML format.
|
|
|
+ if (jsonExtensionLength <= filenameLength && dStricmp(pEndOfFilename - jsonExtensionLength, mAutoFormatJSONExtension) == 0)
|
|
|
+ return Taml::JSONFormat;
|
|
|
+ }
|
|
|
|
|
|
- // Is a reference Id already present?
|
|
|
- if (compiledNode->mRefId == 0)
|
|
|
- {
|
|
|
- // No, so allocate one.
|
|
|
- compiledNode->mRefId = ++mMasterNodeId;
|
|
|
- }
|
|
|
+ // Use the explicitly specified format mode.
|
|
|
+ return mFormatMode;
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+
|
|
|
+TamlWriteNode* Taml::compileObject(SimObject* pSimObject, const bool forceId)
|
|
|
+{
|
|
|
+ // Debug Profiling.
|
|
|
+ PROFILE_SCOPE(Taml_CompileObject);
|
|
|
|
|
|
- // Create write node.
|
|
|
- TamlWriteNode* pNewNode = new TamlWriteNode();
|
|
|
- pNewNode->set(pSimObject);
|
|
|
+ // Sanity!
|
|
|
+ AssertFatal(pSimObject != NULL, "Taml::compileObject() - Cannot compile a NULL object.");
|
|
|
|
|
|
- // Set reference node.
|
|
|
- pNewNode->mRefToNode = compiledNode;
|
|
|
+ // Fetch object Id.
|
|
|
+ const SimObjectId objectId = pSimObject->getId();
|
|
|
|
|
|
- // Push new node.
|
|
|
- mCompiledNodes.push_back(pNewNode);
|
|
|
+ // Find a previously compiled node.
|
|
|
+ typeCompiledHash::Iterator compiledItr = mCompiledObjects.find(objectId);
|
|
|
|
|
|
- return pNewNode;
|
|
|
+ // 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;
|
|
|
+
|
|
|
+ // Is a reference Id already present?
|
|
|
+ if (compiledNode->mRefId == 0)
|
|
|
+ {
|
|
|
+ // No, so allocate one.
|
|
|
+ compiledNode->mRefId = ++mMasterNodeId;
|
|
|
}
|
|
|
|
|
|
- // No, so create write node.
|
|
|
+ // 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;
|
|
|
- }
|
|
|
+ // Set reference node.
|
|
|
+ pNewNode->mRefToNode = compiledNode;
|
|
|
|
|
|
// Push new node.
|
|
|
mCompiledNodes.push_back(pNewNode);
|
|
|
|
|
|
- // Insert compiled object.
|
|
|
- mCompiledObjects.insertUnique(objectId, pNewNode);
|
|
|
-
|
|
|
- // Are there any Taml callbacks?
|
|
|
- if (pNewNode->mpTamlCallbacks != NULL)
|
|
|
- {
|
|
|
- // Yes, so call it.
|
|
|
- tamlPreWrite(pNewNode->mpTamlCallbacks);
|
|
|
- }
|
|
|
+ return pNewNode;
|
|
|
+ }
|
|
|
|
|
|
- // Compile static and dynamic fields.
|
|
|
- compileStaticFields(pNewNode);
|
|
|
- compileDynamicFields(pNewNode);
|
|
|
+ // No, so create write node.
|
|
|
+ TamlWriteNode* pNewNode = new TamlWriteNode();
|
|
|
+ pNewNode->set(pSimObject);
|
|
|
|
|
|
- // Compile children.
|
|
|
- compileChildren(pNewNode);
|
|
|
+ // Is an Id being forced for this object?
|
|
|
+ if (forceId)
|
|
|
+ {
|
|
|
+ // Yes, so allocate one.
|
|
|
+ pNewNode->mRefId = ++mMasterNodeId;
|
|
|
+ }
|
|
|
|
|
|
- // Compile custom state.
|
|
|
- compileCustomState(pNewNode);
|
|
|
+ // Push new node.
|
|
|
+ mCompiledNodes.push_back(pNewNode);
|
|
|
|
|
|
- // Are there any Taml callbacks?
|
|
|
- if (pNewNode->mpTamlCallbacks != NULL)
|
|
|
- {
|
|
|
- // Yes, so call it.
|
|
|
- tamlPostWrite(pNewNode->mpTamlCallbacks);
|
|
|
- }
|
|
|
+ // Insert compiled object.
|
|
|
+ mCompiledObjects.insertUnique(objectId, pNewNode);
|
|
|
|
|
|
- return pNewNode;
|
|
|
+ // 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 children.
|
|
|
+ compileChildren(pNewNode);
|
|
|
|
|
|
- void Taml::compileStaticFields(TamlWriteNode* pTamlWriteNode)
|
|
|
+ // Compile custom state.
|
|
|
+ compileCustomState(pNewNode);
|
|
|
+
|
|
|
+ // Are there any Taml callbacks?
|
|
|
+ if (pNewNode->mpTamlCallbacks != NULL)
|
|
|
{
|
|
|
- // Debug Profiling.
|
|
|
- PROFILE_SCOPE(Taml_CompileStaticFields);
|
|
|
+ // Yes, so call it.
|
|
|
+ tamlPostWrite(pNewNode->mpTamlCallbacks);
|
|
|
+ }
|
|
|
|
|
|
- // 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.");
|
|
|
+ return pNewNode;
|
|
|
+}
|
|
|
|
|
|
- // Fetch object.
|
|
|
- SimObject* pSimObject = pTamlWriteNode->mpSimObject;
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // Fetch field list.
|
|
|
- const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList();
|
|
|
+void Taml::compileStaticFields(TamlWriteNode* pTamlWriteNode)
|
|
|
+{
|
|
|
+ // Debug Profiling.
|
|
|
+ PROFILE_SCOPE(Taml_CompileStaticFields);
|
|
|
|
|
|
- // Fetch field count.
|
|
|
- const U32 fieldCount = fieldList.size();
|
|
|
+ // 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.");
|
|
|
|
|
|
- ConsoleObject* defaultConObject = NULL;
|
|
|
- SimObject* defaultObject = NULL;
|
|
|
- if (!getWriteDefaults())
|
|
|
- {
|
|
|
- // Create a default object of the same type
|
|
|
- defaultConObject = ConsoleObject::create(pSimObject->getClassName());
|
|
|
- if (!defaultConObject)
|
|
|
- return;
|
|
|
- defaultObject = dynamic_cast<SimObject*>(defaultConObject);
|
|
|
-
|
|
|
- }
|
|
|
- // ***Really*** shouldn't happen
|
|
|
- if (!defaultConObject || !defaultObject)
|
|
|
- return;
|
|
|
+ // Fetch object.
|
|
|
+ SimObject* pSimObject = pTamlWriteNode->mpSimObject;
|
|
|
|
|
|
- // Iterate fields.
|
|
|
- U8 arrayDepth = 0;
|
|
|
- TamlCustomNode* currentArrayNode = NULL;
|
|
|
- for (U32 index = 0; index < fieldCount; ++index)
|
|
|
- {
|
|
|
- // Fetch field.
|
|
|
- const AbstractClassRep::Field* pField = &fieldList[index];
|
|
|
+ // Fetch field list.
|
|
|
+ const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList();
|
|
|
|
|
|
- // Ignore if field not appropriate.
|
|
|
- if (pField->type == AbstractClassRep::DeprecatedFieldType ||
|
|
|
- pField->type == AbstractClassRep::StartGroupFieldType ||
|
|
|
- pField->type == AbstractClassRep::EndGroupFieldType)
|
|
|
- continue;
|
|
|
+ // Fetch field count.
|
|
|
+ const U32 fieldCount = fieldList.size();
|
|
|
|
|
|
- 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;
|
|
|
- }
|
|
|
+ ConsoleObject* defaultConObject = NULL;
|
|
|
+ SimObject* defaultObject = NULL;
|
|
|
+ if (!getWriteDefaults())
|
|
|
+ {
|
|
|
+ // Create a default object of the same type
|
|
|
+ defaultConObject = ConsoleObject::create(pSimObject->getClassName());
|
|
|
+ if (!defaultConObject)
|
|
|
+ return;
|
|
|
+ defaultObject = dynamic_cast<SimObject*>(defaultConObject);
|
|
|
+
|
|
|
+ }
|
|
|
+ // ***Really*** shouldn't happen
|
|
|
+ if (!defaultConObject || !defaultObject)
|
|
|
+ return;
|
|
|
+
|
|
|
+ // Iterate fields.
|
|
|
+ U8 arrayDepth = 0;
|
|
|
+ TamlCustomNode* currentArrayNode = NULL;
|
|
|
+ for (U32 index = 0; index < fieldCount; ++index)
|
|
|
+ {
|
|
|
+ // Fetch field.
|
|
|
+ const AbstractClassRep::Field* pField = &fieldList[index];
|
|
|
|
|
|
- if (pField->type == AbstractClassRep::EndArrayFieldType)
|
|
|
- {
|
|
|
- arrayDepth--;
|
|
|
- continue;
|
|
|
- }
|
|
|
+ // Ignore if field not appropriate.
|
|
|
+ if (pField->type == AbstractClassRep::DeprecatedFieldType ||
|
|
|
+ pField->type == AbstractClassRep::StartGroupFieldType ||
|
|
|
+ pField->type == AbstractClassRep::EndGroupFieldType)
|
|
|
+ continue;
|
|
|
|
|
|
- if (arrayDepth == 0 && pField->elementCount > 1)
|
|
|
- {
|
|
|
- TamlCustomNodes& pCustomNodes = pTamlWriteNode->mCustomNodes;
|
|
|
- char* niceFieldName = const_cast<char *>(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 (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;
|
|
|
+ }
|
|
|
|
|
|
- // Fetch fieldname.
|
|
|
- StringTableEntry fieldName = StringTable->insert(pField->pFieldname);
|
|
|
+ if (pField->type == AbstractClassRep::EndArrayFieldType)
|
|
|
+ {
|
|
|
+ arrayDepth--;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- // Fetch element count.
|
|
|
- const U32 elementCount = pField->elementCount;
|
|
|
+ if (arrayDepth == 0 && pField->elementCount > 1)
|
|
|
+ {
|
|
|
+ TamlCustomNodes& pCustomNodes = pTamlWriteNode->mCustomNodes;
|
|
|
+ char* niceFieldName = const_cast<char *>(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);
|
|
|
+ }
|
|
|
|
|
|
- // 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;
|
|
|
+ // Fetch fieldname.
|
|
|
+ StringTableEntry fieldName = StringTable->insert(pField->pFieldname);
|
|
|
|
|
|
- // Iterate elements.
|
|
|
- for (U32 elementIndex = 0; elementIndex < elementCount; ++elementIndex)
|
|
|
- {
|
|
|
- char indexBuffer[8];
|
|
|
- dSprintf(indexBuffer, 8, "%d", elementIndex);
|
|
|
+ // Fetch element count.
|
|
|
+ const U32 elementCount = pField->elementCount;
|
|
|
|
|
|
- // Fetch object field value.
|
|
|
- const char* pFieldValue = pSimObject->getPrefixedDataField(fieldName, indexBuffer);
|
|
|
+ // 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;
|
|
|
|
|
|
- if (!pFieldValue)
|
|
|
- pFieldValue = StringTable->EmptyString();
|
|
|
+ // Iterate elements.
|
|
|
+ for (U32 elementIndex = 0; elementIndex < elementCount; ++elementIndex)
|
|
|
+ {
|
|
|
+ char indexBuffer[8];
|
|
|
+ dSprintf(indexBuffer, 8, "%d", elementIndex);
|
|
|
|
|
|
- U32 nBufferSize = dStrlen(pFieldValue) + 1;
|
|
|
- FrameTemp<char> valueCopy(nBufferSize);
|
|
|
- dStrcpy((char *)valueCopy, pFieldValue, nBufferSize);
|
|
|
+ // Fetch object field value.
|
|
|
+ const char* pFieldValue = pSimObject->getPrefixedDataField(fieldName, indexBuffer);
|
|
|
|
|
|
- // Skip if field should not be written.
|
|
|
- if (!pSimObject->writeField(fieldName, valueCopy))
|
|
|
- continue;
|
|
|
+ if (!pFieldValue)
|
|
|
+ pFieldValue = StringTable->EmptyString();
|
|
|
|
|
|
- if (!getWriteDefaults())
|
|
|
- {
|
|
|
- //If the field hasn't been changed from the default value, then don't bother writing it out
|
|
|
- const char* fieldData = defaultObject->getDataField(fieldName, indexBuffer);
|
|
|
- if (fieldData && fieldData[0] != '\0' && dStricmp(fieldData, pFieldValue) == 0)
|
|
|
- continue;
|
|
|
- }
|
|
|
+ U32 nBufferSize = dStrlen(pFieldValue) + 1;
|
|
|
+ FrameTemp<char> valueCopy(nBufferSize);
|
|
|
+ dStrcpy((char *)valueCopy, pFieldValue, nBufferSize);
|
|
|
|
|
|
- // Reassign field value.
|
|
|
- pFieldValue = valueCopy;
|
|
|
+ // Skip if field should not be written.
|
|
|
+ if (!pSimObject->writeField(fieldName, valueCopy))
|
|
|
+ continue;
|
|
|
|
|
|
- if (pField->type == TypeBool)
|
|
|
- pFieldValue = dAtob(pFieldValue) ? "true" : "false";
|
|
|
+ if (!getWriteDefaults())
|
|
|
+ {
|
|
|
+ //If the field hasn't been changed from the default value, then don't bother writing it out
|
|
|
+ const char* fieldData = defaultObject->getDataField(fieldName, indexBuffer);
|
|
|
+ if (fieldData && fieldData[0] != '\0' && dStricmp(fieldData, pFieldValue) == 0)
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- // Detect and collapse relative path information
|
|
|
- char fnBuf[1024];
|
|
|
- if ((S32)pField->type == TypeFilename)
|
|
|
- {
|
|
|
- Con::collapseScriptFilename(fnBuf, 1024, pFieldValue);
|
|
|
- pFieldValue = fnBuf;
|
|
|
- }
|
|
|
+ // Reassign field value.
|
|
|
+ pFieldValue = valueCopy;
|
|
|
|
|
|
- // Save field/value.
|
|
|
- if (currentArrayNode && (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);
|
|
|
- }
|
|
|
+ if (pField->type == TypeBool)
|
|
|
+ pFieldValue = dAtob(pFieldValue) ? "true" : "false";
|
|
|
+
|
|
|
+ // Detect and collapse relative path information
|
|
|
+ char fnBuf[1024];
|
|
|
+ if ((S32)pField->type == TypeFilename)
|
|
|
+ {
|
|
|
+ Con::collapseScriptFilename(fnBuf, 1024, pFieldValue);
|
|
|
+ pFieldValue = fnBuf;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (!getWriteDefaults())
|
|
|
- {
|
|
|
- // Cleanup our created default object
|
|
|
- delete defaultConObject;
|
|
|
+ // Save field/value.
|
|
|
+ if (currentArrayNode && (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);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
-
|
|
|
- static S32 QSORT_CALLBACK compareFieldEntries(const void* a, const void* b)
|
|
|
+ if (!getWriteDefaults())
|
|
|
{
|
|
|
- // Debug Profiling.
|
|
|
- PROFILE_SCOPE(Taml_CompareFieldEntries);
|
|
|
-
|
|
|
- SimFieldDictionary::Entry *fa = *((SimFieldDictionary::Entry **)a);
|
|
|
- SimFieldDictionary::Entry *fb = *((SimFieldDictionary::Entry **)b);
|
|
|
- return dStricmp(fa->slotName, fb->slotName);
|
|
|
+ // Cleanup our created default object
|
|
|
+ delete defaultConObject;
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- void Taml::compileDynamicFields(TamlWriteNode* pTamlWriteNode)
|
|
|
- {
|
|
|
- // Debug Profiling.
|
|
|
- PROFILE_SCOPE(Taml_CompileDynamicFields);
|
|
|
+static S32 QSORT_CALLBACK compareFieldEntries(const void* a, const void* b)
|
|
|
+{
|
|
|
+ // Debug Profiling.
|
|
|
+ PROFILE_SCOPE(Taml_CompareFieldEntries);
|
|
|
|
|
|
- // 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.");
|
|
|
+ SimFieldDictionary::Entry *fa = *((SimFieldDictionary::Entry **)a);
|
|
|
+ SimFieldDictionary::Entry *fb = *((SimFieldDictionary::Entry **)b);
|
|
|
+ return dStricmp(fa->slotName, fb->slotName);
|
|
|
+}
|
|
|
|
|
|
- // Fetch object.
|
|
|
- SimObject* pSimObject = pTamlWriteNode->mpSimObject;
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // Fetch field dictionary.
|
|
|
- SimFieldDictionary* pFieldDictionary = pSimObject->getFieldDictionary();
|
|
|
+void Taml::compileDynamicFields(TamlWriteNode* pTamlWriteNode)
|
|
|
+{
|
|
|
+ // Debug Profiling.
|
|
|
+ PROFILE_SCOPE(Taml_CompileDynamicFields);
|
|
|
|
|
|
- // Ignore if not writing dynamic fields.
|
|
|
- if (!pFieldDictionary || !pSimObject->getCanSaveDynamicFields())
|
|
|
- return;
|
|
|
+ // 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 field list.
|
|
|
- const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList();
|
|
|
+ // Fetch object.
|
|
|
+ SimObject* pSimObject = pTamlWriteNode->mpSimObject;
|
|
|
|
|
|
- // Fetch field count.
|
|
|
- const U32 fieldCount = fieldList.size();
|
|
|
+ // Fetch field dictionary.
|
|
|
+ SimFieldDictionary* pFieldDictionary = pSimObject->getFieldDictionary();
|
|
|
|
|
|
- Vector<SimFieldDictionary::Entry*> dynamicFieldList(__FILE__, __LINE__);
|
|
|
+ // Ignore if not writing dynamic fields.
|
|
|
+ if (!pFieldDictionary || !pSimObject->getCanSaveDynamicFields())
|
|
|
+ return;
|
|
|
|
|
|
- // 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)
|
|
|
- {
|
|
|
- if (fieldList[fieldIndex].pFieldname == pEntry->slotName)
|
|
|
- break;
|
|
|
- }
|
|
|
+ // Fetch field list.
|
|
|
+ const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList();
|
|
|
|
|
|
- // Skip if found.
|
|
|
- if (fieldIndex != (U32)fieldList.size())
|
|
|
- continue;
|
|
|
+ // Fetch field count.
|
|
|
+ const U32 fieldCount = fieldList.size();
|
|
|
|
|
|
- // Skip if not writing field.
|
|
|
- if (!pSimObject->writeField(pEntry->slotName, pEntry->value))
|
|
|
- continue;
|
|
|
+ Vector<SimFieldDictionary::Entry*> dynamicFieldList(__FILE__, __LINE__);
|
|
|
|
|
|
- dynamicFieldList.push_back(pEntry);
|
|
|
+ // 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)
|
|
|
+ {
|
|
|
+ if (fieldList[fieldIndex].pFieldname == pEntry->slotName)
|
|
|
+ break;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- // Sort Entries to prevent version control conflicts
|
|
|
- if (dynamicFieldList.size() > 1)
|
|
|
- dQsort(dynamicFieldList.address(), dynamicFieldList.size(), sizeof(SimFieldDictionary::Entry*), compareFieldEntries);
|
|
|
+ // Skip if found.
|
|
|
+ if (fieldIndex != (U32)fieldList.size())
|
|
|
+ continue;
|
|
|
|
|
|
- // Save the fields.
|
|
|
- for (Vector<SimFieldDictionary::Entry*>::iterator entryItr = dynamicFieldList.begin(); entryItr != dynamicFieldList.end(); ++entryItr)
|
|
|
- {
|
|
|
- // Fetch entry.
|
|
|
- SimFieldDictionary::Entry* pEntry = *entryItr;
|
|
|
+ // Skip if not writing field.
|
|
|
+ if (!pSimObject->writeField(pEntry->slotName, pEntry->value))
|
|
|
+ continue;
|
|
|
|
|
|
- // Save field/value.
|
|
|
- TamlWriteNode::FieldValuePair* pFieldValuePair = new TamlWriteNode::FieldValuePair(pEntry->slotName, pEntry->value);
|
|
|
- pTamlWriteNode->mFields.push_back(pFieldValuePair);
|
|
|
+ dynamicFieldList.push_back(pEntry);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+ // Sort Entries to prevent version control conflicts
|
|
|
+ if (dynamicFieldList.size() > 1)
|
|
|
+ dQsort(dynamicFieldList.address(), dynamicFieldList.size(), sizeof(SimFieldDictionary::Entry*), compareFieldEntries);
|
|
|
|
|
|
- void Taml::compileChildren(TamlWriteNode* pTamlWriteNode)
|
|
|
+ // Save the fields.
|
|
|
+ for (Vector<SimFieldDictionary::Entry*>::iterator entryItr = dynamicFieldList.begin(); entryItr != dynamicFieldList.end(); ++entryItr)
|
|
|
{
|
|
|
- // Debug Profiling.
|
|
|
- PROFILE_SCOPE(Taml_CompileChildren);
|
|
|
+ // Fetch entry.
|
|
|
+ SimFieldDictionary::Entry* pEntry = *entryItr;
|
|
|
|
|
|
- // Sanity!
|
|
|
- AssertFatal(pTamlWriteNode != NULL, "Cannot compile children on a NULL node.");
|
|
|
- AssertFatal(pTamlWriteNode->mpSimObject != NULL, "Cannot compile children on a node with no object.");
|
|
|
+ // Save field/value.
|
|
|
+ TamlWriteNode::FieldValuePair* pFieldValuePair = new TamlWriteNode::FieldValuePair(pEntry->slotName, pEntry->value);
|
|
|
+ pTamlWriteNode->mFields.push_back(pFieldValuePair);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- // Fetch object.
|
|
|
- SimObject* pSimObject = pTamlWriteNode->mpSimObject;
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // Fetch the Taml children.
|
|
|
- TamlChildren* pChildren = dynamic_cast<TamlChildren*>(pSimObject);
|
|
|
+void Taml::compileChildren(TamlWriteNode* pTamlWriteNode)
|
|
|
+{
|
|
|
+ // Debug Profiling.
|
|
|
+ PROFILE_SCOPE(Taml_CompileChildren);
|
|
|
|
|
|
- // Finish if object does not contain Taml children.
|
|
|
- if (pChildren == NULL || pChildren->getTamlChildCount() == 0)
|
|
|
- return;
|
|
|
+ // Sanity!
|
|
|
+ AssertFatal(pTamlWriteNode != NULL, "Cannot compile children on a NULL node.");
|
|
|
+ AssertFatal(pTamlWriteNode->mpSimObject != NULL, "Cannot compile children on a node with no object.");
|
|
|
|
|
|
- // Create children vector.
|
|
|
- pTamlWriteNode->mChildren = new typeNodeVector();
|
|
|
+ // Fetch object.
|
|
|
+ SimObject* pSimObject = pTamlWriteNode->mpSimObject;
|
|
|
|
|
|
- // Fetch the child count.
|
|
|
- const U32 childCount = pChildren->getTamlChildCount();
|
|
|
+ // Fetch the Taml children.
|
|
|
+ TamlChildren* pChildren = dynamic_cast<TamlChildren*>(pSimObject);
|
|
|
|
|
|
- // Iterate children.
|
|
|
- for (U32 childIndex = 0; childIndex < childCount; childIndex++)
|
|
|
- {
|
|
|
- // Compile object.
|
|
|
- TamlWriteNode* pChildTamlWriteNode = compileObject(pChildren->getTamlChild(childIndex));
|
|
|
+ // Finish if object does not contain Taml children.
|
|
|
+ if (pChildren == NULL || pChildren->getTamlChildCount() == 0)
|
|
|
+ return;
|
|
|
|
|
|
- // Save node.
|
|
|
- pTamlWriteNode->mChildren->push_back(pChildTamlWriteNode);
|
|
|
- }
|
|
|
- }
|
|
|
+ // Create children vector.
|
|
|
+ pTamlWriteNode->mChildren = new typeNodeVector();
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+ // Fetch the child count.
|
|
|
+ const U32 childCount = pChildren->getTamlChildCount();
|
|
|
|
|
|
- void Taml::compileCustomState(TamlWriteNode* pTamlWriteNode)
|
|
|
+ // Iterate children.
|
|
|
+ for (U32 childIndex = 0; childIndex < childCount; childIndex++)
|
|
|
{
|
|
|
- // 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.");
|
|
|
+ // Compile object.
|
|
|
+ TamlWriteNode* pChildTamlWriteNode = compileObject(pChildren->getTamlChild(childIndex));
|
|
|
|
|
|
- // Fetch the custom node on the write node.
|
|
|
- TamlCustomNodes& customNodes = pTamlWriteNode->mCustomNodes;
|
|
|
+ // Save node.
|
|
|
+ pTamlWriteNode->mChildren->push_back(pChildTamlWriteNode);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- // Are there any Taml callbacks?
|
|
|
- if (pTamlWriteNode->mpTamlCallbacks != NULL)
|
|
|
- {
|
|
|
- // Yes, so call it.
|
|
|
- tamlCustomWrite(pTamlWriteNode->mpTamlCallbacks, customNodes);
|
|
|
- }
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // Fetch custom nodes.
|
|
|
- const TamlCustomNodeVector& nodes = customNodes.getNodes();
|
|
|
+void Taml::compileCustomState(TamlWriteNode* pTamlWriteNode)
|
|
|
+{
|
|
|
+ // Debug Profiling.
|
|
|
+ PROFILE_SCOPE(Taml_CompileCustomProperties);
|
|
|
|
|
|
- // Finish if no custom nodes to process.
|
|
|
- if (nodes.size() == 0)
|
|
|
- return;
|
|
|
+ // 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.");
|
|
|
|
|
|
- // Iterate custom properties.
|
|
|
- for (TamlCustomNodeVector::const_iterator customNodesItr = nodes.begin(); customNodesItr != nodes.end(); ++customNodesItr)
|
|
|
- {
|
|
|
- // Fetch the custom node.
|
|
|
- TamlCustomNode* pCustomNode = *customNodesItr;
|
|
|
+ // Fetch the custom node on the write node.
|
|
|
+ TamlCustomNodes& customNodes = pTamlWriteNode->mCustomNodes;
|
|
|
|
|
|
- // Compile custom node state.
|
|
|
- compileCustomNodeState(pCustomNode);
|
|
|
- }
|
|
|
+ // Are there any Taml callbacks?
|
|
|
+ if (pTamlWriteNode->mpTamlCallbacks != NULL)
|
|
|
+ {
|
|
|
+ // Yes, so call it.
|
|
|
+ tamlCustomWrite(pTamlWriteNode->mpTamlCallbacks, customNodes);
|
|
|
}
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+ // Fetch custom nodes.
|
|
|
+ const TamlCustomNodeVector& nodes = customNodes.getNodes();
|
|
|
|
|
|
- void Taml::compileCustomNodeState(TamlCustomNode* 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)
|
|
|
{
|
|
|
- // Sanity!
|
|
|
- AssertFatal(pCustomNode != NULL, "Taml: Cannot compile NULL custom node state.");
|
|
|
+ // Fetch the custom node.
|
|
|
+ TamlCustomNode* pCustomNode = *customNodesItr;
|
|
|
|
|
|
- // Fetch children.
|
|
|
- const TamlCustomNodeVector& children = pCustomNode->getChildren();
|
|
|
+ // Compile custom node state.
|
|
|
+ compileCustomNodeState(pCustomNode);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- // Fetch proxy object.
|
|
|
- SimObject* pProxyObject = pCustomNode->getProxyObject<SimObject>(false);
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- // 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.");
|
|
|
-
|
|
|
- // 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;
|
|
|
- }
|
|
|
+void Taml::compileCustomNodeState(TamlCustomNode* pCustomNode)
|
|
|
+{
|
|
|
+ // Sanity!
|
|
|
+ AssertFatal(pCustomNode != NULL, "Taml: Cannot compile NULL custom node state.");
|
|
|
|
|
|
- // Finish if no children.
|
|
|
- if (children.size() == 0)
|
|
|
- return;
|
|
|
+ // Fetch children.
|
|
|
+ const TamlCustomNodeVector& children = pCustomNode->getChildren();
|
|
|
|
|
|
- // Iterate children.
|
|
|
- for (TamlCustomNodeVector::const_iterator childItr = children.begin(); childItr != children.end(); ++childItr)
|
|
|
- {
|
|
|
- // Fetch shape node.
|
|
|
- TamlCustomNode* pChildNode = *childItr;
|
|
|
+ // Fetch proxy object.
|
|
|
+ SimObject* pProxyObject = pCustomNode->getProxyObject<SimObject>(false);
|
|
|
|
|
|
- // Compile the child.
|
|
|
- compileCustomNodeState(pChildNode);
|
|
|
- }
|
|
|
+ // 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.");
|
|
|
+
|
|
|
+ // 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;
|
|
|
}
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+ // Finish if no children.
|
|
|
+ if (children.size() == 0)
|
|
|
+ return;
|
|
|
|
|
|
- SimObject* Taml::createType(StringTableEntry typeName, const Taml* pTaml, const char* pProgenitorSuffix)
|
|
|
+ // Iterate children.
|
|
|
+ for (TamlCustomNodeVector::const_iterator childItr = children.begin(); childItr != children.end(); ++childItr)
|
|
|
{
|
|
|
- // Debug Profiling.
|
|
|
- PROFILE_SCOPE(Taml_CreateType);
|
|
|
+ // Fetch shape node.
|
|
|
+ TamlCustomNode* pChildNode = *childItr;
|
|
|
+
|
|
|
+ // Compile the child.
|
|
|
+ compileCustomNodeState(pChildNode);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- typedef HashTable<StringTableEntry, AbstractClassRep*> 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<StringTableEntry, AbstractClassRep*> typeClassHash;
|
|
|
+ static typeClassHash mClassMap;
|
|
|
|
|
|
- // 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)
|
|
|
- {
|
|
|
- // Yes, so insert it.
|
|
|
- typeItr = mClassMap.insertUnique(typeName, pClassRep);
|
|
|
- break;
|
|
|
- }
|
|
|
+ // Sanity!
|
|
|
+ AssertFatal(typeName != NULL, "Taml: Type cannot be NULL");
|
|
|
|
|
|
- // Next type.
|
|
|
- pClassRep = pClassRep->getNextClass();
|
|
|
- }
|
|
|
+ // Find type.
|
|
|
+ typeClassHash::Iterator typeItr = mClassMap.find(typeName);
|
|
|
|
|
|
- // Did we find the type?
|
|
|
- if (typeItr == mClassMap.end())
|
|
|
+ // 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)
|
|
|
{
|
|
|
- // No, so warn and fail.
|
|
|
- Con::warnf("Taml: Failed to create type '%s' as such a registered type could not be found.", typeName);
|
|
|
- return NULL;
|
|
|
+ // Yes, so insert it.
|
|
|
+ typeItr = mClassMap.insertUnique(typeName, pClassRep);
|
|
|
+ break;
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- // 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.
|
|
|
|
|
|
- // Fetch the SimObject.
|
|
|
- SimObject* pSimObject = dynamic_cast<SimObject*>(pConsoleObject);
|
|
|
+ // Next type.
|
|
|
+ pClassRep = pClassRep->getNextClass();
|
|
|
+ }
|
|
|
|
|
|
- // Was it a SimObject?
|
|
|
- if (pSimObject == NULL)
|
|
|
+ // Did we find the type?
|
|
|
+ if (typeItr == mClassMap.end())
|
|
|
{
|
|
|
- // No, so warn.
|
|
|
- Con::warnf("Taml: Failed to create type '%s' as it is not a SimObject.", typeName);
|
|
|
-
|
|
|
- // Destroy object and fail.
|
|
|
- delete pConsoleObject;
|
|
|
+ // No, so warn and fail.
|
|
|
+ Con::warnf("Taml: Failed to create type '%s' as such a registered type could not be found.", typeName);
|
|
|
return 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
|
|
|
- {
|
|
|
- // Yes, so format the progenitor buffer.
|
|
|
- char progenitorBuffer[2048];
|
|
|
- dSprintf(progenitorBuffer, sizeof(progenitorBuffer), "%s,%s", pTaml->getFilePathBuffer(), pProgenitorSuffix);
|
|
|
+ // Create the object.
|
|
|
+ ConsoleObject* pConsoleObject = typeItr->value->create();
|
|
|
|
|
|
- // Set the progenitor file.
|
|
|
- pSimObject->setProgenitorFile(progenitorBuffer);
|
|
|
- }
|
|
|
- }
|
|
|
+ // 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.
|
|
|
|
|
|
- return pSimObject;
|
|
|
- }
|
|
|
+ // Fetch the SimObject.
|
|
|
+ SimObject* pSimObject = dynamic_cast<SimObject*>(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);
|
|
|
|
|
|
- tinyxml2::XMLElement* g__write_schema_attribute_element(const AbstractClassRep::Field& field, AbstractClassRep* pType,
|
|
|
- tinyxml2::XMLDocument& schemaDocument)
|
|
|
+ // Destroy object and fail.
|
|
|
+ delete pConsoleObject;
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Are we updating the file-progenitor?
|
|
|
+ if (pTaml->getProgenitorUpdate())
|
|
|
{
|
|
|
- // Skip if not a data field.
|
|
|
- if (field.type == AbstractClassRep::DeprecatedFieldType ||
|
|
|
- field.type == AbstractClassRep::StartGroupFieldType ||
|
|
|
- field.type == AbstractClassRep::EndGroupFieldType)
|
|
|
- return NULL;
|
|
|
+ // 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
|
|
|
+ {
|
|
|
+ // Yes, so format the progenitor buffer.
|
|
|
+ char progenitorBuffer[2048];
|
|
|
+ dSprintf(progenitorBuffer, sizeof(progenitorBuffer), "%s,%s", pTaml->getFilePathBuffer(), pProgenitorSuffix);
|
|
|
|
|
|
- // Skip if the field root is not this type.
|
|
|
- if (pType->findFieldRoot(field.pFieldname) != pType)
|
|
|
- return NULL;
|
|
|
+ // Set the progenitor file.
|
|
|
+ pSimObject->setProgenitorFile(progenitorBuffer);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // Add attribute element.
|
|
|
- tinyxml2::XMLElement* pAttributeElement = schemaDocument.NewElement("xs:attribute");
|
|
|
- pAttributeElement->SetAttribute("name", field.pFieldname);
|
|
|
+ return pSimObject;
|
|
|
+}
|
|
|
|
|
|
- // Handle the console type appropriately.
|
|
|
- const S32 fieldType = (S32)field.type;
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
- /*
|
|
|
- // Is the field an enumeration?
|
|
|
- if ( fieldType == TypeEnum )
|
|
|
- {
|
|
|
- // Yes, so add attribute type.
|
|
|
- tinyxml2::XMLElement* pAttributeSimpleTypeElement = schemaDocument.NewElement( "xs:simpleType" );
|
|
|
- pAttributeElement->LinkEndChild( pAttributeSimpleTypeElement );
|
|
|
+tinyxml2::XMLElement* g__write_schema_attribute_element(const AbstractClassRep::Field& field, AbstractClassRep* pType,
|
|
|
+ tinyxml2::XMLDocument& schemaDocument)
|
|
|
+{
|
|
|
+ // Skip if not a data field.
|
|
|
+ if (field.type == AbstractClassRep::DeprecatedFieldType ||
|
|
|
+ field.type == AbstractClassRep::StartGroupFieldType ||
|
|
|
+ field.type == AbstractClassRep::EndGroupFieldType)
|
|
|
+ return NULL;
|
|
|
|
|
|
- // Add restriction element.
|
|
|
- tinyxml2::XMLElement* pAttributeRestrictionElement = schemaDocument.NewElement( "xs:restriction" );
|
|
|
- pAttributeRestrictionElement->SetAttribute( "base", "xs:string" );
|
|
|
- pAttributeSimpleTypeElement->LinkEndChild( pAttributeRestrictionElement );
|
|
|
+ // Skip if the field root is not this type.
|
|
|
+ if (pType->findFieldRoot(field.pFieldname) != pType)
|
|
|
+ return NULL;
|
|
|
|
|
|
- // Yes, so fetch enumeration count.
|
|
|
- const S32 enumCount = field.table->size;
|
|
|
+ // Add attribute element.
|
|
|
+ tinyxml2::XMLElement* pAttributeElement = schemaDocument.NewElement("xs:attribute");
|
|
|
+ pAttributeElement->SetAttribute("name", field.pFieldname);
|
|
|
|
|
|
- // Iterate enumeration.
|
|
|
- for( S32 index = 0; index < enumCount; ++index )
|
|
|
- {
|
|
|
- // Add enumeration element.
|
|
|
- tinyxml2::XMLElement* pAttributeEnumerationElement = schemaDocument.NewElement( "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";
|
|
|
+ // Handle the console type appropriately.
|
|
|
+ const S32 fieldType = (S32)field.type;
|
|
|
|
|
|
- // Handle known types.
|
|
|
- if (fieldType == TypeF32)
|
|
|
- {
|
|
|
- pFieldTypeDescription = "xs:float";
|
|
|
- }
|
|
|
- else if (fieldType == TypeS8 || fieldType == TypeS16 || 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";
|
|
|
- }
|
|
|
+ /*
|
|
|
+ // Is the field an enumeration?
|
|
|
+ if ( fieldType == TypeEnum )
|
|
|
+ {
|
|
|
+ // Yes, so add attribute type.
|
|
|
+ tinyxml2::XMLElement* pAttributeSimpleTypeElement = schemaDocument.NewElement( "xs:simpleType" );
|
|
|
+ pAttributeElement->LinkEndChild( pAttributeSimpleTypeElement );
|
|
|
|
|
|
- // Set attribute type.
|
|
|
- pAttributeElement->SetAttribute("type", pFieldTypeDescription);
|
|
|
- //}
|
|
|
+ // Add restriction element.
|
|
|
+ tinyxml2::XMLElement* pAttributeRestrictionElement = schemaDocument.NewElement( "xs:restriction" );
|
|
|
+ pAttributeRestrictionElement->SetAttribute( "base", "xs:string" );
|
|
|
+ pAttributeSimpleTypeElement->LinkEndChild( pAttributeRestrictionElement );
|
|
|
|
|
|
- pAttributeElement->SetAttribute("use", "optional");
|
|
|
- return pAttributeElement;
|
|
|
- }
|
|
|
+ // Yes, so fetch enumeration count.
|
|
|
+ const S32 enumCount = field.table->size;
|
|
|
|
|
|
- String g_sanitize_schema_element_name(String buffer)
|
|
|
+ // Iterate enumeration.
|
|
|
+ for( S32 index = 0; index < enumCount; ++index )
|
|
|
{
|
|
|
- return buffer.replace("(", "")
|
|
|
- .replace(")", "");
|
|
|
+ // Add enumeration element.
|
|
|
+ tinyxml2::XMLElement* pAttributeEnumerationElement = schemaDocument.NewElement( "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";
|
|
|
|
|
|
- bool Taml::generateTamlSchema()
|
|
|
+ // Handle known types.
|
|
|
+ if (fieldType == TypeF32)
|
|
|
+ {
|
|
|
+ pFieldTypeDescription = "xs:float";
|
|
|
+ }
|
|
|
+ else if (fieldType == TypeS8 || fieldType == TypeS16 || fieldType == TypeS32)
|
|
|
+ {
|
|
|
+ pFieldTypeDescription = "xs:int";
|
|
|
+ }
|
|
|
+ else if (fieldType == TypeBool || fieldType == TypeFlag)
|
|
|
+ {
|
|
|
+ pFieldTypeDescription = "xs:boolean";
|
|
|
+ }
|
|
|
+ else if (fieldType == TypePoint2F)
|
|
|
{
|
|
|
- // Fetch any TAML Schema file reference.
|
|
|
- const char* pTamlSchemaFile = Con::getVariable(TAML_SCHEMA_VARIABLE);
|
|
|
+ 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";
|
|
|
+ }
|
|
|
|
|
|
- // 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;
|
|
|
- }
|
|
|
+ // Set attribute type.
|
|
|
+ pAttributeElement->SetAttribute("type", pFieldTypeDescription);
|
|
|
+ //}
|
|
|
|
|
|
- // Expand the file-name into the file-path buffer.
|
|
|
- char filePathBuffer[1024];
|
|
|
- Con::expandToolScriptFilename(filePathBuffer, sizeof(filePathBuffer), pTamlSchemaFile);
|
|
|
+ pAttributeElement->SetAttribute("use", "optional");
|
|
|
+ return pAttributeElement;
|
|
|
+}
|
|
|
|
|
|
- FileStream stream;
|
|
|
+String g_sanitize_schema_element_name(String buffer)
|
|
|
+{
|
|
|
+ return buffer.replace("(", "")
|
|
|
+ .replace(")", "");
|
|
|
+}
|
|
|
|
|
|
- // File opened?
|
|
|
- /*if ( !stream.open( filePathBuffer, Torque::FS::File::Write ) )
|
|
|
- {
|
|
|
+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() - Could not open filename '%s' for write.", filePathBuffer );
|
|
|
+ Con::warnf("Taml::generateTamlSchema() - Cannot write a TAML schema as no schema variable is set ('%s').", TAML_SCHEMA_VARIABLE);
|
|
|
return false;
|
|
|
- }*/
|
|
|
-
|
|
|
- // Create document.
|
|
|
- tinyxml2::XMLDocument schemaDocument;
|
|
|
-
|
|
|
- // Add declaration.
|
|
|
- tinyxml2::XMLDeclaration* schemaDeclaration = schemaDocument.NewDeclaration("xml version=\"1.0\" encoding=\"iso-8859-1\" standalone =\"no\"");
|
|
|
- schemaDocument.InsertEndChild(schemaDeclaration);
|
|
|
-
|
|
|
- // Add schema element.
|
|
|
- tinyxml2::XMLElement* pSchemaElement = schemaDocument.NewElement("xs:schema");
|
|
|
- pSchemaElement->SetAttribute("xmlns:xs", "http://www.w3.org/2001/XMLSchema");
|
|
|
- schemaDocument.LinkEndChild(pSchemaElement);
|
|
|
-
|
|
|
- // 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.");
|
|
|
-
|
|
|
- // Reset scratch state.
|
|
|
- char buffer[1024];
|
|
|
- HashTable<AbstractClassRep*, StringTableEntry> childGroups;
|
|
|
-
|
|
|
- // *************************************************************
|
|
|
- // Generate console type elements.
|
|
|
- // *************************************************************
|
|
|
-
|
|
|
- // Vector2.
|
|
|
- tinyxml2::XMLComment* pVector2Comment = schemaDocument.NewComment("Vector2 Console Type");
|
|
|
- pSchemaElement->LinkEndChild(pVector2Comment);
|
|
|
- tinyxml2::XMLElement* pVector2TypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pVector2TypeElement->SetAttribute("name", "Vector2_ConsoleType");
|
|
|
- pSchemaElement->LinkEndChild(pVector2TypeElement);
|
|
|
- tinyxml2::XMLElement* pVector2ElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
- pVector2ElementA->SetAttribute("base", "xs:string");
|
|
|
- pVector2TypeElement->LinkEndChild(pVector2ElementA);
|
|
|
- tinyxml2::XMLElement* pVector2ElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
- pVector2ElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b");
|
|
|
- pVector2ElementA->LinkEndChild(pVector2ElementB);
|
|
|
-
|
|
|
- // Point2F.
|
|
|
- tinyxml2::XMLComment* pPoint2FComment = schemaDocument.NewComment("Point2F Console Type");
|
|
|
- pSchemaElement->LinkEndChild(pPoint2FComment);
|
|
|
- tinyxml2::XMLElement* pPoint2FTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pPoint2FTypeElement->SetAttribute("name", "Point2F_ConsoleType");
|
|
|
- pSchemaElement->LinkEndChild(pPoint2FTypeElement);
|
|
|
- tinyxml2::XMLElement* pPoint2FElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
- pPoint2FElementA->SetAttribute("base", "xs:string");
|
|
|
- pPoint2FTypeElement->LinkEndChild(pPoint2FElementA);
|
|
|
- tinyxml2::XMLElement* pPoint2FElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
- pPoint2FElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b");
|
|
|
- pPoint2FElementA->LinkEndChild(pPoint2FElementB);
|
|
|
-
|
|
|
- // Point2I.
|
|
|
- tinyxml2::XMLComment* pPoint2IComment = schemaDocument.NewComment("Point2I Console Type");
|
|
|
- pSchemaElement->LinkEndChild(pPoint2IComment);
|
|
|
- tinyxml2::XMLElement* pPoint2ITypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pPoint2ITypeElement->SetAttribute("name", "Point2I_ConsoleType");
|
|
|
- pSchemaElement->LinkEndChild(pPoint2ITypeElement);
|
|
|
- tinyxml2::XMLElement* pPoint2IElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
- pPoint2IElementA->SetAttribute("base", "xs:string");
|
|
|
- pPoint2ITypeElement->LinkEndChild(pPoint2IElementA);
|
|
|
- tinyxml2::XMLElement* pPoint2IElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
- pPoint2IElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]*");
|
|
|
- pPoint2IElementA->LinkEndChild(pPoint2IElementB);
|
|
|
-
|
|
|
- // b2AABB.
|
|
|
- tinyxml2::XMLComment* pb2AABBComment = schemaDocument.NewComment("b2AABB Console Type");
|
|
|
- pSchemaElement->LinkEndChild(pb2AABBComment);
|
|
|
- tinyxml2::XMLElement* pb2AABBTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pb2AABBTypeElement->SetAttribute("name", "b2AABB_ConsoleType");
|
|
|
- pSchemaElement->LinkEndChild(pb2AABBTypeElement);
|
|
|
- tinyxml2::XMLElement* pb2AABBElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
- pb2AABBElementA->SetAttribute("base", "xs:string");
|
|
|
- pb2AABBTypeElement->LinkEndChild(pb2AABBElementA);
|
|
|
- tinyxml2::XMLElement* pb2AABBElementB = schemaDocument.NewElement("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.
|
|
|
- tinyxml2::XMLComment* pRectIComment = schemaDocument.NewComment("RectI Console Type");
|
|
|
- pSchemaElement->LinkEndChild(pRectIComment);
|
|
|
- tinyxml2::XMLElement* pRectITypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pRectITypeElement->SetAttribute("name", "RectI_ConsoleType");
|
|
|
- pSchemaElement->LinkEndChild(pRectITypeElement);
|
|
|
- tinyxml2::XMLElement* pRectIElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
- pRectIElementA->SetAttribute("base", "xs:string");
|
|
|
- pRectITypeElement->LinkEndChild(pRectIElementA);
|
|
|
- tinyxml2::XMLElement* pRectIElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
- pRectIElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*");
|
|
|
- pRectIElementA->LinkEndChild(pRectIElementB);
|
|
|
-
|
|
|
- // RectF.
|
|
|
- tinyxml2::XMLComment* pRectFComment = schemaDocument.NewComment("RectF Console Type");
|
|
|
- pSchemaElement->LinkEndChild(pRectFComment);
|
|
|
- tinyxml2::XMLElement* pRectFTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pRectFTypeElement->SetAttribute("name", "RectF_ConsoleType");
|
|
|
- pSchemaElement->LinkEndChild(pRectFTypeElement);
|
|
|
- tinyxml2::XMLElement* pRectFElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
- pRectFElementA->SetAttribute("base", "xs:string");
|
|
|
- pRectFTypeElement->LinkEndChild(pRectFElementA);
|
|
|
- tinyxml2::XMLElement* pRectFElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
- pRectFElementB->SetAttribute("value", "(\\b[-]?(b[0-9]+)?\\.)?[0-9]+\\b");
|
|
|
- pRectFElementA->LinkEndChild(pRectFElementB);
|
|
|
-
|
|
|
- // AssetId.
|
|
|
- tinyxml2::XMLComment* pAssetIdComment = schemaDocument.NewComment("AssetId Console Type");
|
|
|
- pSchemaElement->LinkEndChild(pAssetIdComment);
|
|
|
- tinyxml2::XMLElement* pAssetIdTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pAssetIdTypeElement->SetAttribute("name", "AssetId_ConsoleType");
|
|
|
- pSchemaElement->LinkEndChild(pAssetIdTypeElement);
|
|
|
- tinyxml2::XMLElement* pAssetIdElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
- pAssetIdElementA->SetAttribute("base", "xs:string");
|
|
|
- pAssetIdTypeElement->LinkEndChild(pAssetIdElementA);
|
|
|
- tinyxml2::XMLElement* pAssetIdElementB = schemaDocument.NewElement("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.
|
|
|
- tinyxml2::XMLComment* pColorEnumsComment = schemaDocument.NewComment("Color Enums");
|
|
|
- pSchemaElement->LinkEndChild(pColorEnumsComment);
|
|
|
- tinyxml2::XMLElement* pColorEnumsTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pColorEnumsTypeElement->SetAttribute("name", "Color_Enums");
|
|
|
- pSchemaElement->LinkEndChild(pColorEnumsTypeElement);
|
|
|
- tinyxml2::XMLElement* pColorEnumsRestrictionElement = schemaDocument.NewElement("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.
|
|
|
- tinyxml2::XMLElement* pColorEnumsAttributeEnumerationElement = schemaDocument.NewElement("xs:enumeration");
|
|
|
- pColorEnumsAttributeEnumerationElement->SetAttribute("value", StockColor::getColorItem(index)->getColorName());
|
|
|
- pColorEnumsRestrictionElement->LinkEndChild(pColorEnumsAttributeEnumerationElement);
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- // LinearColorF.
|
|
|
- tinyxml2::XMLComment* pColorFValuesComment = schemaDocument.NewComment("LinearColorF Values");
|
|
|
- pSchemaElement->LinkEndChild(pColorFValuesComment);
|
|
|
- tinyxml2::XMLElement* pColorFValuesTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pColorFValuesTypeElement->SetAttribute("name", "ColorF_Values");
|
|
|
- pSchemaElement->LinkEndChild(pColorFValuesTypeElement);
|
|
|
- tinyxml2::XMLElement* pColorFValuesElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
- pColorFValuesElementA->SetAttribute("base", "xs:string");
|
|
|
- pColorFValuesTypeElement->LinkEndChild(pColorFValuesElementA);
|
|
|
- tinyxml2::XMLElement* pColorFValuesElementB = schemaDocument.NewElement("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);
|
|
|
-
|
|
|
- tinyxml2::XMLComment* pColorFComment = schemaDocument.NewComment("LinearColorF Console Type");
|
|
|
- pSchemaElement->LinkEndChild(pColorFComment);
|
|
|
- tinyxml2::XMLElement* pColorFTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pColorFTypeElement->SetAttribute("name", "ColorF_ConsoleType");
|
|
|
- pSchemaElement->LinkEndChild(pColorFTypeElement);
|
|
|
- tinyxml2::XMLElement* pColorFUnionElement = schemaDocument.NewElement("xs:union");
|
|
|
- pColorFUnionElement->SetAttribute("memberTypes", "ColorF_Values Color_Enums");
|
|
|
- pColorFTypeElement->LinkEndChild(pColorFUnionElement);
|
|
|
-
|
|
|
- // ColorI.
|
|
|
- tinyxml2::XMLComment* pColorIValuesComment = schemaDocument.NewComment("ColorI Values");
|
|
|
- pSchemaElement->LinkEndChild(pColorIValuesComment);
|
|
|
- tinyxml2::XMLElement* pColorIValuesTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pColorIValuesTypeElement->SetAttribute("name", "ColorI_Values");
|
|
|
- pSchemaElement->LinkEndChild(pColorIValuesTypeElement);
|
|
|
- tinyxml2::XMLElement* pColorIValuesElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
- pColorIValuesElementA->SetAttribute("base", "xs:string");
|
|
|
- pColorIValuesTypeElement->LinkEndChild(pColorIValuesElementA);
|
|
|
- tinyxml2::XMLElement* pColorIValuesElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
- pColorIValuesElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*");
|
|
|
- pColorIValuesElementA->LinkEndChild(pColorIValuesElementB);
|
|
|
-
|
|
|
- tinyxml2::XMLComment* pColorIComment = schemaDocument.NewComment("ColorI Console Type");
|
|
|
- pSchemaElement->LinkEndChild(pColorIComment);
|
|
|
- tinyxml2::XMLElement* pColorITypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
- pColorITypeElement->SetAttribute("name", "ColorI_ConsoleType");
|
|
|
- pSchemaElement->LinkEndChild(pColorITypeElement);
|
|
|
- tinyxml2::XMLElement* pColorIUnionElement = schemaDocument.NewElement("xs:union");
|
|
|
- pColorIUnionElement->SetAttribute("memberTypes", "ColorI_Values Color_Enums");
|
|
|
- pColorITypeElement->LinkEndChild(pColorIUnionElement);
|
|
|
-
|
|
|
- // *************************************************************
|
|
|
- // Generate engine type elements.
|
|
|
- // *************************************************************
|
|
|
-
|
|
|
- // Generate the engine type elements.
|
|
|
- tinyxml2::XMLComment* tComment = schemaDocument.NewComment("Type Elements");
|
|
|
- pSchemaElement->LinkEndChild(tComment);
|
|
|
- for (AbstractClassRep* pType = pRootType; pType != NULL; pType = pType->getNextClass())
|
|
|
- {
|
|
|
- // Add type.
|
|
|
- tinyxml2::XMLElement* pTypeElement = schemaDocument.NewElement("xs:element");
|
|
|
- pTypeElement->SetAttribute("name", pType->getClassName());
|
|
|
- dSprintf(buffer, sizeof(buffer), "%s_Type", pType->getClassName());
|
|
|
- pTypeElement->SetAttribute("type", buffer);
|
|
|
- pSchemaElement->LinkEndChild(pTypeElement);
|
|
|
- }
|
|
|
+ // Expand the file-name into the file-path buffer.
|
|
|
+ char filePathBuffer[1024];
|
|
|
+ Con::expandToolScriptFilename(filePathBuffer, sizeof(filePathBuffer), pTamlSchemaFile);
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }*/
|
|
|
+
|
|
|
+ // Create document.
|
|
|
+ tinyxml2::XMLDocument schemaDocument;
|
|
|
+
|
|
|
+ // Add declaration.
|
|
|
+ tinyxml2::XMLDeclaration* schemaDeclaration = schemaDocument.NewDeclaration("xml version=\"1.0\" encoding=\"iso-8859-1\" standalone =\"no\"");
|
|
|
+ schemaDocument.InsertEndChild(schemaDeclaration);
|
|
|
+
|
|
|
+ // Add schema element.
|
|
|
+ tinyxml2::XMLElement* pSchemaElement = schemaDocument.NewElement("xs:schema");
|
|
|
+ pSchemaElement->SetAttribute("xmlns:xs", "http://www.w3.org/2001/XMLSchema");
|
|
|
+ schemaDocument.LinkEndChild(pSchemaElement);
|
|
|
+
|
|
|
+ // 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.");
|
|
|
+
|
|
|
+ // Reset scratch state.
|
|
|
+ char buffer[1024];
|
|
|
+ HashTable<AbstractClassRep*, StringTableEntry> childGroups;
|
|
|
+
|
|
|
+ // *************************************************************
|
|
|
+ // Generate console type elements.
|
|
|
+ // *************************************************************
|
|
|
+
|
|
|
+ // Vector2.
|
|
|
+ tinyxml2::XMLComment* pVector2Comment = schemaDocument.NewComment("Vector2 Console Type");
|
|
|
+ pSchemaElement->LinkEndChild(pVector2Comment);
|
|
|
+ tinyxml2::XMLElement* pVector2TypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pVector2TypeElement->SetAttribute("name", "Vector2_ConsoleType");
|
|
|
+ pSchemaElement->LinkEndChild(pVector2TypeElement);
|
|
|
+ tinyxml2::XMLElement* pVector2ElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
+ pVector2ElementA->SetAttribute("base", "xs:string");
|
|
|
+ pVector2TypeElement->LinkEndChild(pVector2ElementA);
|
|
|
+ tinyxml2::XMLElement* pVector2ElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
+ pVector2ElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b");
|
|
|
+ pVector2ElementA->LinkEndChild(pVector2ElementB);
|
|
|
+
|
|
|
+ // Point2F.
|
|
|
+ tinyxml2::XMLComment* pPoint2FComment = schemaDocument.NewComment("Point2F Console Type");
|
|
|
+ pSchemaElement->LinkEndChild(pPoint2FComment);
|
|
|
+ tinyxml2::XMLElement* pPoint2FTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pPoint2FTypeElement->SetAttribute("name", "Point2F_ConsoleType");
|
|
|
+ pSchemaElement->LinkEndChild(pPoint2FTypeElement);
|
|
|
+ tinyxml2::XMLElement* pPoint2FElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
+ pPoint2FElementA->SetAttribute("base", "xs:string");
|
|
|
+ pPoint2FTypeElement->LinkEndChild(pPoint2FElementA);
|
|
|
+ tinyxml2::XMLElement* pPoint2FElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
+ pPoint2FElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b");
|
|
|
+ pPoint2FElementA->LinkEndChild(pPoint2FElementB);
|
|
|
+
|
|
|
+ // Point2I.
|
|
|
+ tinyxml2::XMLComment* pPoint2IComment = schemaDocument.NewComment("Point2I Console Type");
|
|
|
+ pSchemaElement->LinkEndChild(pPoint2IComment);
|
|
|
+ tinyxml2::XMLElement* pPoint2ITypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pPoint2ITypeElement->SetAttribute("name", "Point2I_ConsoleType");
|
|
|
+ pSchemaElement->LinkEndChild(pPoint2ITypeElement);
|
|
|
+ tinyxml2::XMLElement* pPoint2IElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
+ pPoint2IElementA->SetAttribute("base", "xs:string");
|
|
|
+ pPoint2ITypeElement->LinkEndChild(pPoint2IElementA);
|
|
|
+ tinyxml2::XMLElement* pPoint2IElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
+ pPoint2IElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]*");
|
|
|
+ pPoint2IElementA->LinkEndChild(pPoint2IElementB);
|
|
|
+
|
|
|
+ // b2AABB.
|
|
|
+ tinyxml2::XMLComment* pb2AABBComment = schemaDocument.NewComment("b2AABB Console Type");
|
|
|
+ pSchemaElement->LinkEndChild(pb2AABBComment);
|
|
|
+ tinyxml2::XMLElement* pb2AABBTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pb2AABBTypeElement->SetAttribute("name", "b2AABB_ConsoleType");
|
|
|
+ pSchemaElement->LinkEndChild(pb2AABBTypeElement);
|
|
|
+ tinyxml2::XMLElement* pb2AABBElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
+ pb2AABBElementA->SetAttribute("base", "xs:string");
|
|
|
+ pb2AABBTypeElement->LinkEndChild(pb2AABBElementA);
|
|
|
+ tinyxml2::XMLElement* pb2AABBElementB = schemaDocument.NewElement("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.
|
|
|
+ tinyxml2::XMLComment* pRectIComment = schemaDocument.NewComment("RectI Console Type");
|
|
|
+ pSchemaElement->LinkEndChild(pRectIComment);
|
|
|
+ tinyxml2::XMLElement* pRectITypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pRectITypeElement->SetAttribute("name", "RectI_ConsoleType");
|
|
|
+ pSchemaElement->LinkEndChild(pRectITypeElement);
|
|
|
+ tinyxml2::XMLElement* pRectIElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
+ pRectIElementA->SetAttribute("base", "xs:string");
|
|
|
+ pRectITypeElement->LinkEndChild(pRectIElementA);
|
|
|
+ tinyxml2::XMLElement* pRectIElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
+ pRectIElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*");
|
|
|
+ pRectIElementA->LinkEndChild(pRectIElementB);
|
|
|
+
|
|
|
+ // RectF.
|
|
|
+ tinyxml2::XMLComment* pRectFComment = schemaDocument.NewComment("RectF Console Type");
|
|
|
+ pSchemaElement->LinkEndChild(pRectFComment);
|
|
|
+ tinyxml2::XMLElement* pRectFTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pRectFTypeElement->SetAttribute("name", "RectF_ConsoleType");
|
|
|
+ pSchemaElement->LinkEndChild(pRectFTypeElement);
|
|
|
+ tinyxml2::XMLElement* pRectFElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
+ pRectFElementA->SetAttribute("base", "xs:string");
|
|
|
+ pRectFTypeElement->LinkEndChild(pRectFElementA);
|
|
|
+ tinyxml2::XMLElement* pRectFElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
+ pRectFElementB->SetAttribute("value", "(\\b[-]?(b[0-9]+)?\\.)?[0-9]+\\b");
|
|
|
+ pRectFElementA->LinkEndChild(pRectFElementB);
|
|
|
+
|
|
|
+ // AssetId.
|
|
|
+ tinyxml2::XMLComment* pAssetIdComment = schemaDocument.NewComment("AssetId Console Type");
|
|
|
+ pSchemaElement->LinkEndChild(pAssetIdComment);
|
|
|
+ tinyxml2::XMLElement* pAssetIdTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pAssetIdTypeElement->SetAttribute("name", "AssetId_ConsoleType");
|
|
|
+ pSchemaElement->LinkEndChild(pAssetIdTypeElement);
|
|
|
+ tinyxml2::XMLElement* pAssetIdElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
+ pAssetIdElementA->SetAttribute("base", "xs:string");
|
|
|
+ pAssetIdTypeElement->LinkEndChild(pAssetIdElementA);
|
|
|
+ tinyxml2::XMLElement* pAssetIdElementB = schemaDocument.NewElement("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.
|
|
|
+ tinyxml2::XMLComment* pColorEnumsComment = schemaDocument.NewComment("Color Enums");
|
|
|
+ pSchemaElement->LinkEndChild(pColorEnumsComment);
|
|
|
+ tinyxml2::XMLElement* pColorEnumsTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pColorEnumsTypeElement->SetAttribute("name", "Color_Enums");
|
|
|
+ pSchemaElement->LinkEndChild(pColorEnumsTypeElement);
|
|
|
+ tinyxml2::XMLElement* pColorEnumsRestrictionElement = schemaDocument.NewElement("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.
|
|
|
+ tinyxml2::XMLElement* pColorEnumsAttributeEnumerationElement = schemaDocument.NewElement("xs:enumeration");
|
|
|
+ pColorEnumsAttributeEnumerationElement->SetAttribute("value", StockColor::getColorItem(index)->getColorName());
|
|
|
+ pColorEnumsRestrictionElement->LinkEndChild(pColorEnumsAttributeEnumerationElement);
|
|
|
+ }
|
|
|
+
|
|
|
+ // LinearColorF.
|
|
|
+ tinyxml2::XMLComment* pColorFValuesComment = schemaDocument.NewComment("LinearColorF Values");
|
|
|
+ pSchemaElement->LinkEndChild(pColorFValuesComment);
|
|
|
+ tinyxml2::XMLElement* pColorFValuesTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pColorFValuesTypeElement->SetAttribute("name", "ColorF_Values");
|
|
|
+ pSchemaElement->LinkEndChild(pColorFValuesTypeElement);
|
|
|
+ tinyxml2::XMLElement* pColorFValuesElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
+ pColorFValuesElementA->SetAttribute("base", "xs:string");
|
|
|
+ pColorFValuesTypeElement->LinkEndChild(pColorFValuesElementA);
|
|
|
+ tinyxml2::XMLElement* pColorFValuesElementB = schemaDocument.NewElement("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);
|
|
|
+
|
|
|
+ tinyxml2::XMLComment* pColorFComment = schemaDocument.NewComment("LinearColorF Console Type");
|
|
|
+ pSchemaElement->LinkEndChild(pColorFComment);
|
|
|
+ tinyxml2::XMLElement* pColorFTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pColorFTypeElement->SetAttribute("name", "ColorF_ConsoleType");
|
|
|
+ pSchemaElement->LinkEndChild(pColorFTypeElement);
|
|
|
+ tinyxml2::XMLElement* pColorFUnionElement = schemaDocument.NewElement("xs:union");
|
|
|
+ pColorFUnionElement->SetAttribute("memberTypes", "ColorF_Values Color_Enums");
|
|
|
+ pColorFTypeElement->LinkEndChild(pColorFUnionElement);
|
|
|
+
|
|
|
+ // ColorI.
|
|
|
+ tinyxml2::XMLComment* pColorIValuesComment = schemaDocument.NewComment("ColorI Values");
|
|
|
+ pSchemaElement->LinkEndChild(pColorIValuesComment);
|
|
|
+ tinyxml2::XMLElement* pColorIValuesTypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pColorIValuesTypeElement->SetAttribute("name", "ColorI_Values");
|
|
|
+ pSchemaElement->LinkEndChild(pColorIValuesTypeElement);
|
|
|
+ tinyxml2::XMLElement* pColorIValuesElementA = schemaDocument.NewElement("xs:restriction");
|
|
|
+ pColorIValuesElementA->SetAttribute("base", "xs:string");
|
|
|
+ pColorIValuesTypeElement->LinkEndChild(pColorIValuesElementA);
|
|
|
+ tinyxml2::XMLElement* pColorIValuesElementB = schemaDocument.NewElement("xs:pattern");
|
|
|
+ pColorIValuesElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*");
|
|
|
+ pColorIValuesElementA->LinkEndChild(pColorIValuesElementB);
|
|
|
+
|
|
|
+ tinyxml2::XMLComment* pColorIComment = schemaDocument.NewComment("ColorI Console Type");
|
|
|
+ pSchemaElement->LinkEndChild(pColorIComment);
|
|
|
+ tinyxml2::XMLElement* pColorITypeElement = schemaDocument.NewElement("xs:simpleType");
|
|
|
+ pColorITypeElement->SetAttribute("name", "ColorI_ConsoleType");
|
|
|
+ pSchemaElement->LinkEndChild(pColorITypeElement);
|
|
|
+ tinyxml2::XMLElement* pColorIUnionElement = schemaDocument.NewElement("xs:union");
|
|
|
+ pColorIUnionElement->SetAttribute("memberTypes", "ColorI_Values Color_Enums");
|
|
|
+ pColorITypeElement->LinkEndChild(pColorIUnionElement);
|
|
|
+
|
|
|
+ // *************************************************************
|
|
|
+ // Generate engine type elements.
|
|
|
+ // *************************************************************
|
|
|
+
|
|
|
+ // Generate the engine type elements.
|
|
|
+ tinyxml2::XMLComment* tComment = schemaDocument.NewComment("Type Elements");
|
|
|
+ pSchemaElement->LinkEndChild(tComment);
|
|
|
+ for (AbstractClassRep* pType = pRootType; pType != NULL; pType = pType->getNextClass())
|
|
|
+ {
|
|
|
+ // Add type.
|
|
|
+ tinyxml2::XMLElement* pTypeElement = schemaDocument.NewElement("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())
|
|
|
+ // *************************************************************
|
|
|
+ // 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());
|
|
|
+ tinyxml2::XMLComment* ctComment = schemaDocument.NewComment(buffer);
|
|
|
+ pSchemaElement->LinkEndChild(ctComment);
|
|
|
+
|
|
|
+ // Add complex type.
|
|
|
+ tinyxml2::XMLElement* pComplexTypeElement = schemaDocument.NewElement("xs:complexType");
|
|
|
+ dSprintf(buffer, sizeof(buffer), "%s_Type", pType->getClassName());
|
|
|
+ pComplexTypeElement->SetAttribute("name", buffer);
|
|
|
+ pSchemaElement->LinkEndChild(pComplexTypeElement);
|
|
|
+
|
|
|
+ // Add sequence.
|
|
|
+ tinyxml2::XMLElement* pAllElement = schemaDocument.NewElement("xs:all");
|
|
|
+ pComplexTypeElement->LinkEndChild(pAllElement);
|
|
|
+
|
|
|
+ // Fetch container child class.
|
|
|
+ AbstractClassRep* pContainerChildClass = pType->getContainerChildClass(true);
|
|
|
+
|
|
|
+ // Is the type allowed children?
|
|
|
+ if (pContainerChildClass != NULL)
|
|
|
{
|
|
|
- // Add complex type comment.
|
|
|
- dSprintf(buffer, sizeof(buffer), " %s Type ", pType->getClassName());
|
|
|
- tinyxml2::XMLComment* ctComment = schemaDocument.NewComment(buffer);
|
|
|
- pSchemaElement->LinkEndChild(ctComment);
|
|
|
-
|
|
|
- // Add complex type.
|
|
|
- tinyxml2::XMLElement* pComplexTypeElement = schemaDocument.NewElement("xs:complexType");
|
|
|
- dSprintf(buffer, sizeof(buffer), "%s_Type", pType->getClassName());
|
|
|
- pComplexTypeElement->SetAttribute("name", buffer);
|
|
|
- pSchemaElement->LinkEndChild(pComplexTypeElement);
|
|
|
-
|
|
|
- // Add sequence.
|
|
|
- tinyxml2::XMLElement* pAllElement = schemaDocument.NewElement("xs:all");
|
|
|
- pComplexTypeElement->LinkEndChild(pAllElement);
|
|
|
-
|
|
|
- // Fetch container child class.
|
|
|
- AbstractClassRep* pContainerChildClass = pType->getContainerChildClass(true);
|
|
|
-
|
|
|
- // Is the type allowed children?
|
|
|
- if (pContainerChildClass != NULL)
|
|
|
- {
|
|
|
- // Yes, so add choice element.
|
|
|
- tinyxml2::XMLElement* pChoiceElement = schemaDocument.NewElement("xs:choice");
|
|
|
- pChoiceElement->SetAttribute("minOccurs", 0);
|
|
|
- pChoiceElement->SetAttribute("maxOccurs", "unbounded");
|
|
|
- pAllElement->LinkEndChild(pChoiceElement);
|
|
|
+ // Yes, so add choice element.
|
|
|
+ tinyxml2::XMLElement* pChoiceElement = schemaDocument.NewElement("xs:choice");
|
|
|
+ pChoiceElement->SetAttribute("minOccurs", 0);
|
|
|
+ pChoiceElement->SetAttribute("maxOccurs", "unbounded");
|
|
|
+ pAllElement->LinkEndChild(pChoiceElement);
|
|
|
|
|
|
- // Find child group.
|
|
|
- HashTable<AbstractClassRep*, StringTableEntry>::Iterator childGroupItr = childGroups.find(pContainerChildClass);
|
|
|
+ // Find child group.
|
|
|
+ HashTable<AbstractClassRep*, StringTableEntry>::Iterator childGroupItr = childGroups.find(pContainerChildClass);
|
|
|
|
|
|
- // Does the group exist?
|
|
|
- if (childGroupItr == childGroups.end())
|
|
|
- {
|
|
|
- // No, so format group name.
|
|
|
- dSprintf(buffer, sizeof(buffer), "%s_ChildrenTypes", pContainerChildClass->getClassName());
|
|
|
+ // Does the group exist?
|
|
|
+ if (childGroupItr == childGroups.end())
|
|
|
+ {
|
|
|
+ // 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.
|
|
|
- tinyxml2::XMLElement* pChildrenGroupElement = schemaDocument.NewElement("xs:group");
|
|
|
- pChildrenGroupElement->SetAttribute("name", buffer);
|
|
|
- pSchemaElement->LinkEndChild(pChildrenGroupElement);
|
|
|
+ // Add the group.
|
|
|
+ tinyxml2::XMLElement* pChildrenGroupElement = schemaDocument.NewElement("xs:group");
|
|
|
+ pChildrenGroupElement->SetAttribute("name", buffer);
|
|
|
+ pSchemaElement->LinkEndChild(pChildrenGroupElement);
|
|
|
|
|
|
- // Add choice element.
|
|
|
- tinyxml2::XMLElement* pChildreGroupChoiceElement = schemaDocument.NewElement("xs:choice");
|
|
|
- pChildrenGroupElement->LinkEndChild(pChildreGroupChoiceElement);
|
|
|
+ // Add choice element.
|
|
|
+ tinyxml2::XMLElement* pChildreGroupChoiceElement = schemaDocument.NewElement("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 member.
|
|
|
- tinyxml2::XMLElement* pChildrenMemberElement = schemaDocument.NewElement("xs:element");
|
|
|
- pChildrenMemberElement->SetAttribute("name", pChoiceType->getClassName());
|
|
|
- dSprintf(buffer, sizeof(buffer), "%s_Type", pChoiceType->getClassName());
|
|
|
- pChildrenMemberElement->SetAttribute("type", buffer);
|
|
|
- pChildreGroupChoiceElement->LinkEndChild(pChildrenMemberElement);
|
|
|
- }
|
|
|
+ // 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.
|
|
|
+ tinyxml2::XMLElement* pChildrenMemberElement = schemaDocument.NewElement("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.
|
|
|
- tinyxml2::XMLElement* pChoiceGroupReferenceElement = schemaDocument.NewElement("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())
|
|
|
- {
|
|
|
- // Fetch the types custom TAML schema function.
|
|
|
- AbstractClassRep::WriteCustomTamlSchema customSchemaFn = pCustomSchemaType->getCustomTamlSchema();
|
|
|
+ // Reference the child group.
|
|
|
+ tinyxml2::XMLElement* pChoiceGroupReferenceElement = schemaDocument.NewElement("xs:group");
|
|
|
+ pChoiceGroupReferenceElement->SetAttribute("ref", childGroupItr->value);
|
|
|
+ pChoiceGroupReferenceElement->SetAttribute("minOccurs", 0);
|
|
|
+ pChoiceElement->LinkEndChild(pChoiceGroupReferenceElement);
|
|
|
+ }
|
|
|
|
|
|
- // Skip if no function avilable.
|
|
|
- if (customSchemaFn == NULL)
|
|
|
- continue;
|
|
|
+ // 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();
|
|
|
|
|
|
- // Call schema generation function.
|
|
|
- customSchemaFn(pType, pAllElement);
|
|
|
- }
|
|
|
+ // Skip if no function avilable.
|
|
|
+ if (customSchemaFn == NULL)
|
|
|
+ continue;
|
|
|
|
|
|
- // Fetch field list.
|
|
|
- const AbstractClassRep::FieldList& fields = pType->mFieldList;
|
|
|
+ // Call schema generation function.
|
|
|
+ customSchemaFn(pType, pAllElement);
|
|
|
+ }
|
|
|
|
|
|
- // Fetch field count.
|
|
|
- const S32 fieldCount = fields.size();
|
|
|
+ // Fetch field list.
|
|
|
+ const AbstractClassRep::FieldList& fields = pType->mFieldList;
|
|
|
|
|
|
- // Generate array attribute groups
|
|
|
- for (S32 index = 0; index < fieldCount; ++index)
|
|
|
- {
|
|
|
- // Fetch field.
|
|
|
- const AbstractClassRep::Field& field = fields[index];
|
|
|
+ // Fetch field count.
|
|
|
+ const S32 fieldCount = fields.size();
|
|
|
+
|
|
|
+ // Generate array attribute groups
|
|
|
+ for (S32 index = 0; index < fieldCount; ++index)
|
|
|
+ {
|
|
|
+ // Fetch field.
|
|
|
+ const AbstractClassRep::Field& field = fields[index];
|
|
|
|
|
|
- if (field.type == AbstractClassRep::StartArrayFieldType)
|
|
|
+ if (field.type == AbstractClassRep::StartArrayFieldType)
|
|
|
+ {
|
|
|
+ // Add the top-level array identifier
|
|
|
+ tinyxml2::XMLElement* pArrayElement = schemaDocument.NewElement("xs:element");
|
|
|
+ dSprintf(buffer, sizeof(buffer), "%s.%s", pType->getClassName(), g_sanitize_schema_element_name(field.pGroupname).c_str());
|
|
|
+ pArrayElement->SetAttribute("name", buffer);
|
|
|
+ pArrayElement->SetAttribute("minOccurs", 0);
|
|
|
+ pAllElement->LinkEndChild(pArrayElement);
|
|
|
+
|
|
|
+ // Inline type specification
|
|
|
+ tinyxml2::XMLElement* pArrayComplexTypeElement = schemaDocument.NewElement("xs:complexType");
|
|
|
+ pArrayElement->LinkEndChild(pArrayComplexTypeElement);
|
|
|
+
|
|
|
+ // Add the actual (repeating) array elements
|
|
|
+ tinyxml2::XMLElement* pInnerArrayElement = schemaDocument.NewElement("xs:element");
|
|
|
+ pInnerArrayElement->SetAttribute("name", g_sanitize_schema_element_name(field.pFieldname).c_str());
|
|
|
+ pInnerArrayElement->SetAttribute("minOccurs", 0);
|
|
|
+ pInnerArrayElement->SetAttribute("maxOccurs", field.elementCount);
|
|
|
+ pArrayComplexTypeElement->LinkEndChild(pInnerArrayElement);
|
|
|
+
|
|
|
+ // Inline type specification
|
|
|
+ tinyxml2::XMLElement* pInnerComplexTypeElement = schemaDocument.NewElement("xs:complexType");
|
|
|
+ pInnerArrayElement->LinkEndChild(pInnerComplexTypeElement);
|
|
|
+
|
|
|
+ // Add a reference to the attribute group for the array
|
|
|
+ tinyxml2::XMLElement* pInnerAttributeGroupElement = schemaDocument.NewElement("xs:attributeGroup");
|
|
|
+ dSprintf(buffer, sizeof(buffer), "%s_%s_Array_Fields", pType->getClassName(), g_sanitize_schema_element_name(field.pFieldname).c_str());
|
|
|
+ pInnerAttributeGroupElement->SetAttribute("ref", buffer);
|
|
|
+ pInnerComplexTypeElement->LinkEndChild(pInnerAttributeGroupElement);
|
|
|
+
|
|
|
+ // Add the attribute group itself
|
|
|
+ tinyxml2::XMLElement* pFieldAttributeGroupElement = schemaDocument.NewElement("xs:attributeGroup");
|
|
|
+ pFieldAttributeGroupElement->SetAttribute("name", buffer);
|
|
|
+ pSchemaElement->LinkEndChild(pFieldAttributeGroupElement);
|
|
|
+
|
|
|
+ // Keep adding fields to attribute group until we hit the end of the array
|
|
|
+ for (; index < fieldCount; ++index)
|
|
|
{
|
|
|
- // Add the top-level array identifier
|
|
|
- tinyxml2::XMLElement* pArrayElement = schemaDocument.NewElement("xs:element");
|
|
|
- dSprintf(buffer, sizeof(buffer), "%s.%s", pType->getClassName(), g_sanitize_schema_element_name(field.pGroupname).c_str());
|
|
|
- pArrayElement->SetAttribute("name", buffer);
|
|
|
- pArrayElement->SetAttribute("minOccurs", 0);
|
|
|
- pAllElement->LinkEndChild(pArrayElement);
|
|
|
-
|
|
|
- // Inline type specification
|
|
|
- tinyxml2::XMLElement* pArrayComplexTypeElement = schemaDocument.NewElement("xs:complexType");
|
|
|
- pArrayElement->LinkEndChild(pArrayComplexTypeElement);
|
|
|
-
|
|
|
- // Add the actual (repeating) array elements
|
|
|
- tinyxml2::XMLElement* pInnerArrayElement = schemaDocument.NewElement("xs:element");
|
|
|
- pInnerArrayElement->SetAttribute("name", g_sanitize_schema_element_name(field.pFieldname).c_str());
|
|
|
- pInnerArrayElement->SetAttribute("minOccurs", 0);
|
|
|
- pInnerArrayElement->SetAttribute("maxOccurs", field.elementCount);
|
|
|
- pArrayComplexTypeElement->LinkEndChild(pInnerArrayElement);
|
|
|
-
|
|
|
- // Inline type specification
|
|
|
- tinyxml2::XMLElement* pInnerComplexTypeElement = schemaDocument.NewElement("xs:complexType");
|
|
|
- pInnerArrayElement->LinkEndChild(pInnerComplexTypeElement);
|
|
|
-
|
|
|
- // Add a reference to the attribute group for the array
|
|
|
- tinyxml2::XMLElement* pInnerAttributeGroupElement = schemaDocument.NewElement("xs:attributeGroup");
|
|
|
- dSprintf(buffer, sizeof(buffer), "%s_%s_Array_Fields", pType->getClassName(), g_sanitize_schema_element_name(field.pFieldname).c_str());
|
|
|
- pInnerAttributeGroupElement->SetAttribute("ref", buffer);
|
|
|
- pInnerComplexTypeElement->LinkEndChild(pInnerAttributeGroupElement);
|
|
|
-
|
|
|
- // Add the attribute group itself
|
|
|
- tinyxml2::XMLElement* pFieldAttributeGroupElement = schemaDocument.NewElement("xs:attributeGroup");
|
|
|
- pFieldAttributeGroupElement->SetAttribute("name", buffer);
|
|
|
- pSchemaElement->LinkEndChild(pFieldAttributeGroupElement);
|
|
|
-
|
|
|
- // Keep adding fields to attribute group until we hit the end of the array
|
|
|
- for (; index < fieldCount; ++index)
|
|
|
+ const AbstractClassRep::Field& array_field = fields[index];
|
|
|
+ if (array_field.type == AbstractClassRep::EndArrayFieldType)
|
|
|
{
|
|
|
- const AbstractClassRep::Field& array_field = fields[index];
|
|
|
- if (array_field.type == AbstractClassRep::EndArrayFieldType)
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- tinyxml2::XMLElement* pAttributeElement = g__write_schema_attribute_element(array_field, pType, schemaDocument);
|
|
|
- if (pAttributeElement == NULL)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- pFieldAttributeGroupElement->LinkEndChild(pAttributeElement);
|
|
|
+ tinyxml2::XMLElement* pAttributeElement = g__write_schema_attribute_element(array_field, pType, schemaDocument);
|
|
|
+ if (pAttributeElement == NULL)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
}
|
|
|
+
|
|
|
+ pFieldAttributeGroupElement->LinkEndChild(pAttributeElement);
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- // Generate field attribute group.
|
|
|
- tinyxml2::XMLElement* pFieldAttributeGroupElement = schemaDocument.NewElement("xs:attributeGroup");
|
|
|
- dSprintf(buffer, sizeof(buffer), "%s_Fields", pType->getClassName());
|
|
|
- pFieldAttributeGroupElement->SetAttribute("name", buffer);
|
|
|
- pSchemaElement->LinkEndChild(pFieldAttributeGroupElement);
|
|
|
+ // Generate field attribute group.
|
|
|
+ tinyxml2::XMLElement* pFieldAttributeGroupElement = schemaDocument.NewElement("xs:attributeGroup");
|
|
|
+ dSprintf(buffer, sizeof(buffer), "%s_Fields", pType->getClassName());
|
|
|
+ pFieldAttributeGroupElement->SetAttribute("name", buffer);
|
|
|
+ pSchemaElement->LinkEndChild(pFieldAttributeGroupElement);
|
|
|
|
|
|
- // 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];
|
|
|
+ // 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 fields inside arrays
|
|
|
- if (field.type == AbstractClassRep::EndArrayFieldType)
|
|
|
+ // Skip fields inside arrays
|
|
|
+ if (field.type == AbstractClassRep::EndArrayFieldType)
|
|
|
+ {
|
|
|
+ for (; index > 0; --index)
|
|
|
{
|
|
|
- for (; index > 0; --index)
|
|
|
+ if (field.type == AbstractClassRep::StartArrayFieldType)
|
|
|
{
|
|
|
- if (field.type == AbstractClassRep::StartArrayFieldType)
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
+ break;
|
|
|
}
|
|
|
- continue;
|
|
|
}
|
|
|
-
|
|
|
- tinyxml2::XMLElement* pAttributeElement = g__write_schema_attribute_element(field, pType, schemaDocument);
|
|
|
- if (pAttributeElement == NULL)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- pFieldAttributeGroupElement->LinkEndChild(pAttributeElement);
|
|
|
- }
|
|
|
-
|
|
|
- // Is this the SimObject Type?
|
|
|
- if (pType == pSimObjectType)
|
|
|
- {
|
|
|
- // Yes, so add reserved Taml field attributes here...
|
|
|
-
|
|
|
- // Add Taml "Name" attribute element.
|
|
|
- tinyxml2::XMLElement* pNameAttributeElement = schemaDocument.NewElement("xs:attribute");
|
|
|
- pNameAttributeElement->SetAttribute("name", tamlNamedObjectName);
|
|
|
- pNameAttributeElement->SetAttribute("type", "xs:normalizedString");
|
|
|
- pFieldAttributeGroupElement->LinkEndChild(pNameAttributeElement);
|
|
|
-
|
|
|
- // Add Taml "TamlId" attribute element.
|
|
|
- tinyxml2::XMLElement* pTamlIdAttributeElement = schemaDocument.NewElement("xs:attribute");
|
|
|
- pTamlIdAttributeElement->SetAttribute("name", tamlRefIdName);
|
|
|
- pTamlIdAttributeElement->SetAttribute("type", "xs:nonNegativeInteger");
|
|
|
- pFieldAttributeGroupElement->LinkEndChild(pTamlIdAttributeElement);
|
|
|
-
|
|
|
- // Add Taml "TamlRefId" attribute element.
|
|
|
- tinyxml2::XMLElement* pTamlRefIdAttributeElement = schemaDocument.NewElement("xs:attribute");
|
|
|
- pTamlRefIdAttributeElement->SetAttribute("name", tamlRefToIdName);
|
|
|
- pTamlRefIdAttributeElement->SetAttribute("type", "xs:nonNegativeInteger");
|
|
|
- pFieldAttributeGroupElement->LinkEndChild(pTamlRefIdAttributeElement);
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
- // Add attribute group types.
|
|
|
- for (AbstractClassRep* pAttributeGroupsType = pType; pAttributeGroupsType != NULL; pAttributeGroupsType = pAttributeGroupsType->getParentClass())
|
|
|
+ tinyxml2::XMLElement* pAttributeElement = g__write_schema_attribute_element(field, pType, schemaDocument);
|
|
|
+ if (pAttributeElement == NULL)
|
|
|
{
|
|
|
- tinyxml2::XMLElement* pFieldAttributeGroupRefElement = schemaDocument.NewElement("xs:attributeGroup");
|
|
|
- dSprintf(buffer, sizeof(buffer), "%s_Fields", pAttributeGroupsType->getClassName());
|
|
|
- pFieldAttributeGroupRefElement->SetAttribute("ref", buffer);
|
|
|
- pComplexTypeElement->LinkEndChild(pFieldAttributeGroupRefElement);
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
- // Add "any" attribute element (dynamic fields).
|
|
|
- tinyxml2::XMLElement* pAnyAttributeElement = schemaDocument.NewElement("xs:anyAttribute");
|
|
|
- pAnyAttributeElement->SetAttribute("processContents", "skip");
|
|
|
- pComplexTypeElement->LinkEndChild(pAnyAttributeElement);
|
|
|
+ pFieldAttributeGroupElement->LinkEndChild(pAttributeElement);
|
|
|
}
|
|
|
|
|
|
- // Write the schema document.
|
|
|
- schemaDocument.SaveFile(filePathBuffer);
|
|
|
+ // Is this the SimObject Type?
|
|
|
+ if (pType == pSimObjectType)
|
|
|
+ {
|
|
|
+ // Yes, so add reserved Taml field attributes here...
|
|
|
+
|
|
|
+ // Add Taml "Name" attribute element.
|
|
|
+ tinyxml2::XMLElement* pNameAttributeElement = schemaDocument.NewElement("xs:attribute");
|
|
|
+ pNameAttributeElement->SetAttribute("name", tamlNamedObjectName);
|
|
|
+ pNameAttributeElement->SetAttribute("type", "xs:normalizedString");
|
|
|
+ pFieldAttributeGroupElement->LinkEndChild(pNameAttributeElement);
|
|
|
+
|
|
|
+ // Add Taml "TamlId" attribute element.
|
|
|
+ tinyxml2::XMLElement* pTamlIdAttributeElement = schemaDocument.NewElement("xs:attribute");
|
|
|
+ pTamlIdAttributeElement->SetAttribute("name", tamlRefIdName);
|
|
|
+ pTamlIdAttributeElement->SetAttribute("type", "xs:nonNegativeInteger");
|
|
|
+ pFieldAttributeGroupElement->LinkEndChild(pTamlIdAttributeElement);
|
|
|
+
|
|
|
+ // Add Taml "TamlRefId" attribute element.
|
|
|
+ tinyxml2::XMLElement* pTamlRefIdAttributeElement = schemaDocument.NewElement("xs:attribute");
|
|
|
+ pTamlRefIdAttributeElement->SetAttribute("name", tamlRefToIdName);
|
|
|
+ pTamlRefIdAttributeElement->SetAttribute("type", "xs:nonNegativeInteger");
|
|
|
+ pFieldAttributeGroupElement->LinkEndChild(pTamlRefIdAttributeElement);
|
|
|
+ }
|
|
|
|
|
|
- // Close file.
|
|
|
- stream.close();
|
|
|
+ // Add attribute group types.
|
|
|
+ for (AbstractClassRep* pAttributeGroupsType = pType; pAttributeGroupsType != NULL; pAttributeGroupsType = pAttributeGroupsType->getParentClass())
|
|
|
+ {
|
|
|
+ tinyxml2::XMLElement* pFieldAttributeGroupRefElement = schemaDocument.NewElement("xs:attributeGroup");
|
|
|
+ dSprintf(buffer, sizeof(buffer), "%s_Fields", pAttributeGroupsType->getClassName());
|
|
|
+ pFieldAttributeGroupRefElement->SetAttribute("ref", buffer);
|
|
|
+ pComplexTypeElement->LinkEndChild(pFieldAttributeGroupRefElement);
|
|
|
+ }
|
|
|
|
|
|
- return true;
|
|
|
+ // Add "any" attribute element (dynamic fields).
|
|
|
+ tinyxml2::XMLElement* pAnyAttributeElement = schemaDocument.NewElement("xs:anyAttribute");
|
|
|
+ pAnyAttributeElement->SetAttribute("processContents", "skip");
|
|
|
+ pComplexTypeElement->LinkEndChild(pAnyAttributeElement);
|
|
|
}
|
|
|
|
|
|
- //-----------------------------------------------------------------------------
|
|
|
+ // Write the schema document.
|
|
|
+ schemaDocument.SaveFile(filePathBuffer);
|
|
|
|
|
|
- void Taml::WriteUnrestrictedCustomTamlSchema(const char* pCustomNodeName, const AbstractClassRep* pClassRep, tinyxml2::XMLElement* 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.");
|
|
|
-
|
|
|
- tinyxml2::XMLDocument* doc = pParentElement->GetDocument();
|
|
|
-
|
|
|
- char buffer[1024];
|
|
|
-
|
|
|
- // Add custom type element.
|
|
|
- tinyxml2::XMLElement* pCustomElement = doc->NewElement("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.
|
|
|
- tinyxml2::XMLElement* pComplexTypeElement = doc->NewElement("xs:complexType");
|
|
|
- pCustomElement->LinkEndChild(pComplexTypeElement);
|
|
|
-
|
|
|
- // Add choice element.
|
|
|
- tinyxml2::XMLElement* pChoiceElement = doc->NewElement("xs:choice");
|
|
|
- pChoiceElement->SetAttribute("minOccurs", 0);
|
|
|
- pChoiceElement->SetAttribute("maxOccurs", "unbounded");
|
|
|
- pComplexTypeElement->LinkEndChild(pChoiceElement);
|
|
|
-
|
|
|
- // Add sequence element.
|
|
|
- tinyxml2::XMLElement* pSequenceElement = doc->NewElement("xs:sequence");
|
|
|
- pChoiceElement->LinkEndChild(pSequenceElement);
|
|
|
-
|
|
|
- // Add "any" element.
|
|
|
- tinyxml2::XMLElement* pAnyElement = doc->NewElement("xs:any");
|
|
|
- pAnyElement->SetAttribute("processContents", "skip");
|
|
|
- pSequenceElement->LinkEndChild(pAnyElement);
|
|
|
- }
|
|
|
+ // Close file.
|
|
|
+ stream.close();
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+
|
|
|
+void Taml::WriteUnrestrictedCustomTamlSchema(const char* pCustomNodeName, const AbstractClassRep* pClassRep, tinyxml2::XMLElement* 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.");
|
|
|
+
|
|
|
+ tinyxml2::XMLDocument* doc = pParentElement->GetDocument();
|
|
|
+
|
|
|
+ char buffer[1024];
|
|
|
+
|
|
|
+ // Add custom type element.
|
|
|
+ tinyxml2::XMLElement* pCustomElement = doc->NewElement("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.
|
|
|
+ tinyxml2::XMLElement* pComplexTypeElement = doc->NewElement("xs:complexType");
|
|
|
+ pCustomElement->LinkEndChild(pComplexTypeElement);
|
|
|
+
|
|
|
+ // Add choice element.
|
|
|
+ tinyxml2::XMLElement* pChoiceElement = doc->NewElement("xs:choice");
|
|
|
+ pChoiceElement->SetAttribute("minOccurs", 0);
|
|
|
+ pChoiceElement->SetAttribute("maxOccurs", "unbounded");
|
|
|
+ pComplexTypeElement->LinkEndChild(pChoiceElement);
|
|
|
+
|
|
|
+ // Add sequence element.
|
|
|
+ tinyxml2::XMLElement* pSequenceElement = doc->NewElement("xs:sequence");
|
|
|
+ pChoiceElement->LinkEndChild(pSequenceElement);
|
|
|
+
|
|
|
+ // Add "any" element.
|
|
|
+ tinyxml2::XMLElement* pAnyElement = doc->NewElement("xs:any");
|
|
|
+ pAnyElement->SetAttribute("processContents", "skip");
|
|
|
+ pSequenceElement->LinkEndChild(pAnyElement);
|
|
|
+}
|