diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/20-codegen-compiler/CodegenDecl.hpp | 10 | ||||
-rw-r--r-- | source/20-codegen-compiler/main.cpp | 325 | ||||
-rw-r--r-- | source/20-codegen-compiler/test/examples/TestEnum.hpp.txt | 12 | ||||
-rw-r--r-- | source/20-codegen-runtime/MacrosCodegen.hpp | 2 | ||||
-rw-r--r-- | source/30-game/GameObject.hpp | 5 | ||||
-rw-r--r-- | source/30-game/Ires.hpp | 5 |
6 files changed, 218 insertions, 141 deletions
diff --git a/source/20-codegen-compiler/CodegenDecl.hpp b/source/20-codegen-compiler/CodegenDecl.hpp index 0728c08..60d5a13 100644 --- a/source/20-codegen-compiler/CodegenDecl.hpp +++ b/source/20-codegen-compiler/CodegenDecl.hpp @@ -80,6 +80,16 @@ struct DeclEnum { // Start with invalid value, calculate on demand mutable EnumValuePattern pattern = EVP_COUNT; + // TODO replace this with a regex? + std::string generateRemovingPrefix; + std::string generatingAddingPrefix; + // NOTE: this flag acts as a gate for every specific generating option, must be enabled for them to work + bool generating : 1 = false; + bool generateToString : 1 = false; + bool generateFromString : 1 = false; + // NOTE: see GenerateForEnum() for the exact heuristics + bool generateExcludeUseHeuristics : 1 = false; + EnumValuePattern CalcPattern() const; EnumValuePattern GetPattern() const; }; diff --git a/source/20-codegen-compiler/main.cpp b/source/20-codegen-compiler/main.cpp index 5e052a3..326e4a9 100644 --- a/source/20-codegen-compiler/main.cpp +++ b/source/20-codegen-compiler/main.cpp @@ -302,6 +302,8 @@ enum EnumMetaGenOptions { EMGO_ToString, EMGO_FromString, EMGO_ExcludeUseHeuristics, + EMGO_RemovePrefix, + EMGO_AddPrefix, EMGO_COUNT, }; @@ -310,6 +312,8 @@ RSTR_LUT_DECL(EnumMetaGenOptions, 0, EMGO_COUNT) { RSTR_LUT_MAP(EMGO_ToString, "ToString"); RSTR_LUT_MAP(EMGO_FromString, "FromString"); RSTR_LUT_MAP(EMGO_ExcludeUseHeuristics, "ExcludeHeuristics"); + RSTR_LUT_MAP(EMGO_RemovePrefix, "RemovePrefix"); + RSTR_LUT_MAP(EMGO_AddPrefix, "AddPrefix"); } void GenerateEnumStringArray(CodegenOutput& out, const DeclEnum& decl, const char* arrayName, const std::vector<DeclEnumElement>& filteredElements) { @@ -328,7 +332,7 @@ void GenerateEnumStringMap(CodegenOutput& out, const DeclEnum& decl, const char* out.AddOutputThing(std::move(thing)); } -void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const DeclEnum& decl, EnumFlags<EnumMetaGenOptions> options) { +void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const DeclEnum& decl) { char enumName[2048]; if (decl.container) { snprintf(enumName, sizeof(enumName), "%.*s::%s", PRINTF_STRING_VIEW(decl.container->fullname), decl.name.c_str()); @@ -339,14 +343,24 @@ void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const D // TODO mangle to prevent name conflicts of enum in different namespaces auto& declIdName = decl.name; - auto useExcludeHeuristics = options.IsSet(EMGO_ExcludeUseHeuristics); + auto useExcludeHeuristics = decl.generateExcludeUseHeuristics; auto filteredElements = [&]() { if (useExcludeHeuristics) { decltype(decl.elements) result; for (auto& elm : decl.elements) { if (elm.name.ends_with("COUNT")) continue; - result.push_back(elm); + std::string_view trimmedName = elm.name; + if (!decl.generateRemovingPrefix.empty() && + elm.name.starts_with(decl.generateRemovingPrefix)) + { + trimmedName = trimmedName.substr(decl.generateRemovingPrefix.size()); + } + + result.push_back(DeclEnumElement{ + .name = decl.generatingAddingPrefix + std::string(trimmedName), + .value = elm.value, + }); } return result; } else { @@ -354,7 +368,7 @@ void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const D } }(); - if (options.IsSet(EMGO_ToString)) { + if (decl.generateToString) { // Generate value -> string lookup table and function INPLACE_FMT(val2StrName, "gCG_%s_Val2Str", declIdName.c_str()); @@ -400,7 +414,7 @@ void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const D } } - if (options.IsSet(EMGO_FromString)) { + if (decl.generateFromString) { // Generate string -> value lookup table INPLACE_FMT(str2ValName, "gCG_%s_Str2Val", declIdName.c_str()); @@ -489,7 +503,95 @@ void GenerateForClassMetadata( sourceOutput.AddOutputThing(std::move(queryFunc)); } -void HandleInputFile(AppState& state, std::string_view filenameStem, std::string_view source) { +struct NamespaceStackframe { + // The current namespace that owns the brace level, see example + DeclNamespace* ns = nullptr; + // Brace depth `ns` was created at (e.g. [std::details].depth == 0) + int depth = 0; +}; + +struct ParserState { + CodegenInput input; + CodegenOutput headerOutput; + CodegenOutput sourceOutput; + CodegenOutput standaloneSourceOutput; + + // Example: + // namespace std::details { + // /* [stack top].ns = std::details */ + // /* [stack top].depth = std */ + // } + // namespace foo { + // /* [stack top].ns = foo */ + // /* [stack top].depth = foo */ + // namespace details { + // /* [stack top].ns = foo::details */ + // /* [stack top].depth = foo::details */ + // } + // } + std::vector<NamespaceStackframe> nsStack; + // The current effective namespace, see example + DeclNamespace* currentNamespace = nullptr; + + DeclStruct* currentStruct = nullptr; + DeclEnum* currentEnum = nullptr; + int currentBraceDepth = 0; + int currentStructBraceDepth = -1; + int currentEnumBraceDepth = -1; +}; + +void HandleDirectiveEnum(AppState& as, ParserState& ps, CodegenLexer& lexer) { + // Consume the directive + ++lexer.idx; + + if (!ps.currentEnum) { + printf("[ERROR] BRUSSEL_ENUM must be used within a enum\n"); + return; + } + + auto argList = TryConsumeDirectiveArgumentList(lexer); + auto& lut = RSTR_LUT(EnumMetaGenOptions); + for (auto& arg : argList) { + if (arg.empty()) { + printf("[ERROR] empty argument is invalid in BRUSSEL_ENUM\n"); + continue; + } + + auto& optionDirective = arg[0]->text; + auto iter = lut.find(optionDirective); + if (iter == lut.end()) { + printf("[ERROR] BRUSSEL_ENUM: invalid option '%s'\n", optionDirective.c_str()); + } + + auto option = iter->second; + switch (option) { + case EMGO_ToString: ps.currentEnum->generateToString = true; break; + case EMGO_FromString: ps.currentEnum->generateFromString = true; break; + case EMGO_ExcludeUseHeuristics: ps.currentEnum->generateExcludeUseHeuristics = true; break; + + case EMGO_RemovePrefix: { + if (argList.size() <= 1) { + printf("[ERROR] missing argument for RemovePrefix"); + break; + } + ps.currentEnum->generateRemovingPrefix = arg[1]->text; + } break; + case EMGO_AddPrefix: { + if (argList.size() <= 1) { + printf("[ERROR] missing argument for AddPrefix"); + break; + } + ps.currentEnum->generatingAddingPrefix = arg[1]->text; + } break; + + case EMGO_COUNT: break; + } + } + + ps.currentEnum->generating = true; +} + +void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_view source) { CodegenLexer lexer; lexer.InitializeFrom(source); @@ -513,43 +615,12 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string printf("END tokens\n"); #endif - CodegenInput cgInput; - CodegenOutput cgHeaderOutput; - CodegenOutput cgSourceOutput; + ParserState ps; { INPLACE_FMT(hpp, "%.*s.gh.inl", PRINTF_STRING_VIEW(filenameStem)); INPLACE_FMT(cpp, "%.*s.gs.inl", PRINTF_STRING_VIEW(filenameStem)); - Utils::ProduceGeneratedHeader(hpp, cgHeaderOutput, cpp, cgSourceOutput); + Utils::ProduceGeneratedHeader(hpp, ps.headerOutput, cpp, ps.sourceOutput); } - CodegenOutput cgStandaloneSourceOutput; - - int currentBraceDepth = 0; - // The current effective namespace, see example - DeclNamespace* currentNamespace = nullptr; - DeclStruct* currentStruct = nullptr; - int currentStructBraceDepth = 0; - - struct NamespaceStackframe { - // The current namespace that owns the brace level, see example - DeclNamespace* ns = nullptr; - // Brace depth `ns` was created at (e.g. [std::details].depth == 0) - int depth = 0; - }; - std::vector<NamespaceStackframe> nsStack; - - // Example: - // namespace std::details { - // /* [stack top].ns = std::details */ - // /* [stack top].depth = std */ - // } - // namespace foo { - // /* [stack top].ns = foo */ - // /* [stack top].depth = foo */ - // namespace details { - // /* [stack top].ns = foo::details */ - // /* [stack top].depth = foo::details */ - // } - // } auto& tokens = lexer.tokens; auto& idx = lexer.idx; @@ -592,8 +663,8 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string break; } - currentNamespace = cgInput.AddNamespace(DeclNamespace{ - .container = currentNamespace, + ps.currentNamespace = ps.input.AddNamespace(DeclNamespace{ + .container = ps.currentNamespace, .name = tokens[idx].text, }); @@ -608,9 +679,9 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string } } - nsStack.push_back(NamespaceStackframe{ - .ns = currentNamespace, - .depth = currentBraceDepth, + ps.nsStack.push_back(NamespaceStackframe{ + .ns = ps.currentNamespace, + .depth = ps.currentBraceDepth, }); goto endCaseCLEX_id; @@ -631,9 +702,9 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string DEBUG_PRINTF("[DEBUG] found struct named %s\n", idenTok.text.c_str()); auto& name = idenTok.text; - auto fullname = Utils::MakeFullName(name, currentNamespace); + auto fullname = Utils::MakeFullName(name, ps.currentNamespace); DeclStruct structDecl; - structDecl.container = currentNamespace; + structDecl.container = ps.currentNamespace; structDecl.name = name; // Consume the identifier token @@ -651,8 +722,8 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string } // TODO support namespace qualified names - auto baseClassFullname = Utils::MakeFullName(idenTok.text, currentNamespace); - auto baseClassDecl = cgInput.FindStruct(baseClassFullname); + auto baseClassFullname = Utils::MakeFullName(idenTok.text, ps.currentNamespace); + auto baseClassDecl = ps.input.FindStruct(baseClassFullname); if (baseClassDecl) { // We silently ignore a non-existent base class, because they may reside in a file that we didn't scan structDecl.baseClasses.push_back(baseClassDecl); @@ -679,9 +750,9 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string { // Get a pointer to the decl inside CodegenInput's storage - auto decl = cgInput.AddStruct(std::move(fullname), std::move(structDecl)); - currentStruct = decl; - currentStructBraceDepth = currentBraceDepth; + auto decl = ps.input.AddStruct(std::move(fullname), std::move(structDecl)); + ps.currentStruct = decl; + ps.currentStructBraceDepth = ps.currentBraceDepth; } endCase: @@ -704,10 +775,16 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string DEBUG_PRINTF("[DEBUG] found enum named %s\n", idenTok->text.c_str()); } + auto& name = tokens[idx].text; + auto fullname = Utils::MakeFullName(name, ps.currentNamespace); DeclEnum enumDecl; - enumDecl.container = currentNamespace; + enumDecl.container = ps.currentNamespace; enumDecl.underlyingType = EUT_Int32; // TODO - enumDecl.name = tokens[idx].text; + enumDecl.name = name; + + // Temporarily bind the pointers to local variable, HandleDirectiveEnum() and other functions expect these to the set + ps.currentEnum = &enumDecl; + ps.currentEnumBraceDepth = ps.currentBraceDepth; // Consume the enum name identifier ++idx; @@ -718,14 +795,20 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string auto& token = tokens[idx]; switch (token.type) { case CLEX_id: { - auto& vec = enumDecl.elements; - // Set to the previous enum element's value + 1, or starting from 0 if this is the first - // Also overridden in the CLEX_intlit branch - auto value = vec.empty() ? 0 : vec.back().value + 1; - vec.push_back(DeclEnumElement{ - .name = token.text, - .value = value, - }); + if (token.text == "BRUSSEL_ENUM") { + // Consume the argument list and skip advancing index: this function already consumed all the tokens about BRUSSEL_ENUM + HandleDirectiveEnum(as, ps, lexer); + continue; + } else { + auto& vec = enumDecl.elements; + // Set to the previous enum element's value + 1, or starting from 0 if this is the first + // Also overridden in the CLEX_intlit branch + auto value = vec.empty() ? 0 : vec.back().value + 1; + vec.push_back(DeclEnumElement{ + .name = token.text, + .value = value, + }); + } } break; case CLEX_intlit: { @@ -753,8 +836,16 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string ++idx; } - auto fullname = Utils::MakeFullName(enumDecl.name, currentNamespace); - cgInput.AddEnum(std::move(fullname), std::move(enumDecl)); + if (ps.currentEnum->generating) { + GenerateForEnum(ps.headerOutput, ps.sourceOutput, *ps.currentEnum); + } + + { + auto decl = ps.input.AddEnum(std::move(fullname), std::move(enumDecl)); + ps.currentEnum = decl; + ps.currentEnumBraceDepth = ps.currentBraceDepth; + } + goto endCaseCLEX_id; } @@ -782,13 +873,13 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string ++idx; incrementTokenIdx = false; - if (!currentStruct) { + if (!ps.currentStruct) { printf("[ERROR] BRUSSEL_CLASS must be used within a class or struct\n"); break; } // Always-on option - currentStruct->generating = true; + ps.currentStruct->generating = true; auto argList = TryConsumeDirectiveArgumentList(lexer); auto& lut = RSTR_LUT(StructMetaGenOptions); @@ -802,7 +893,7 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string auto iter = lut.find(optionDirective); if (iter == lut.end()) continue; switch (iter->second) { - case SMGO_InheritanceHiearchy: currentStruct->generatingInheritanceHiearchy = true; break; + case SMGO_InheritanceHiearchy: ps.currentStruct->generatingInheritanceHiearchy = true; break; case SMGO_COUNT: break; } } @@ -815,8 +906,8 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string ++idx; incrementTokenIdx = false; - if (!currentStruct || - !currentStruct->generating) + if (!ps.currentStruct || + !ps.currentStruct->generating) { printf("[ERROR] BRUSSEL_PROPERTY must be used within a class or struct, that has the BRUSSEL_CLASS directive\n"); break; @@ -884,7 +975,7 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string } } - currentStruct->memberVariables.push_back(std::move(decl)); + ps.currentStruct->memberVariables.push_back(std::move(decl)); goto endCaseCLEX_id; } @@ -897,42 +988,8 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string goto endCaseCLEX_id; } - case CD_Enum: { - // Consume the directive - ++idx; - incrementTokenIdx = false; - - auto& optionsStrMap = RSTR_LUT(EnumMetaGenOptions); - auto argList = TryConsumeDirectiveArgumentList(lexer); - - if (argList.size() < 1) { - printf("[ERROR] invalid syntax for BRUSSEL_ENUM\n"); - break; - } - - auto& enumName = argList[0][0]->text; - auto enumDecl = cgInput.FindEnum(Utils::MakeFullName(enumName, currentNamespace)); - if (!enumDecl) { - printf("[ERROR] BRUSSEL_ENUM: referring to non-existent enum '%s'\n", enumName.c_str()); - break; - } - - auto& directiveOptions = argList[1]; - EnumFlags<EnumMetaGenOptions> options; - for (auto optionTok : directiveOptions) { - auto iter = optionsStrMap.find(optionTok->text); - if (iter != optionsStrMap.end()) { - options |= iter->second; - } else { - printf("[ERROR] BRUSSEL_ENUM: invalid option '%s'\n", optionTok->text.c_str()); - } - } - - GenerateForEnum(cgHeaderOutput, cgSourceOutput, *enumDecl, options); - - goto endCaseCLEX_id; - } - + // This directive always appear inside a enum{} block, which is handled above in the keywords section + case CD_Enum: case CD_COUNT: break; } @@ -940,46 +997,50 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string } break; case '{': { - currentBraceDepth++; - if (currentBraceDepth < 0) { + ps.currentBraceDepth++; + if (ps.currentBraceDepth < 0) { printf("[WARNING] unbalanced brace\n"); } } break; case '}': { - currentBraceDepth--; - if (currentBraceDepth < 0) { + ps.currentBraceDepth--; + if (ps.currentBraceDepth < 0) { printf("[WARNING] unbalanced brace\n"); } - if (!nsStack.empty()) { - auto& ns = nsStack.back(); - if (ns.depth == currentBraceDepth) { - nsStack.pop_back(); + if (!ps.nsStack.empty()) { + auto& ns = ps.nsStack.back(); + if (ns.depth == ps.currentBraceDepth) { + ps.nsStack.pop_back(); - if (!nsStack.empty()) { - currentNamespace = nsStack.back().ns; + if (!ps.nsStack.empty()) { + ps.currentNamespace = ps.nsStack.back().ns; } else { - currentNamespace = nullptr; + ps.currentNamespace = nullptr; } } } - if (currentStruct && - currentBraceDepth == currentStructBraceDepth) - { + if (ps.currentStruct && ps.currentBraceDepth == ps.currentStructBraceDepth) { // Exit struct - if (currentStruct->generating) { - GenerateForClassMetadata(cgHeaderOutput, cgSourceOutput, *currentStruct); + if (ps.currentStruct->generating) { + GenerateForClassMetadata(ps.headerOutput, ps.sourceOutput, *ps.currentStruct); } - if (currentStruct->generatingInheritanceHiearchy) { + if (ps.currentStruct->generatingInheritanceHiearchy) { // NOTE: this option is transitive to all child classes (as long as they have the basic annotation) // TODO } - currentStruct = nullptr; - currentStructBraceDepth = 0; + ps.currentStruct = nullptr; + ps.currentStructBraceDepth = 0; + } + if (ps.currentEnum && ps.currentBraceDepth == ps.currentEnumBraceDepth) { + // Exit enum + + ps.currentEnum = nullptr; + ps.currentEnumBraceDepth = 0; } } break; } @@ -989,16 +1050,16 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string } } - if (currentBraceDepth != 0) { - printf("[WARNING] unbalanced brace at end of file."); + if (ps.currentBraceDepth != 0) { + printf("[WARNING] unbalanced brace at end of file\n"); } - INPLACE_FMT(generatedHeaderInlName, "%.*s/%.*s.gh.inl", PRINTF_STRING_VIEW(state.outputDir), PRINTF_STRING_VIEW(filenameStem)); - Utils::WriteOutputFile(cgHeaderOutput, generatedHeaderInlName); - INPLACE_FMT(generatedSourceInlName, "%.*s/%.*s.gs.inl", PRINTF_STRING_VIEW(state.outputDir), PRINTF_STRING_VIEW(filenameStem)); - Utils::WriteOutputFile(cgSourceOutput, generatedSourceInlName); - INPLACE_FMT(generatedCppName, "%.*s/%.*s.g.cpp", PRINTF_STRING_VIEW(state.outputDir), PRINTF_STRING_VIEW(filenameStem)); - Utils::WriteOutputFile(cgStandaloneSourceOutput, generatedCppName); + INPLACE_FMT(generatedHeaderInlName, "%.*s/%.*s.gh.inl", PRINTF_STRING_VIEW(as.outputDir), PRINTF_STRING_VIEW(filenameStem)); + Utils::WriteOutputFile(ps.headerOutput, generatedHeaderInlName); + INPLACE_FMT(generatedSourceInlName, "%.*s/%.*s.gs.inl", PRINTF_STRING_VIEW(as.outputDir), PRINTF_STRING_VIEW(filenameStem)); + Utils::WriteOutputFile(ps.sourceOutput, generatedSourceInlName); + INPLACE_FMT(generatedCppName, "%.*s/%.*s.g.cpp", PRINTF_STRING_VIEW(as.outputDir), PRINTF_STRING_VIEW(filenameStem)); + Utils::WriteOutputFile(ps.standaloneSourceOutput, generatedCppName); } enum InputOpcode { diff --git a/source/20-codegen-compiler/test/examples/TestEnum.hpp.txt b/source/20-codegen-compiler/test/examples/TestEnum.hpp.txt index 30c36c0..fea1f6d 100644 --- a/source/20-codegen-compiler/test/examples/TestEnum.hpp.txt +++ b/source/20-codegen-compiler/test/examples/TestEnum.hpp.txt @@ -1,44 +1,44 @@ enum MyEnum { + BRUSSEL_ENUM(ToString, FromString) EnumElement1, EnumElement2, EnumElement3, }; -BRUSSEL_ENUM(MyEnum, ToString FromString); // Let's also test enum class enum class CountedEnumAll { + BRUSSEL_ENUM(ToString, FromString) CEA_Foo, CEA_Bar, CEA_COUNT, }; -BRUSSEL_ENUM(CountedEnumAll, ToString FromString); enum CountedEnum { + BRUSSEL_ENUM(ToString, FromString, RemovePrefix CE_, AddPrefix CustomPrefix, ExcludeHeuristics) CE_Foo, CE_Bar, CE_FooBar, CE_COUNT, }; -BRUSSEL_ENUM(CountedEnum, ToString FromString ExcludeHeuristics); namespace MyNamespace { enum class MyNamespacedEnum { + BRUSSEL_ENUM(ToString, FromString, ExcludeHeuristics) MNE_Foo, MNE_Bar, }; -BRUSSEL_ENUM(MyNamespacedEnum, ToString FromString ExcludeHeuristics); namespace details { enum MyNamespacedEnum { + BRUSSEL_ENUM(ToString, FromString, ExcludeHeuristics) MNE_Foo, MNE_Bar, }; - BRUSSEL_ENUM(MyNamespacedEnum, ToString FromString ExcludeHeuristics); } } namespace foo::details { enum Enum { + BRUSSEL_ENUM(ToString, FromString, ExcludeHeuristics) }; -BRUSSEL_ENUM(Enum, ToString FromString ExcludeHeuristics); } diff --git a/source/20-codegen-runtime/MacrosCodegen.hpp b/source/20-codegen-runtime/MacrosCodegen.hpp index 956123c..43ae99c 100644 --- a/source/20-codegen-runtime/MacrosCodegen.hpp +++ b/source/20-codegen-runtime/MacrosCodegen.hpp @@ -7,4 +7,4 @@ #define BRUSSEL_PROPERTY(...) #define BRUSSEL_METHOD(...) -#define BRUSSEL_ENUM(name, options) +#define BRUSSEL_ENUM(...) diff --git a/source/30-game/GameObject.hpp b/source/30-game/GameObject.hpp index f975803..56beb80 100644 --- a/source/30-game/GameObject.hpp +++ b/source/30-game/GameObject.hpp @@ -16,6 +16,10 @@ namespace Tags { enum class GameObjectKind { + // clang-format off + BRUSSEL_ENUM(ToString, FromString, RemovePrefix KD_, AddPrefix GameObject, ExcludeHeuristics) + // clang-format on + KD_Generic, KD_Player, KD_SimpleGeometry, @@ -23,7 +27,6 @@ enum class GameObjectKind { KD_LevelWrapper, KD_COUNT, }; -BRUSSEL_ENUM(GameObjectKind, ToString FromString ExcludeHeuristics); } // namespace Tags class GameWorld; diff --git a/source/30-game/Ires.hpp b/source/30-game/Ires.hpp index b6420f3..22018cd 100644 --- a/source/30-game/Ires.hpp +++ b/source/30-game/Ires.hpp @@ -21,6 +21,10 @@ class IresLoadingContext; namespace Tags { enum class IresObjectKind { + // clang-format off + BRUSSEL_ENUM(ToString, FromString, RemovePrefix KD_, AddPrefix Ires, ExcludeHeuristics) + // clang-format on + KD_Texture, KD_Shader, KD_Material, @@ -28,7 +32,6 @@ enum class IresObjectKind { KD_Spritesheet, KD_COUNT, }; -BRUSSEL_ENUM(IresObjectKind, ToString FromString ExcludeHeuristics); } // namespace Tags class IresObject : public RefCounted { |