Dump structured data def structs

This commit is contained in:
Jan 2022-01-15 23:14:37 +01:00
parent 02769fe21d
commit 0aad5a42cb
5 changed files with 210 additions and 7 deletions

View File

@ -2031,7 +2031,8 @@ namespace IW4
DATA_ENUM_ARRAY = 0x7, DATA_ENUM_ARRAY = 0x7,
DATA_FLOAT = 0x8, DATA_FLOAT = 0x8,
DATA_SHORT = 0x9, DATA_SHORT = 0x9,
DATA_COUNT = 0xA,
DATA_COUNT
}; };
struct StructuredDataEnumEntry struct StructuredDataEnumEntry

View File

@ -83,7 +83,7 @@ void StructuredDataDefDumper::EndEnum()
m_stream << ",\n"; m_stream << ",\n";
Indent(); Indent();
m_stream << entry; m_stream << "\"" << entry << "\"";
} }
if (!firstEntry) if (!firstEntry)
@ -94,6 +94,7 @@ void StructuredDataDefDumper::EndEnum()
m_stream << "};\n"; m_stream << "};\n";
m_block = Block::BLOCK_NONE; m_block = Block::BLOCK_NONE;
m_flags.m_empty_line_before_block = true; m_flags.m_empty_line_before_block = true;
m_enum_entries.clear();
} }
void StructuredDataDefDumper::WriteEnumEntry(const std::string& entryName, const size_t entryValue) void StructuredDataDefDumper::WriteEnumEntry(const std::string& entryName, const size_t entryValue)
@ -141,3 +142,50 @@ void StructuredDataDefDumper::EndStruct()
m_block = Block::BLOCK_NONE; m_block = Block::BLOCK_NONE;
m_flags.m_empty_line_before_block = true; m_flags.m_empty_line_before_block = true;
} }
void StructuredDataDefDumper::BeginProperty(const std::string& propertyName)
{
assert(m_flags.m_in_version);
assert(m_block == Block::BLOCK_STRUCT);
if (m_block != Block::BLOCK_STRUCT)
return;
m_property_name = propertyName;
m_block = Block::BLOCK_PROPERTY;
}
void StructuredDataDefDumper::AddPropertyArraySpecifier(const std::string& specifierName)
{
m_property_array_specifiers.emplace_back(specifierName);
}
void StructuredDataDefDumper::SetPropertyTypeName(const std::string& typeName)
{
m_property_type_name = typeName;
}
void StructuredDataDefDumper::EndProperty()
{
assert(m_block == Block::BLOCK_PROPERTY);
if (m_block != Block::BLOCK_PROPERTY)
return;
Indent();
m_stream << m_property_type_name << " " << m_property_name;
for(const auto& arraySpecifierName : m_property_array_specifiers)
{
m_stream << "[" << arraySpecifierName << "]";
}
m_stream << ";\n";
m_block = Block::BLOCK_STRUCT;
m_property_array_specifiers.clear();
m_property_name = std::string();
m_property_type_name = std::string();
}

View File

@ -10,7 +10,8 @@ class StructuredDataDefDumper : AbstractTextDumper
{ {
BLOCK_NONE = 0, BLOCK_NONE = 0,
BLOCK_ENUM = 1, BLOCK_ENUM = 1,
BLOCK_STRUCT = 2 BLOCK_STRUCT = 2,
BLOCK_PROPERTY = 3
} m_block; } m_block;
struct struct
@ -23,6 +24,10 @@ class StructuredDataDefDumper : AbstractTextDumper
std::vector<std::string> m_enum_entries; std::vector<std::string> m_enum_entries;
size_t m_enum_size; size_t m_enum_size;
std::string m_property_name;
std::string m_property_type_name;
std::vector<std::string> m_property_array_specifiers;
public: public:
explicit StructuredDataDefDumper(std::ostream& stream); explicit StructuredDataDefDumper(std::ostream& stream);
@ -35,4 +40,8 @@ public:
void BeginStruct(const std::string& structName); void BeginStruct(const std::string& structName);
void EndStruct(); void EndStruct();
void BeginProperty(const std::string& propertyName);
void AddPropertyArraySpecifier(const std::string& specifierName);
void SetPropertyTypeName(const std::string& typeName);
void EndProperty();
}; };

View File

@ -36,6 +36,146 @@ void AssetDumperStructuredDataDefSet::DumpEnum(StructuredDataDefDumper& dumper,
dumper.EndEnum(); dumper.EndEnum();
} }
void AssetDumperStructuredDataDefSet::DumpProperty(StructuredDataDefDumper& dumper, const StructuredDataStructProperty& property, const StructuredDataDef* def, const int rootStructIndex)
{
dumper.BeginProperty(property.name);
auto currentType = property.type;
auto stopTypeIteration = false;
do
{
switch (currentType.type)
{
case DATA_INT:
dumper.SetPropertyTypeName("int");
stopTypeIteration = true;
break;
case DATA_BYTE:
dumper.SetPropertyTypeName("byte");
stopTypeIteration = true;
break;
case DATA_BOOL:
dumper.SetPropertyTypeName("bool");
stopTypeIteration = true;
break;
case DATA_FLOAT:
dumper.SetPropertyTypeName("float");
stopTypeIteration = true;
break;
case DATA_SHORT:
dumper.SetPropertyTypeName("short");
stopTypeIteration = true;
break;
case DATA_STRING:
{
std::ostringstream ss;
ss << "string(" << currentType.u.stringDataLength << ")";
dumper.SetPropertyTypeName(ss.str());
stopTypeIteration = true;
break;
}
case DATA_ENUM:
{
std::ostringstream ss;
ss << "ENUM_" << currentType.u.enumIndex;
dumper.SetPropertyTypeName(ss.str());
stopTypeIteration = true;
break;
}
case DATA_STRUCT:
{
if (currentType.u.structIndex == rootStructIndex)
{
dumper.SetPropertyTypeName("root");
}
else
{
std::ostringstream ss;
ss << "STRUCT_" << currentType.u.enumIndex;
dumper.SetPropertyTypeName(ss.str());
}
stopTypeIteration = true;
break;
}
case DATA_INDEXED_ARRAY:
{
if (def->indexedArrays == nullptr
|| currentType.u.indexedArrayIndex < 0
|| currentType.u.indexedArrayIndex >= def->indexedArrayCount)
{
assert(false);
dumper.SetPropertyTypeName("ERRORTYPE");
stopTypeIteration = true;
}
else
{
const auto& indexedArray = def->indexedArrays[currentType.u.indexedArrayIndex];
dumper.AddPropertyArraySpecifier(std::to_string(indexedArray.arraySize));
currentType = indexedArray.elementType;
}
break;
}
case DATA_ENUM_ARRAY:
{
if (def->enumedArrays == nullptr
|| currentType.u.enumedArrayIndex < 0
|| currentType.u.enumedArrayIndex >= def->enumedArrayCount)
{
assert(false);
dumper.SetPropertyTypeName("ERRORTYPE");
stopTypeIteration = true;
}
else
{
const auto& enumedArray = def->enumedArrays[currentType.u.enumedArrayIndex];
std::ostringstream ss;
ss << "ENUM_" << enumedArray.enumIndex;
dumper.AddPropertyArraySpecifier(ss.str());
currentType = enumedArray.elementType;
}
break;
}
default:
break;
}
}
while (!stopTypeIteration);
dumper.EndProperty();
}
void AssetDumperStructuredDataDefSet::DumpStruct(StructuredDataDefDumper& dumper, const int structIndex, const StructuredDataStruct* _struct, const StructuredDataDef* def, const bool isRoot)
{
if (!_struct->properties || _struct->propertyCount <= 0)
return;
std::string structName;
if (isRoot)
{
structName = "root";
}
else
{
std::ostringstream ss;
ss << "STRUCT_" << structIndex;
structName = ss.str();
}
dumper.BeginStruct(structName);
const auto rootStructIndex = def->rootType.type == DATA_STRUCT ? def->rootType.u.structIndex : -1;
for (auto i = 0; i < _struct->propertyCount; i++)
{
const auto& property = _struct->properties[i];
DumpProperty(dumper, property, def, rootStructIndex);
}
dumper.EndStruct();
}
void AssetDumperStructuredDataDefSet::DumpAsset(AssetDumpingContext& context, XAssetInfo<StructuredDataDefSet>* asset) void AssetDumperStructuredDataDefSet::DumpAsset(AssetDumpingContext& context, XAssetInfo<StructuredDataDefSet>* asset)
{ {
const auto* set = asset->Asset(); const auto* set = asset->Asset();
@ -55,7 +195,10 @@ void AssetDumperStructuredDataDefSet::DumpAsset(AssetDumpingContext& context, XA
for (auto enumIndex = 0; enumIndex < def.enumCount; enumIndex++) for (auto enumIndex = 0; enumIndex < def.enumCount; enumIndex++)
DumpEnum(dumper, enumIndex, &def.enums[enumIndex]); DumpEnum(dumper, enumIndex, &def.enums[enumIndex]);
// TODO const auto rootStructIndex = def.rootType.type == DATA_STRUCT ? def.rootType.u.structIndex : -1;
assert(rootStructIndex >= 0);
for (auto structIndex = 0; structIndex < def.structCount; structIndex++)
DumpStruct(dumper, structIndex, &def.structs[structIndex], &def, structIndex == rootStructIndex);
dumper.EndVersion(); dumper.EndVersion();
} }

View File

@ -9,6 +9,8 @@ namespace IW4
class AssetDumperStructuredDataDefSet final : public AbstractAssetDumper<StructuredDataDefSet> class AssetDumperStructuredDataDefSet final : public AbstractAssetDumper<StructuredDataDefSet>
{ {
static void DumpEnum(StructuredDataDefDumper& dumper, int enumIndex, const StructuredDataEnum* _enum); static void DumpEnum(StructuredDataDefDumper& dumper, int enumIndex, const StructuredDataEnum* _enum);
static void DumpProperty(StructuredDataDefDumper& dumper, const StructuredDataStructProperty& property, const StructuredDataDef* def, int rootStructIndex);
static void DumpStruct(StructuredDataDefDumper& dumper, int structIndex, const StructuredDataStruct* _struct, const StructuredDataDef* def, bool isRoot);
protected: protected:
bool ShouldDump(XAssetInfo<StructuredDataDefSet>* asset) override; bool ShouldDump(XAssetInfo<StructuredDataDefSet>* asset) override;