From ff00119e5b48cc79750d412e52df60a6e3052987 Mon Sep 17 00:00:00 2001 From: Asuro Date: Mon, 10 Mar 2025 15:16:48 +0100 Subject: [PATCH] minidef refactor --- src/dependency/minidef/CMakeLists.txt | 6 +- src/dependency/minidef/src/CppGen.cpp | 206 +++++++++++++++++++++ src/dependency/minidef/src/CppGen.h | 20 ++ src/dependency/minidef/src/Gen/Generated.h | 22 +-- src/dependency/minidef/src/MiniDef.cpp | 180 +----------------- src/dependency/minidef/src/MiniDef.h | 75 +------- src/dependency/minidef/src/TypeDef.h | 52 ++++++ 7 files changed, 306 insertions(+), 255 deletions(-) create mode 100644 src/dependency/minidef/src/CppGen.cpp create mode 100644 src/dependency/minidef/src/CppGen.h create mode 100644 src/dependency/minidef/src/TypeDef.h diff --git a/src/dependency/minidef/CMakeLists.txt b/src/dependency/minidef/CMakeLists.txt index 661277a..9b2de4e 100644 --- a/src/dependency/minidef/CMakeLists.txt +++ b/src/dependency/minidef/CMakeLists.txt @@ -1,6 +1,10 @@ cmake_minimum_required(VERSION 3.10) project(MiniDefProj) -add_executable(minidef "${CMAKE_CURRENT_SOURCE_DIR}/src/MiniDef.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/Logging.cpp") + +file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h") +file(GLOB sources "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") + +add_executable(minidef ${headers} ${sources}) target_include_directories(minidef PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../bgfx.cmake/bx/include/" "${CMAKE_CURRENT_SOURCE_DIR}/../bgfx.cmake/bx/include/compat/msvc/" diff --git a/src/dependency/minidef/src/CppGen.cpp b/src/dependency/minidef/src/CppGen.cpp new file mode 100644 index 0000000..103a8a3 --- /dev/null +++ b/src/dependency/minidef/src/CppGen.cpp @@ -0,0 +1,206 @@ +#include "CppGen.h" +#include "Logging.h" +#include "TypeDef.h" + +#include +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include "Windows.h" + +namespace WriteTemplates +{ + constexpr char FileHeader[] = + R"END(#pragma once +#include "Def.h" + +namespace Generated +{ +)END"; + + constexpr char StructHeader1[] = + R"END( struct %s + { +)END"; + + constexpr char StructField4[] = + R"END( %s %s%s = %s; +)END"; + + constexpr char StructEnd[] = + R"END( }; +)END"; + + constexpr char EnumHeader3[] = + R"END( struct %s + { + static constexpr int32_t EntryCount = %u; + enum class Enum : %s + { +)END"; + + constexpr char EnumField1[] = + R"END( %s, +)END"; + + constexpr char EnumNamesStart2[] = + R"END( }; + static constexpr char %s[EntryCount][%u] + { +)END"; + + constexpr char EnumNamesEntry1[] = + R"END( "%s", +)END"; + + constexpr char EnumNamesEnd[] = + R"END( }; + }; +)END"; + + constexpr char FileEnd[] = + R"END(} +)END"; +} // namespace WriteTemplates + +void CppFileWriter::PrintTypeName(char* buf, + int32_t bufSize, + const Def::FieldType& type, + const Def::DefinitionFile& definitions) +{ + if (type.FieldKind == Def::EFieldType::Native) + { + if (int32_t(type.Native) < Generated::KnownType::EntryCount) + { + bx::strCopy(buf, bufSize, Generated::KnownType::CName[size_t(type.Native)]); + } + else + { + LOG_ERROR(0, "Unknown native type index: %u", type.Native); + } + } + else if (type.FieldKind == Def::EFieldType::DefinedClass) + { + bx::strCopy(buf, bufSize, definitions.Types[type.TypeIdx].Name); + } + else if (type.FieldKind == Def::EFieldType::DefinedEnum) + { + bx::strCopy(buf, bufSize, definitions.Enums[type.TypeIdx].Name); + } +} + +void CppFileWriter::WriteEnums(const Def::DefinitionFile& definitions) +{ + for (int32_t enumIdx = 0; enumIdx < definitions.EnumCount; ++enumIdx) + { + const Def::Enum& e = definitions.Enums[enumIdx]; + + Write( + WriteTemplates::EnumHeader3, e.Name, 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]); + } + + Write(WriteTemplates::EnumNamesStart2, "EntryNames", Def::MaxNameLength); + for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx) + { + Write(WriteTemplates::EnumNamesEntry1, e.EntryNames[entryIdx]); + } + + for (int32_t extraIdx = 0; extraIdx < e.ExtraStringFieldCount; ++extraIdx) + { + Write(WriteTemplates::EnumNamesStart2, e.ExtraStringFieldNames[extraIdx], Def::MaxNameLength); + for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx) + { + Write(WriteTemplates::EnumNamesEntry1, e.ExtraStringFields[entryIdx][extraIdx]); + } + } + + Write(WriteTemplates::EnumNamesEnd); + } +} +void CppFileWriter::WriteTypes(const Def::DefinitionFile& definitions) +{ + for (int32_t typeIdx = 0; typeIdx < definitions.TypeCount; ++typeIdx) + { + const Def::Type& t = definitions.Types[typeIdx]; + + Write(WriteTemplates::StructHeader1, t.Name); + for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx) + { + char Type[64]{0}; + PrintTypeName(Type, sizeof(Type), t.FieldTypes[fieldIdx], definitions); + char Array[32]{0}; + uint32_t ArraySize = t.FieldArraySizes[fieldIdx]; + if (ArraySize > 0) + { + bx::snprintf(Array, sizeof(Array), "[%u]", ArraySize); + } + Write(WriteTemplates::StructField4, Type, t.FieldNames[fieldIdx], Array, t.FieldVaules[fieldIdx]); + } + Write(WriteTemplates::StructEnd); + } +} +void CppFileWriter::GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions) +{ + LOG(0, "Generating..."); + + // Allocate write buffer + if (FileWriteBuffer != nullptr) + { + LOG_ERROR(0, "Multiple writes not supported yet!"); + return; + } + FileWriteBuffer = + reinterpret_cast(VirtualAlloc(nullptr, BufferRequestSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)); + if (FileWriteBuffer == nullptr) + { + LOG_ERROR(0, "Failed to allocate write memory!"); + return; + } + FileWriterWritten = 0; + + // Write text to buffer + Write(WriteTemplates::FileHeader); + WriteEnums(definitions); + WriteTypes(definitions); + Write(WriteTemplates::FileEnd); + + // Write buffer to disk + bx::Error error; + bx::FileWriter writer; + bx::FilePath writePath = outDir; + // std::filesystem::create_directory(outDir.getCPtr()); + writePath.join("Generated.h"); + + LOG(0, "Writing to %s", writePath.getCPtr()); + if (!writer.open(writePath, false, &error)) + { + LOG_ERROR(0, "Failed to open output file: %s", error.getMessage().getCPtr()); + return; + } + + writer.write(FileWriteBuffer, FileWriterWritten, &error); + if (!error.isOk()) + { + LOG_ERROR(0, "Failed to write to output file: %s", error.getMessage().getCPtr()); + } + writer.close(); + LOG(0, "Finished writing!"); +} + +void CppFileWriter::Write(const char* Template, ...) +{ + if (FileWriteBuffer == nullptr) + { + LOG_ERROR(0, "Wrote too early!"); + return; + } + + va_list ArgList; + va_start(ArgList, Template); + FileWriterWritten += bx::vsnprintf(&FileWriteBuffer[FileWriterWritten], BufferRequestSize, Template, ArgList); + va_end(ArgList); +} diff --git a/src/dependency/minidef/src/CppGen.h b/src/dependency/minidef/src/CppGen.h new file mode 100644 index 0000000..d4db0b8 --- /dev/null +++ b/src/dependency/minidef/src/CppGen.h @@ -0,0 +1,20 @@ +#pragma once + +#include "TypeDef.h" + +#include "bx/filepath.h" + +struct CppFileWriter +{ + private: + static constexpr size_t BufferRequestSize = 1024 * 1024 * 1024; + char* FileWriteBuffer = nullptr; + uint64_t FileWriterWritten = 0; + + public: + void PrintTypeName(char* buf, int32_t bufSize, const Def::FieldType& type, const Def::DefinitionFile& definitions); + void WriteEnums(const Def::DefinitionFile& definitions); + void WriteTypes(const Def::DefinitionFile& definitions); + void GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions); + void Write(const char* Template, ...); +}; diff --git a/src/dependency/minidef/src/Gen/Generated.h b/src/dependency/minidef/src/Gen/Generated.h index 5535533..e2a77ee 100644 --- a/src/dependency/minidef/src/Gen/Generated.h +++ b/src/dependency/minidef/src/Gen/Generated.h @@ -3,17 +3,6 @@ namespace Generated { - struct Test - { - uint32_t Number = {}; - }; - struct Texture - { - uint32_t Width = {}; - uint32_t Height = {}; - char StrTest[3] = {}; - Test T = {}; - }; struct KnownType { static constexpr int32_t EntryCount = 12; @@ -63,4 +52,15 @@ namespace Generated "char", }; }; + struct Test + { + uint32_t Number = {}; + }; + struct Texture + { + uint32_t Width = {}; + uint32_t Height = {}; + char StrTest[3] = {}; + Test T = {}; + }; } diff --git a/src/dependency/minidef/src/MiniDef.cpp b/src/dependency/minidef/src/MiniDef.cpp index 1f3701d..bd53932 100644 --- a/src/dependency/minidef/src/MiniDef.cpp +++ b/src/dependency/minidef/src/MiniDef.cpp @@ -1,3 +1,4 @@ +#include "CppGen.h" #include "Gen/Generated.h" #include "Logging.h" #include "MiniDef.h" @@ -5,159 +6,6 @@ #include "bx/string.h" #include #include -#include - -namespace WriteTemplates -{ - constexpr char FileHeader[] = - R"END(#pragma once -#include "Def.h" - -namespace Generated -{ -)END"; - - constexpr char StructHeader1[] = - R"END( struct %s - { -)END"; - - constexpr char StructField4[] = - R"END( %s %s%s = %s; -)END"; - - constexpr char StructEnd[] = - R"END( }; -)END"; - - constexpr char EnumHeader3[] = - R"END( struct %s - { - static constexpr int32_t EntryCount = %u; - enum class Enum : %s - { -)END"; - - constexpr char EnumField1[] = - R"END( %s, -)END"; - - constexpr char EnumNamesStart2[] = - R"END( }; - static constexpr char %s[EntryCount][%u] - { -)END"; - - constexpr char EnumNamesEntry1[] = - R"END( "%s", -)END"; - - constexpr char EnumNamesEnd[] = - R"END( }; - }; -)END"; - - constexpr char FileEnd[] = - R"END(} -)END"; -} // namespace WriteTemplates - -void DefinitionFile::PrintTypeName(char* buf, int32_t bufSize, const Def::FieldType& type) -{ - if (type.FieldKind == Def::EFieldType::Native) - { - if (int32_t(type.Native) < Generated::KnownType::EntryCount) - { - bx::strCopy(buf, bufSize, Generated::KnownType::CName[size_t(type.Native)]); - } - else - { - LOG_ERROR(0, "Unknown native type index: %u", type.Native); - } - } - else if (type.FieldKind == Def::EFieldType::DefinedClass) - { - bx::strCopy(buf, bufSize, Types[type.TypeIdx].Name); - } - else if (type.FieldKind == Def::EFieldType::DefinedEnum) - { - bx::strCopy(buf, bufSize, Enums[type.TypeIdx].Name); - } -} - -void DefinitionFile::WriteEnums(TemplateWriter& Template) -{ - for (int32_t enumIdx = 0; enumIdx < EnumCount; ++enumIdx) - { - Def::Enum& e = Enums[enumIdx]; - - Template.Write( - WriteTemplates::EnumHeader3, e.Name, e.EntryCount, Generated::KnownType::CName[(int32_t)e.EnumType.Native]); - for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx) - { - Template.Write(WriteTemplates::EnumField1, e.EntryNames[entryIdx]); - } - - Template.Write(WriteTemplates::EnumNamesStart2, "EntryNames", Def::MaxNameLength); - for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx) - { - Template.Write(WriteTemplates::EnumNamesEntry1, e.EntryNames[entryIdx]); - } - - for (int32_t extraIdx = 0; extraIdx < e.ExtraStringFieldCount; ++extraIdx) - { - Template.Write(WriteTemplates::EnumNamesStart2, e.ExtraStringFieldNames[extraIdx], Def::MaxNameLength); - for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx) - { - Template.Write(WriteTemplates::EnumNamesEntry1, e.ExtraStringFields[entryIdx][extraIdx]); - } - } - - Template.Write(WriteTemplates::EnumNamesEnd); - } -} -void DefinitionFile::WriteTypes(TemplateWriter& Template) -{ - for (int32_t typeIdx = 0; typeIdx < TypeCount; ++typeIdx) - { - Def::Type& t = Types[typeIdx]; - - Template.Write(WriteTemplates::StructHeader1, t.Name); - for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx) - { - char Type[64]{0}; - PrintTypeName(Type, sizeof(Type), t.FieldTypes[fieldIdx]); - char Array[32]{0}; - uint32_t ArraySize = t.FieldArraySizes[fieldIdx]; - if (ArraySize > 0) - { - bx::snprintf(Array, sizeof(Array), "[%u]", ArraySize); - } - Template.Write(WriteTemplates::StructField4, Type, t.FieldNames[fieldIdx], Array, t.FieldVaules[fieldIdx]); - } - Template.Write(WriteTemplates::StructEnd); - } -} -void DefinitionFile::GenerateCpp(const bx::FilePath& outDir) -{ - LOG(0, "Generating..."); - - bx::Error error; - bx::FileWriter writer; - bx::FilePath writePath = outDir; - std::filesystem::create_directory(outDir.getCPtr()); - writePath.join("Generated.h"); - writer.open(writePath, false, &error); - - TemplateWriter Template{writer, error}; - Template.Write(WriteTemplates::FileHeader); - - WriteEnums(Template); - WriteTypes(Template); - - Template.Write(WriteTemplates::FileEnd); - writer.close(); -} bool Parser::CmpAdvance(bx::StringView expect, Result& Res, bool RequireGap) { @@ -308,7 +156,7 @@ Parser::Result Parser::HandleType() if (!Stack.Push(TokenType::TypeKeyword)) return Error; CHECK(SkipWhitespace()); - if (Definitions.TypeCount >= DefinitionFile::MaxTypes) + if (Definitions.TypeCount >= Def::DefinitionFile::MaxTypes) { LOG_ERROR(Line, "Too many types!"); ErrorLine(); @@ -386,7 +234,7 @@ Parser::Result Parser::HandleEnum() if (!Stack.Push(TokenType::EnumKeyword)) return Error; CHECK(SkipWhitespace()); - if (Definitions.EnumCount >= DefinitionFile::MaxTypes) + if (Definitions.EnumCount >= Def::DefinitionFile::MaxTypes) { LOG_ERROR(Line, "Too many enums!"); ErrorLine(); @@ -578,21 +426,10 @@ int32_t Parser::GetRemaining() return &Buffer[BufferSize] - ReadPtr; } -char WriteBuffer[1024 * 1024]{0}; -void TemplateWriter::Write(const char* Template, ...) -{ - va_list ArgList; - va_start(ArgList, Template); - int32_t Count = bx::vsnprintf(WriteBuffer, sizeof(WriteBuffer), Template, ArgList); - va_end(ArgList); - bx::write(&Writer, WriteBuffer, Count, &Error); -} - -Parser TestParser; +Parser FileParser; +CppFileWriter Writer; int main(int argc, const char** argv) { - LOG(0, "Hello"); - if (argc != 3) { LOG(0, "invalid number of arguments!"); @@ -609,8 +446,9 @@ int main(int argc, const char** argv) return 1; } - TestParser.BufferSize = bx::read(&reader, TestParser.Buffer, Parser::MaxBufferSize, &error); - Parser::Result Res = TestParser.Parse(); + LOG(0, "Reading from %s", defPath.getCPtr()); + FileParser.BufferSize = bx::read(&reader, FileParser.Buffer, Parser::MaxBufferSize, &error); + Parser::Result Res = FileParser.Parse(); if (Res == Parser::OK) { @@ -622,7 +460,7 @@ int main(int argc, const char** argv) return 1; } LOG(0, "Finished parsing!"); - TestParser.Definitions.GenerateCpp(outPath); + Writer.GenerateCpp(outPath, FileParser.Definitions); return 0; } diff --git a/src/dependency/minidef/src/MiniDef.h b/src/dependency/minidef/src/MiniDef.h index 57dd1a3..905cc0b 100644 --- a/src/dependency/minidef/src/MiniDef.h +++ b/src/dependency/minidef/src/MiniDef.h @@ -1,12 +1,11 @@ #pragma once +#include "bx/string.h" #include #include #include -#include -#include "Gen/Generated.h" #include "Logging.h" -#include "bx/string.h" +#include "TypeDef.h" enum class TokenType : uint8_t { @@ -50,74 +49,6 @@ struct ParseStack } }; -class TemplateWriter -{ - private: - bx::WriterI& Writer; - bx::Error& Error; - - public: - TemplateWriter(bx::WriterI& W, bx::Error& E) : Writer(W), Error(E) - { - } - - void Write(const char* Template, ...); -}; - -namespace Def -{ - constexpr int32_t MaxNameLength = 64; - constexpr int32_t MaxFields = 64; - constexpr int32_t MaxExtraEnumFields = 1; - enum class EFieldType - { - Native, - DefinedClass, - DefinedEnum - }; - struct FieldType - { - EFieldType FieldKind = EFieldType::Native; - Generated::KnownType::Enum Native = Generated::KnownType::Enum::i32; - uint16_t TypeIdx = UINT16_MAX; - }; - - struct Type - { - int32_t FieldCount = 0; - FieldType FieldTypes[MaxFields]; - char FieldNames[MaxFields][MaxNameLength]; - uint32_t FieldArraySizes[MaxFields]{0}; - char FieldVaules[MaxFields][128]{0}; - char Name[MaxNameLength]{0}; - }; - - struct Enum - { - FieldType EnumType; - int32_t EntryCount = 0; - char EntryNames[MaxFields][MaxNameLength]; - int32_t ExtraStringFieldCount = 0; - char ExtraStringFieldNames[MaxExtraEnumFields][MaxNameLength]; - char ExtraStringFields[MaxFields][MaxExtraEnumFields][MaxNameLength]; - char Name[MaxNameLength]{0}; - }; -} // namespace Def - -struct DefinitionFile -{ - static constexpr int32_t MaxTypes = 256; - void PrintTypeName(char* buf, int32_t bufSize, const Def::FieldType& type); - void WriteEnums(TemplateWriter& Template); - void WriteTypes(TemplateWriter& Template); - void GenerateCpp(const bx::FilePath& outDir); - - Def::Type Types[MaxTypes]; - uint16_t TypeCount = 0; - Def::Enum Enums[MaxTypes]; - int32_t EnumCount = 0; -}; - class Parser { public: @@ -140,7 +71,7 @@ class Parser char* ReadPtr = &Buffer[0]; uint32_t Line = 0; - DefinitionFile Definitions; + Def::DefinitionFile Definitions; ParseStack Stack; public: diff --git a/src/dependency/minidef/src/TypeDef.h b/src/dependency/minidef/src/TypeDef.h new file mode 100644 index 0000000..7e703f0 --- /dev/null +++ b/src/dependency/minidef/src/TypeDef.h @@ -0,0 +1,52 @@ +#pragma once +#include "Gen/Generated.h" +#include + +namespace Def +{ + constexpr int32_t MaxNameLength = 64; + constexpr int32_t MaxFields = 64; + constexpr int32_t MaxExtraEnumFields = 1; + enum class EFieldType + { + Native, + DefinedClass, + DefinedEnum + }; + struct FieldType + { + EFieldType FieldKind = EFieldType::Native; + Generated::KnownType::Enum Native = Generated::KnownType::Enum::i32; + uint16_t TypeIdx = UINT16_MAX; + }; + + struct Type + { + int32_t FieldCount = 0; + FieldType FieldTypes[MaxFields]; + char FieldNames[MaxFields][MaxNameLength]; + uint32_t FieldArraySizes[MaxFields]{0}; + char FieldVaules[MaxFields][128]{0}; + char Name[MaxNameLength]{0}; + }; + + struct Enum + { + FieldType EnumType; + int32_t EntryCount = 0; + char EntryNames[MaxFields][MaxNameLength]; + int32_t ExtraStringFieldCount = 0; + char ExtraStringFieldNames[MaxExtraEnumFields][MaxNameLength]; + char ExtraStringFields[MaxFields][MaxExtraEnumFields][MaxNameLength]; + char Name[MaxNameLength]{0}; + }; + + struct DefinitionFile + { + static constexpr int32_t MaxTypes = 256; + Def::Type Types[MaxTypes]; + uint16_t TypeCount = 0; + Def::Enum Enums[MaxTypes]; + int32_t EnumCount = 0; + }; +} // namespace Def