From fd4d3e88b9603c0604abb477b4de7c8c8053f2b4 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Mon, 14 Aug 2023 17:31:15 +0200 Subject: [PATCH] Introduce ObjectImpl#GetParentsAffectingLogging() --- tools/mkclass/class_lexer.ll | 1 + tools/mkclass/classcompiler.cpp | 81 +++++++++++++++++++++++++++++++++ tools/mkclass/classcompiler.hpp | 1 + 3 files changed, 83 insertions(+) diff --git a/tools/mkclass/class_lexer.ll b/tools/mkclass/class_lexer.ll index 217ca492c..06a1291fc 100644 --- a/tools/mkclass/class_lexer.ll +++ b/tools/mkclass/class_lexer.ll @@ -135,6 +135,7 @@ deprecated { yylval->num = FADeprecated; return T_FIELD_ATTRIBUTE; } get_virtual { yylval->num = FAGetVirtual; return T_FIELD_ATTRIBUTE; } set_virtual { yylval->num = FASetVirtual; return T_FIELD_ATTRIBUTE; } signal_with_old_value { yylval->num = FASignalWithOldValue; return T_FIELD_ATTRIBUTE; } +parent_affecting_logging { yylval->num = FAParentAffectingLogging; return T_FIELD_ATTRIBUTE; } virtual { yylval->num = FAGetVirtual | FASetVirtual; return T_FIELD_ATTRIBUTE; } navigation { return T_NAVIGATION; } validator { return T_VALIDATOR; } diff --git a/tools/mkclass/classcompiler.cpp b/tools/mkclass/classcompiler.cpp index 693011369..c35f5c662 100644 --- a/tools/mkclass/classcompiler.cpp +++ b/tools/mkclass/classcompiler.cpp @@ -1087,6 +1087,87 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&) << field.GetFriendlyName() << "ChangedWithOldValue;" << std::endl << std::endl; } } + + /* override ConfigObject#GetParentsAffectingLogging() */ + + bool overrideGetParentsAffectingLogging = klass.Name == "ConfigObject"; + + if (!overrideGetParentsAffectingLogging) { + for (auto& field : klass.Fields) { + if (field.Attributes & FAParentAffectingLogging && (field.Type.IsName || field.Attributes & FANavigation)) { + overrideGetParentsAffectingLogging = true; + break; + } + } + } + + if (overrideGetParentsAffectingLogging) { + m_Header << "protected:" << std::endl << "\t"; + + if (klass.Name == "ConfigObject") { + m_Header << "virtual void GetParentsAffectingLogging(std::vector>& output) const;"; + } else { + m_Header << "void GetParentsAffectingLogging(std::vector& output) const override;"; + } + + m_Header << std::endl; + + m_Impl << "void ObjectImpl<" << klass.Name + << ">::GetParentsAffectingLogging(std::vector& output) const" << std::endl + << "{" << std::endl; + + std::set types; + + for (auto& field : klass.Fields) { + if (field.Attributes & FAParentAffectingLogging && field.Type.IsName && types.emplace(field.Type.TypeName).second) { + m_Impl << "\t" << "static const auto type" << field.Type.TypeName + << " (Type::GetByName(\"" << field.Type.TypeName << "\"));" << std::endl + << "\t" << "static const auto configType" << field.Type.TypeName + << " (dynamic_cast(type" << field.Type.TypeName << ".get()));" << std::endl; + } + } + + if (klass.Name != "ConfigObject") { + m_Impl << std::endl << "\t" << klass.Parent << "::GetParentsAffectingLogging(output);" << std::endl; + } + + for (auto& field : klass.Fields) { + if (field.Attributes & FAParentAffectingLogging && (field.Type.IsName || field.Attributes & FANavigation)) { + m_Impl << std::endl << "\t"; + + if (field.Type.IsName) { + if (field.Type.ArrayRank) { + m_Impl << "auto names" << field.GetFriendlyName() + << " (Get" << field.GetFriendlyName() << "());" << std::endl << std::endl + << "\t" << "if (names" << field.GetFriendlyName() << ") {" << std::endl + << "\t\t" << "ObjectLock lock (names" << field.GetFriendlyName() << ");" << std::endl << std::endl + << "\t\t" << "for (auto& name : names" << field.GetFriendlyName() << ") {" << std::endl + << "\t\t\t" << "auto object (configType" << field.Type.TypeName << "->GetObject(name));" << std::endl << std::endl + << "\t\t\t" << "if (object) {" << std::endl + << "\t\t\t\t" << "output.emplace_back(std::move(object));" << std::endl + << "\t\t\t" << "}" << std::endl + << "\t\t" << "}"; + } else { + m_Impl << "auto object" << field.GetFriendlyName() + << " (configType" << field.Type.TypeName << "->GetObject(Get" + << field.GetFriendlyName() << "()));" << std::endl << std::endl + << "\t" << "if (object" << field.GetFriendlyName() << ") {" << std::endl + << "\t\t" << "output.emplace_back(std::move(object" << field.GetFriendlyName() << "));"; + } + } else { + m_Impl << "auto object" << field.GetFriendlyName() + << " (static_pointer_cast(Navigate" + << field.GetFriendlyName() << "()));" << std::endl << std::endl + << "\t" << "if (object" << field.GetFriendlyName() << ") {" << std::endl + << "\t\t" << "output.emplace_back(std::move(object" << field.GetFriendlyName() << "));"; + } + + m_Impl << std::endl << "\t" << "}" << std::endl; + } + } + + m_Impl << "}" << std::endl << std::endl; + } } if (klass.Name == "ConfigObject") diff --git a/tools/mkclass/classcompiler.hpp b/tools/mkclass/classcompiler.hpp index 0bd789dd3..8befea0b1 100644 --- a/tools/mkclass/classcompiler.hpp +++ b/tools/mkclass/classcompiler.hpp @@ -62,6 +62,7 @@ enum FieldAttribute FASetVirtual = 16384, FAActivationPriority = 32768, FASignalWithOldValue = 65536, + FAParentAffectingLogging = 131072, }; struct FieldType