version 3.15.0 - improved pip_cmg and PICodeInfo storage

Important! changed API to access PICodeInfo storage
This commit is contained in:
2023-12-08 16:14:18 +03:00
parent 49a5ed6aa3
commit b8fc44714c
5 changed files with 130 additions and 55 deletions

View File

@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(PIP)
set(PIP_MAJOR 3)
set(PIP_MINOR 14)
set(PIP_REVISION 1)
set(PIP_MINOR 15)
set(PIP_REVISION 0)
set(PIP_SUFFIX )
set(PIP_COMPANY SHS)
set(PIP_DOMAIN org.SHS)
@@ -458,6 +458,9 @@ if (NOT CROSSTOOLS)
endif()
if (NOT "x${MINGW_INCLUDE}" STREQUAL "x")
list(APPEND CMAKE_INCLUDE_PATH "${MINGW_INCLUDE}")
endif()
find_package(OpenCL QUIET) #OpenCL_VERSION_STRING
if(OpenCL_FOUND)
set(_opencl_inc "${OpenCL_INCLUDE_DIRS}")
@@ -489,8 +492,10 @@ if (NOT CROSSTOOLS)
# Test program
if(PIP_UTILS)
#add_library(pip_plugin SHARED "test_plugin.h" "test_plugin.cpp")
#add_library(pip_plugin SHARED "test_plugin.h" "test_plugin.cpp" "ccm.h" "ccm.cpp")
#target_link_libraries(pip_plugin pip)
add_executable(pip_test "main.cpp")
target_link_libraries(pip_test pip)
if(sodium_FOUND)

View File

@@ -45,18 +45,39 @@ PIVariantTypes::Enum PICodeInfo::EnumInfo::toPIVariantEnum() {
}
PIMap<PIConstChars, PICodeInfo::ClassInfo *> * PICodeInfo::classesInfo;
PIMap<PIConstChars, PICodeInfo::EnumInfo *> * PICodeInfo::enumsInfo;
PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * PICodeInfo::accessValueFunctions;
PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * PICodeInfo::accessTypeFunctions;
bool __PICodeInfoInitializer__::_inited_ = false;
PIVariant PICodeInfo::getMemberAsVariant(const void * p, const char * class_name, const char * member_name) {
if (!p || !class_name || !member_name || !accessTypeFunctions || !accessValueFunctions) return PIVariant();
AccessTypeFunction atf = accessTypeFunctions->value(class_name, (AccessTypeFunction)0);
AccessValueFunction avf = accessValueFunctions->value(class_name, (AccessValueFunction)0);
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 (!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";
}
PICodeInfo::__Storage__ * PICodeInfo::__Storage__::instance() {
static __Storage__ ret;
return &ret;
}

View File

@@ -278,28 +278,40 @@ inline PICout operator<<(PICout s, const PICodeInfo::EnumInfo & v) {
}
//! \~english Pointer to single storage of PICodeInfo::ClassInfo, access by name
//! \~russian Указатель на единое хренилище PICodeInfo::ClassInfo, доступ по имени
extern PIP_EXPORT PIMap<PIConstChars, PICodeInfo::ClassInfo *> * classesInfo;
class PIP_EXPORT __Storage__ {
__Storage__();
~__Storage__();
//! \~english Pointer to single storage of PICodeInfo::EnumInfo, access by name
//! \~russian Указатель на единое хренилище PICodeInfo::EnumInfo, доступ по имени
extern PIP_EXPORT PIMap<PIConstChars, PICodeInfo::EnumInfo *> * enumsInfo;
public:
static __Storage__ * instance();
extern PIP_EXPORT PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * accessValueFunctions;
//! \~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;
};
#define PICODEINFO (PICodeInfo::__Storage__::instance())
extern PIP_EXPORT PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * accessTypeFunctions;
inline PIByteArray getMemberValue(const void * p, const char * class_name, const char * member_name) {
if (!p || !class_name || !member_name || !accessValueFunctions) return PIByteArray();
AccessValueFunction af = accessValueFunctions->value(class_name, (AccessValueFunction)0);
if (!p || !class_name || !member_name || !PICODEINFO->accessValueFunctions) 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 || !accessTypeFunctions) return "";
AccessTypeFunction af = accessTypeFunctions->value(class_name, (AccessTypeFunction)0);
if (!class_name || !member_name || !PICODEINFO->accessTypeFunctions) return "";
AccessTypeFunction af = PICODEINFO->accessTypeFunctions->value(class_name, (AccessTypeFunction)0);
if (!af) return "";
return af(member_name);
}
@@ -317,19 +329,5 @@ void serialize(PIByteArray & ret, const T & v) {}
} // namespace PICodeInfo
class PIP_EXPORT __PICodeInfoInitializer__ {
public:
__PICodeInfoInitializer__() {
if (_inited_) return;
_inited_ = true;
PICodeInfo::classesInfo = new PIMap<PIConstChars, PICodeInfo::ClassInfo *>;
PICodeInfo::enumsInfo = new PIMap<PIConstChars, PICodeInfo::EnumInfo *>;
PICodeInfo::accessValueFunctions = new PIMap<PIConstChars, PICodeInfo::AccessValueFunction>;
PICodeInfo::accessTypeFunctions = new PIMap<PIConstChars, PICodeInfo::AccessTypeFunction>;
}
static bool _inited_;
};
static __PICodeInfoInitializer__ __picodeinfoinitializer__;
#endif // PICODEINFO_H

View File

@@ -4,13 +4,29 @@
#include "pijson.h"
#include "pimathbase.h"
#include "pip.h"
#include "piplugin.h"
#include "pivaluetree.h"
#include "test_plugin_shared.h"
using namespace PICoutManipulators;
int main(int argc, char * argv[]) {
PICodeParser cp;
cp.parseFile("kmm_types.h", false);
PIPluginLoader loader;
for (int j = 0; j < 2; ++j) {
piCout << "\nITER" << j;
loader.load("pip_plugin");
auto f = loader.resolve("myFunc");
if (f) {
PIMap<int, MyFunc> funcs;
((void (*)(PIMap<int, MyFunc> &))f)(funcs);
piCout << "size =" << funcs.size();
for (auto i: funcs) {
piCout << i.first;
i.second();
}
}
loader.unload();
}
return 0;
}

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::classesInfo\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::enumsInfo\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(*classesInfo)[ci->name] = ci;\n";
ts << "\t(*PICODEINFO->classesInfo)[ci->name] = ci;\n";
if (e->parent_scope) {
ts << "\tpci = "
<< "classesInfo->value(\"" << e->parent_scope->name << "\", 0);\n";
<< "PICODEINFO->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 = (*enumsInfo)[\"\"];\n";
ts << "\n\tei = (*PICODEINFO->enumsInfo)[\"\"];\n";
} else {
ts << "\n\tei = new EnumInfo();\n";
ts << "\t(*enumsInfo)[\"" << e->name << "\"] = ei;\n";
ts << "\t(*PICODEINFO->enumsInfo)[\"" << e->name << "\"] = ei;\n";
ts << "\tei->name = \"" << e->name << "\";\n";
if (!e->meta.isEmpty()) {
auto i = e->meta.makeIterator();
@@ -512,14 +512,15 @@ bool writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met
}
}
ts << "\n\n// Metainformation\n\n__ClassInfo_" << defname << "_Initializer__::__ClassInfo_" << defname << "_Initializer__() {\n";
ts << "\tif (_inited_) return;\n\t_inited_ = true;\n\n";
ts << "\tstatic __ClassInfo_" << defname << "_Initializer__::Content content;\n";
ts << "}\n\n";
ts << "__ClassInfo_" << defname << "_Initializer__::Content::Content() {\n";
if (meta) {
ts << "\tClassInfo * pci = new ClassInfo();\n";
ts << "\t(*classesInfo)[\"\"] = pci;\n";
ts << "\t(*PICODEINFO->classesInfo)[\"\"] = pci;\n";
}
if (enums && !parser.enums.isEmpty()) {
ts << "\tEnumInfo * ei;\n";
ts << "\t(*enumsInfo)[\"\"] = new EnumInfo();\n";
}
if (meta) {
ts << "\n\n// Classes\n";
@@ -538,12 +539,39 @@ 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(*accessValueFunctions)[\"" << e->name << "\"] = getterValue" << toCName(e->name) << ";\n";
ts << "\t(*accessTypeFunctions)[\"" << e->name << "\"] = getterType" << toCName(e->name) << ";\n";
ts << "\t(*PICODEINFO->accessValueFunctions)[\"" << e->name << "\"] = getterValue" << toCName(e->name) << ";\n";
ts << "\t(*PICODEINFO->accessTypeFunctions)[\"" << e->name << "\"] = getterType" << toCName(e->name) << ";\n";
}
}
ts << "}\n\n";
ts << "__ClassInfo_" << defname << "_Initializer__::Content::~Content() {\n";
if (meta) {
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";
}
}
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";
}
}
}
if (getters) {
ts << "\n// Getters clean\n";
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 << "}\n";
ts << "\n\nbool __ClassInfo_" << defname << "_Initializer__::_inited_ = false;\n";
}
f.close();
@@ -575,7 +603,14 @@ bool writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met
}
if (meta || enums || getters) {
ts << "\n\n// Metainformation\n\nclass __ClassInfo_" << defname << "_Initializer__ {\n";
ts << "public:\n\t__ClassInfo_" << defname << "_Initializer__();\n\tstatic bool _inited_;\n};\n";
ts << "public:\n";
ts << "\t__ClassInfo_" << defname << "_Initializer__();\n";
ts << "\tclass Content {\n";
ts << "\tpublic:\n";
ts << "\t\tContent();\n";
ts << "\t\t~Content();\n";
ts << "\t};\n";
ts << "};\n";
ts << "\nstatic __ClassInfo_" << defname << "_Initializer__ __classinfo_" << defname.toLowerCase() << "_initializer__;\n";
}
ts << "\n\n#endif // " << defname << "\n";