PICodeInfo compatible with old interface, safety access to PICODEINFO

This commit is contained in:
2023-12-08 19:01:22 +03:00
parent b8fc44714c
commit c77afcc374
3 changed files with 98 additions and 35 deletions

View File

@@ -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<PIConstChars, ClassInfo *>;
enumsInfo = new PIMap<PIConstChars, EnumInfo *>;
accessValueFunctions = new PIMap<PIConstChars, AccessValueFunction>;
accessTypeFunctions = new PIMap<PIConstChars, AccessTypeFunction>;
(*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;

View File

@@ -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<PIConstChars, PICodeInfo::ClassInfo *> & classes() { return *classesInfo; }
//! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name
//! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени
const PIMap<PIConstChars, PICodeInfo::EnumInfo *> & enums() { return *enumsInfo; }
PIMap<PIConstChars, PICodeInfo::ClassInfo *> * classesInfo;
PIMap<PIConstChars, PICodeInfo::EnumInfo *> * enumsInfo;
PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * accessValueFunctions;
PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * 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<PIConstChars, PICodeInfo::ClassInfo *> & classes() { return *(__Storage__::instance()->classesInfo); }
//! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name
//! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени
static const PIMap<PIConstChars, PICodeInfo::EnumInfo *> & enums() { return *(__Storage__::instance()->enumsInfo); }
static const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> & accessValueFunctions() {
return *(__Storage__::instance()->accessValueFunctions);
}
static const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> & accessTypeFunctions() {
return *(__Storage__::instance()->accessTypeFunctions);
}
};
#define PICODEINFO PICodeInfo::__StorageAccess__
class PIP_EXPORT ClassInfoInterface {
public:
const PIMap<PIConstChars, PICodeInfo::ClassInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::classes()") {
return __Storage__::instance()->classesInfo;
}
};
static ClassInfoInterface classesInfo;
class PIP_EXPORT EnumsInfoInterface {
public:
const PIMap<PIConstChars, PICodeInfo::EnumInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::enums()") {
return __Storage__::instance()->enumsInfo;
}
};
static EnumsInfoInterface enumsInfo;
class PIP_EXPORT AccessValueFunctionInterface {
public:
const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * operator->() const DEPRECATEDM("use PICODEINFO::accessValueFunctions()") {
return __Storage__::instance()->accessValueFunctions;
}
};
static AccessValueFunctionInterface accessValueFunctions;
class PIP_EXPORT AccessTypeFunctionInterface {
public:
const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * 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);
}

View File

@@ -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";