From c77afcc37449560e112e158671528402347fc2b2 Mon Sep 17 00:00:00 2001 From: peri4 Date: Fri, 8 Dec 2023 19:01:22 +0300 Subject: [PATCH] PICodeInfo compatible with old interface, safety access to PICODEINFO --- libs/main/code/picodeinfo.cpp | 16 +++--- libs/main/code/picodeinfo.h | 84 ++++++++++++++++++++++++----- utils/code_model_generator/main.cpp | 33 ++++++------ 3 files changed, 98 insertions(+), 35 deletions(-) diff --git a/libs/main/code/picodeinfo.cpp b/libs/main/code/picodeinfo.cpp index ee54c934..b1728452 100644 --- a/libs/main/code/picodeinfo.cpp +++ b/libs/main/code/picodeinfo.cpp @@ -46,34 +46,30 @@ PIVariantTypes::Enum PICodeInfo::EnumInfo::toPIVariantEnum() { PIVariant PICodeInfo::getMemberAsVariant(const void * p, const char * class_name, const char * member_name) { - if (!p || !class_name || !member_name || !PICODEINFO->accessTypeFunctions || !PICODEINFO->accessValueFunctions) return PIVariant(); - AccessTypeFunction atf = PICODEINFO->accessTypeFunctions->value(class_name, (AccessTypeFunction)0); - AccessValueFunction avf = PICODEINFO->accessValueFunctions->value(class_name, (AccessValueFunction)0); + if (!p || !class_name || !member_name) return PIVariant(); + AccessTypeFunction atf = PICODEINFO::accessTypeFunctions().value(class_name, (AccessTypeFunction) nullptr); + AccessValueFunction avf = PICODEINFO::accessValueFunctions().value(class_name, (AccessValueFunction) nullptr); if (!atf || !avf) return PIVariant(); return PIVariant::fromValue(avf(p, member_name), PIStringAscii(atf(member_name))); } PICodeInfo::__Storage__::__Storage__() { - piCout << "PICodeInfo::__Storage__" << this << "new ..."; classesInfo = new PIMap; enumsInfo = new PIMap; accessValueFunctions = new PIMap; accessTypeFunctions = new PIMap; (*enumsInfo)[""] = new EnumInfo(); - piCout << "PICodeInfo::__Storage__" << this << "new done"; } PICodeInfo::__Storage__::~__Storage__() { - piCout << "PICodeInfo::__Storage__" << this << "delete ..."; piDeleteAll(classesInfo->values()); piDeleteAll(enumsInfo->values()); piDeleteSafety(classesInfo); piDeleteSafety(enumsInfo); piDeleteSafety(accessValueFunctions); piDeleteSafety(accessTypeFunctions); - piCout << "PICodeInfo::__Storage__" << this << "delete done"; } @@ -81,3 +77,9 @@ PICodeInfo::__Storage__ * PICodeInfo::__Storage__::instance() { static __Storage__ ret; return &ret; } + + +PICodeInfo::ClassInfoInterface classesInfo; +PICodeInfo::EnumsInfoInterface enumsInfo; +PICodeInfo::AccessValueFunctionInterface accessValueFunctions; +PICodeInfo::AccessTypeFunctionInterface accessTypeFunctions; diff --git a/libs/main/code/picodeinfo.h b/libs/main/code/picodeinfo.h index e49dd2c4..6936493a 100644 --- a/libs/main/code/picodeinfo.h +++ b/libs/main/code/picodeinfo.h @@ -285,33 +285,91 @@ class PIP_EXPORT __Storage__ { public: static __Storage__ * instance(); - //! \~english Getter for single storage of PICodeInfo::ClassInfo, access by name - //! \~russian Доступ к единому хранилищу PICodeInfo::ClassInfo, доступ по имени - const PIMap & classes() { return *classesInfo; } - - //! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name - //! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени - const PIMap & enums() { return *enumsInfo; } - PIMap * classesInfo; PIMap * enumsInfo; PIMap * accessValueFunctions; PIMap * accessTypeFunctions; + +private: + NO_COPY_CLASS(__Storage__) }; -#define PICODEINFO (PICodeInfo::__Storage__::instance()) +class PIP_EXPORT __StorageAccess__ { +public: + //! \~english Getter for single storage of PICodeInfo::ClassInfo, access by name + //! \~russian Доступ к единому хранилищу PICodeInfo::ClassInfo, доступ по имени + static const PIMap & classes() { return *(__Storage__::instance()->classesInfo); } + + //! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name + //! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени + static const PIMap & enums() { return *(__Storage__::instance()->enumsInfo); } + + static const PIMap & accessValueFunctions() { + return *(__Storage__::instance()->accessValueFunctions); + } + + static const PIMap & accessTypeFunctions() { + return *(__Storage__::instance()->accessTypeFunctions); + } +}; + +#define PICODEINFO PICodeInfo::__StorageAccess__ + + +class PIP_EXPORT ClassInfoInterface { +public: + const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::classes()") { + return __Storage__::instance()->classesInfo; + } +}; +static ClassInfoInterface classesInfo; + + +class PIP_EXPORT EnumsInfoInterface { +public: + const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::enums()") { + return __Storage__::instance()->enumsInfo; + } +}; +static EnumsInfoInterface enumsInfo; + + +class PIP_EXPORT AccessValueFunctionInterface { +public: + const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::accessValueFunctions()") { + return __Storage__::instance()->accessValueFunctions; + } +}; +static AccessValueFunctionInterface accessValueFunctions; + + +class PIP_EXPORT AccessTypeFunctionInterface { +public: + const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::accessTypeFunctions()") { + return __Storage__::instance()->accessTypeFunctions; + } +}; +static AccessTypeFunctionInterface accessTypeFunctions; + + +STATIC_INITIALIZER_BEGIN + NO_UNUSED(classesInfo); + NO_UNUSED(enumsInfo); + NO_UNUSED(accessValueFunctions); + NO_UNUSED(accessTypeFunctions); +STATIC_INITIALIZER_END inline PIByteArray getMemberValue(const void * p, const char * class_name, const char * member_name) { - if (!p || !class_name || !member_name || !PICODEINFO->accessValueFunctions) return PIByteArray(); - AccessValueFunction af = PICODEINFO->accessValueFunctions->value(class_name, (AccessValueFunction)0); + if (!p || !class_name || !member_name) return PIByteArray(); + AccessValueFunction af = PICODEINFO::accessValueFunctions().value(class_name, (AccessValueFunction)0); if (!af) return PIByteArray(); return af(p, member_name); } inline const char * getMemberType(const char * class_name, const char * member_name) { - if (!class_name || !member_name || !PICODEINFO->accessTypeFunctions) return ""; - AccessTypeFunction af = PICODEINFO->accessTypeFunctions->value(class_name, (AccessTypeFunction)0); + if (!class_name || !member_name) return ""; + AccessTypeFunction af = PICODEINFO::accessTypeFunctions().value(class_name, (AccessTypeFunction)0); if (!af) return ""; return af(member_name); } diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index 4525ecde..d2fa5fdd 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -31,7 +31,7 @@ const char help_string[] = "-M (Metainfo)\n" "Generate classes and structs info. It contains\n" "names, subclass info, all methods and variables.\n" "Place information:\n" - " * classes and structs - PICODEINFO->classes()\n" + " * classes and structs - PICODEINFO::classes()\n" " * methods - ClassInfo::functions\n" " * variables - ClassInfo::variables\n" "\n" @@ -39,7 +39,7 @@ const char help_string[] = "-M (Metainfo)\n" "Generate enumeration descriptions.\n" "Useful for GUI integrations, because\n" "you can obtain enumerators value and name.\n" - " * enums - PICODEINFO->enums()\n" + " * enums - PICODEINFO::enums()\n" "\n" "-S (Stream operators)\n" "Generate store/restore operators with format\n" @@ -144,10 +144,10 @@ void makeClassInfo(PIIOTextStream & ts, const PICodeParser::Entity * e) { while (i.next()) ts << "\tci->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; } - ts << "\t(*PICODEINFO->classesInfo)[ci->name] = ci;\n"; + ts << "\t(*PICodeInfo::__Storage__::instance()->classesInfo)[ci->name] = ci;\n"; if (e->parent_scope) { ts << "\tpci = " - << "PICODEINFO->classesInfo->value(\"" << e->parent_scope->name << "\", 0);\n"; + << "PICodeInfo::__Storage__::instance()->classesInfo->value(\"" << e->parent_scope->name << "\", 0);\n"; ts << "\tif (pci) pci->children_info << ci;\n"; } for (const PICodeParser::Entity * p: e->parents) @@ -270,10 +270,10 @@ void makeClassInfo(PIIOTextStream & ts, const PICodeParser::Entity * e) { void makeEnumInfo(PIIOTextStream & ts, const PICodeParser::Enum * e) { if (e->name.isEmpty()) { - ts << "\n\tei = (*PICODEINFO->enumsInfo)[\"\"];\n"; + ts << "\n\tei = (*PICodeInfo::__Storage__::instance()->enumsInfo)[\"\"];\n"; } else { ts << "\n\tei = new EnumInfo();\n"; - ts << "\t(*PICODEINFO->enumsInfo)[\"" << e->name << "\"] = ei;\n"; + ts << "\t(*PICodeInfo::__Storage__::instance()->enumsInfo)[\"" << e->name << "\"] = ei;\n"; ts << "\tei->name = \"" << e->name << "\";\n"; if (!e->meta.isEmpty()) { auto i = e->meta.makeIterator(); @@ -517,7 +517,7 @@ bool writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met ts << "__ClassInfo_" << defname << "_Initializer__::Content::Content() {\n"; if (meta) { ts << "\tClassInfo * pci = new ClassInfo();\n"; - ts << "\t(*PICODEINFO->classesInfo)[\"\"] = pci;\n"; + ts << "\t(*PICodeInfo::__Storage__::instance()->classesInfo)[\"\"] = pci;\n"; } if (enums && !parser.enums.isEmpty()) { ts << "\tEnumInfo * ei;\n"; @@ -539,8 +539,10 @@ bool writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met for (const PICodeParser::Entity * e: parser.entities) { if (!needClassStream(e)) continue; if (!e->has_name || e->name.startsWith("_PI")) continue; - ts << "\t(*PICODEINFO->accessValueFunctions)[\"" << e->name << "\"] = getterValue" << toCName(e->name) << ";\n"; - ts << "\t(*PICODEINFO->accessTypeFunctions)[\"" << e->name << "\"] = getterType" << toCName(e->name) << ";\n"; + ts << "\t(*PICodeInfo::__Storage__::instance()->accessValueFunctions)[\"" << e->name << "\"] = getterValue" + << toCName(e->name) << ";\n"; + ts << "\t(*PICodeInfo::__Storage__::instance()->accessTypeFunctions)[\"" << e->name << "\"] = getterType" + << toCName(e->name) << ";\n"; } } ts << "}\n\n"; @@ -549,16 +551,16 @@ bool writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met ts << "\n// Classes clean\n"; for (const PICodeParser::Entity * e: parser.entities) { if (e->name.startsWith("_PI")) continue; - ts << "\tpiDeleteSafety((*PICODEINFO->classesInfo)[\"" << e->name << "\"]);\n"; - ts << "\tPICODEINFO->classesInfo->remove(\"" << e->name << "\");\n"; + ts << "\tpiDeleteSafety((*PICodeInfo::__Storage__::instance()->classesInfo)[\"" << e->name << "\"]);\n"; + ts << "\tPICodeInfo::__Storage__::instance()->classesInfo->remove(\"" << e->name << "\");\n"; } } if (enums) { ts << "\n// Enums clean\n"; for (const PICodeParser::Enum & e: parser.enums) { if (e.name.isNotEmpty()) { - ts << "\tpiDeleteSafety((*PICODEINFO->enumsInfo)[\"" << e.name << "\"]);\n"; - ts << "\tPICODEINFO->enumsInfo->remove(\"" << e.name << "\");\n"; + ts << "\tpiDeleteSafety((*PICodeInfo::__Storage__::instance()->enumsInfo)[\"" << e.name << "\"]);\n"; + ts << "\tPICodeInfo::__Storage__::instance()->enumsInfo->remove(\"" << e.name << "\");\n"; } } } @@ -567,8 +569,8 @@ bool writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met for (const PICodeParser::Entity * e: parser.entities) { if (!needClassStream(e)) continue; if (!e->has_name || e->name.startsWith("_PI")) continue; - ts << "\tPICODEINFO->accessValueFunctions->remove(\"" << e->name << "\");\n"; - ts << "\tPICODEINFO->accessTypeFunctions->remove(\"" << e->name << "\");\n"; + ts << "\tPICodeInfo::__Storage__::instance()->accessValueFunctions->remove(\"" << e->name << "\");\n"; + ts << "\tPICodeInfo::__Storage__::instance()->accessTypeFunctions->remove(\"" << e->name << "\");\n"; } } ts << "}\n"; @@ -605,6 +607,7 @@ bool writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met ts << "\n\n// Metainformation\n\nclass __ClassInfo_" << defname << "_Initializer__ {\n"; ts << "public:\n"; ts << "\t__ClassInfo_" << defname << "_Initializer__();\n"; + ts << "private:\n"; ts << "\tclass Content {\n"; ts << "\tpublic:\n"; ts << "\t\tContent();\n";