diff --git a/src/dependency/minidef/src/CppGen.cpp b/src/dependency/minidef/src/CppGen.cpp index 3b57a06..c2cde21 100644 --- a/src/dependency/minidef/src/CppGen.cpp +++ b/src/dependency/minidef/src/CppGen.cpp @@ -26,9 +26,10 @@ namespace Generated { )END"; - constexpr char StructHeader1[] = + constexpr char StructHeader2[] = R"END( struct %s { + static constexpr uint32_t Hash = %u; )END"; constexpr char StructField4[] = @@ -39,9 +40,10 @@ namespace Generated R"END( }; )END"; - constexpr char EnumHeader3[] = + constexpr char EnumHeader4[] = R"END( struct %s { + static constexpr uint32_t Hash = %u; static constexpr int32_t EntryCount = %u; enum Enum : %s { @@ -192,8 +194,11 @@ void CppFileWriter::WriteEnums(const Def::DefinitionFile& definitions) { const Def::Enum& e = definitions.Enums[enumIdx]; - Write( - WriteTemplates::EnumHeader3, e.Name, e.EntryCount, Generated::KnownType::CName[(int32_t)e.EnumType.Native]); + Write(WriteTemplates::EnumHeader4, + e.Name, + e.Hash, + e.EntryCount, + Generated::KnownType::CName[(int32_t)e.EnumType.Native]); for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx) { Write(WriteTemplates::EnumField1, e.EntryNames[entryIdx]); @@ -223,7 +228,7 @@ void CppFileWriter::WriteTypes(const Def::DefinitionFile& definitions) { const Def::Type& t = definitions.Types[typeIdx]; - Write(WriteTemplates::StructHeader1, t.Name); + Write(WriteTemplates::StructHeader2, t.Name, t.Hash); for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx) { char Type[64]{0}; @@ -234,7 +239,7 @@ void CppFileWriter::WriteTypes(const Def::DefinitionFile& definitions) { bx::snprintf(Array, sizeof(Array), "[%u]", ArraySize); } - Write(WriteTemplates::StructField4, Type, t.FieldNames[fieldIdx], Array, t.FieldVaules[fieldIdx]); + Write(WriteTemplates::StructField4, Type, t.FieldNames[fieldIdx], Array, t.FieldValues[fieldIdx]); } Write(WriteTemplates::StructEnd); } diff --git a/src/dependency/minidef/src/MiniDef.cpp b/src/dependency/minidef/src/MiniDef.cpp index bd53932..c837fa6 100644 --- a/src/dependency/minidef/src/MiniDef.cpp +++ b/src/dependency/minidef/src/MiniDef.cpp @@ -3,6 +3,8 @@ #include "Logging.h" #include "MiniDef.h" +#include "TypeDef.h" +#include "bx/hash.h" #include "bx/string.h" #include #include @@ -165,7 +167,7 @@ Parser::Result Parser::HandleType() Def::Type& t = Definitions.Types[Definitions.TypeCount]; for (int32_t i = 0; i < Def::MaxFields; ++i) { - bx::strCopy(t.FieldVaules[i], sizeof(t.FieldVaules[i]), "{}"); + bx::strCopy(t.FieldValues[i], sizeof(t.FieldValues[i]), "{}"); } CHECK(ReadName(t.Name)); @@ -203,11 +205,11 @@ Parser::Result Parser::HandleType() CHECK(ExpectChar("(")); CHECK(ExpectChar("\"")); - int32_t Remaining = bx::min(GetRemaining(), (int32_t)BX_COUNTOF(Def::Type::FieldVaules[0])); + int32_t Remaining = bx::min(GetRemaining(), (int32_t)BX_COUNTOF(Def::Type::FieldValues[0])); for (int32_t i = 0; i < Remaining; ++i) { if (*ReadPtr != '\\' && CmpAdvance("\"", Res)) break; - t.FieldVaules[t.FieldCount][i] = *ReadPtr; + t.FieldValues[t.FieldCount][i] = *ReadPtr; ReadPtr++; } if (Res != OK) return Res; @@ -404,7 +406,7 @@ Parser::Result Parser::ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx) for (int32_t i = 0; i < Remaining; ++i) { if (CmpAdvance("\"", Res)) break; - Enum.ExtraStringFields[extraIdx][EntryIdx][i] = *ReadPtr; + Enum.ExtraStringFields[EntryIdx][extraIdx][i] = *ReadPtr; ReadPtr++; } if (Res != OK) return Res; @@ -425,6 +427,59 @@ int32_t Parser::GetRemaining() { return &Buffer[BufferSize] - ReadPtr; } +uint32_t Parser::CalculateTypeHash(const Def::Type& t) +{ + bx::HashMurmur2A hash; + hash.begin(); + for (int32_t i = 0; i < t.FieldCount; ++i) + { + hash.add(t.FieldNames[i]); + hash.add(t.FieldArraySizes[i]); + + Def::EFieldType fieldType = t.FieldTypes[i].FieldKind; + if (fieldType == Def::EFieldType::Native) + { + hash.add(t.FieldTypes[i].Native); + } + else if (fieldType == Def::EFieldType::DefinedClass) + { + Def::Type& dependType = Definitions.Types[t.FieldTypes[i].TypeIdx]; + if (dependType.Hash == 0) + { + CalculateTypeHash(dependType); + } + hash.add(dependType.Hash); + } + else if (fieldType == Def::EFieldType::DefinedEnum) + { + hash.add(Definitions.Enums[t.FieldTypes[i].TypeIdx].Hash); + } + else + { + LOG_ERROR(0, "TODO!"); + } + } + return hash.end(); +} +void Parser::CalculateHashes() +{ + for (int32_t i = 0; i < Definitions.EnumCount; ++i) + { + Def::Enum& e = Definitions.Enums[i]; + bx::HashMurmur2A hash; + hash.begin(); + hash.add(e.EnumType.Native); + e.Hash = hash.end(); + } + for (int32_t i = 0; i < Definitions.TypeCount; ++i) + { + Def::Type& t = Definitions.Types[i]; + if (t.Hash == 0) + { + t.Hash = CalculateTypeHash(t); + } + } +} Parser FileParser; CppFileWriter Writer; @@ -460,6 +515,8 @@ int main(int argc, const char** argv) return 1; } LOG(0, "Finished parsing!"); + + FileParser.CalculateHashes(); Writer.GenerateCpp(outPath, FileParser.Definitions); return 0; diff --git a/src/dependency/minidef/src/MiniDef.h b/src/dependency/minidef/src/MiniDef.h index 905cc0b..d11370c 100644 --- a/src/dependency/minidef/src/MiniDef.h +++ b/src/dependency/minidef/src/MiniDef.h @@ -76,6 +76,7 @@ class Parser public: Result Parse(); + void CalculateHashes(); private: int32_t GetRemaining(); @@ -94,6 +95,8 @@ class Parser Result ReadTypeToken(); Result ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx); + uint32_t CalculateTypeHash(const Def::Type& t); + void ErrorLine() { char line[64]{0}; diff --git a/src/dependency/minidef/src/TypeDef.h b/src/dependency/minidef/src/TypeDef.h index 7e703f0..b752fac 100644 --- a/src/dependency/minidef/src/TypeDef.h +++ b/src/dependency/minidef/src/TypeDef.h @@ -6,7 +6,7 @@ namespace Def { constexpr int32_t MaxNameLength = 64; constexpr int32_t MaxFields = 64; - constexpr int32_t MaxExtraEnumFields = 1; + constexpr int32_t MaxExtraEnumFields = 2; enum class EFieldType { Native, @@ -26,8 +26,9 @@ namespace Def FieldType FieldTypes[MaxFields]; char FieldNames[MaxFields][MaxNameLength]; uint32_t FieldArraySizes[MaxFields]{0}; - char FieldVaules[MaxFields][128]{0}; + char FieldValues[MaxFields][128]{0}; char Name[MaxNameLength]{0}; + uint32_t Hash = 0; }; struct Enum @@ -39,6 +40,7 @@ namespace Def char ExtraStringFieldNames[MaxExtraEnumFields][MaxNameLength]; char ExtraStringFields[MaxFields][MaxExtraEnumFields][MaxNameLength]; char Name[MaxNameLength]{0}; + uint32_t Hash = 0; }; struct DefinitionFile diff --git a/src/gen/Def.h b/src/gen/Def.h index 9503ea7..fdc9ed0 100644 --- a/src/gen/Def.h +++ b/src/gen/Def.h @@ -17,6 +17,17 @@ namespace Generated return Err.isOk(); } + template bool WriteT(const char* _4cc, const T& data) + { + Writer.write(_4cc, 4, &Err); + if (!Err.isOk()) return false; + uint32_t hash = data.Hash; + Writer.write(&hash, sizeof(hash), &Err); + uint32_t size = sizeof(T); + Writer.write(&size, sizeof(size), &Err); + return Err.isOk() && Save(&data, 1, *this); + } + bool Write(const void* data, uint32_t size) { Writer.write(data, size, &Err); diff --git a/src/gen/Generated.cpp b/src/gen/Generated.cpp index 4d2f880..6596b48 100644 --- a/src/gen/Generated.cpp +++ b/src/gen/Generated.cpp @@ -123,6 +123,7 @@ namespace Generated bool isOk = true; for (uint32_t i = 0; i < count; ++i) { + isOk = Save(&obj[i].CardCount, 1, serializer) && isOk; isOk = Save(obj[i].Cards, 64, serializer) && isOk; } return isOk; @@ -132,6 +133,7 @@ namespace Generated bool isOk = true; for (uint32_t i = 0; i < count; ++i) { + isOk = Load(&obj[i].CardCount, 1, serializer) && isOk; isOk = Load(obj[i].Cards, 64, serializer) && isOk; } return isOk; diff --git a/src/gen/Generated.h b/src/gen/Generated.h index b5009eb..ece5f7f 100644 --- a/src/gen/Generated.h +++ b/src/gen/Generated.h @@ -5,6 +5,7 @@ namespace Generated { struct PuzzleElementType { + static constexpr uint32_t Hash = 2024002654; static constexpr int32_t EntryCount = 8; enum Enum : int32_t { @@ -39,42 +40,62 @@ namespace Generated "Blocked", "Bridge", }; + static constexpr char ShortName[EntryCount][64] + { + " ", + "~+", + "~-", + "~", + "e+", + "e-", + "█", + "#", + }; }; struct PuzPos { + static constexpr uint32_t Hash = 1834398141; int8_t X = {}; int8_t Y = {}; }; struct ElemPos { + static constexpr uint32_t Hash = 3966109730; PuzPos Position = {}; uint8_t ElemIdx = {}; }; struct PuzzleNode { + static constexpr uint32_t Hash = 1417779061; PuzzleElementType::Enum PlacedTypes[4] = {}; }; struct StaticPuzzleCard { + static constexpr uint32_t Hash = 110653106; PuzzleNode Nodes[4] = {}; uint16_t ModelHandle = {}; }; struct StaticPuzzleCardHandle { + static constexpr uint32_t Hash = 1742502768; uint16_t Idx = UINT16_MAX; }; struct StaticPuzzleData { + static constexpr uint32_t Hash = 2220151575; + uint16_t CardCount = {}; StaticPuzzleCard Cards[64] = {}; }; struct PuzzleCardStack { + static constexpr uint32_t Hash = 53538532; StaticPuzzleCardHandle RefCard = {}; uint8_t MaxAvailableCount = {}; uint8_t UsedCount = {}; }; struct PlacedPuzzleCard { + static constexpr uint32_t Hash = 3555575973; StaticPuzzleCardHandle RefCard = {}; PuzPos Position = {}; uint8_t Rotation = {}; @@ -82,6 +103,7 @@ namespace Generated }; struct PuzzleData { + static constexpr uint32_t Hash = 2015691597; uint8_t WidthTiles = {}; uint8_t HeightTiles = {}; uint32_t AvailableCardCount = {};