diff --git a/CMakeLists.txt b/CMakeLists.txt index bba72ee9..8eccd0b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/libs/main/code/picodeinfo.cpp b/libs/main/code/picodeinfo.cpp index 21ebceb9..ee54c934 100644 --- a/libs/main/code/picodeinfo.cpp +++ b/libs/main/code/picodeinfo.cpp @@ -45,18 +45,39 @@ PIVariantTypes::Enum PICodeInfo::EnumInfo::toPIVariantEnum() { } -PIMap * PICodeInfo::classesInfo; -PIMap * PICodeInfo::enumsInfo; -PIMap * PICodeInfo::accessValueFunctions; -PIMap * 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; + 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"; +} + + +PICodeInfo::__Storage__ * PICodeInfo::__Storage__::instance() { + static __Storage__ ret; + return &ret; +} diff --git a/libs/main/code/picodeinfo.h b/libs/main/code/picodeinfo.h index 7e9e36d6..e49dd2c4 100644 --- a/libs/main/code/picodeinfo.h +++ b/libs/main/code/picodeinfo.h @@ -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 * 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 * enumsInfo; +public: + static __Storage__ * instance(); -extern PIP_EXPORT PIMap * accessValueFunctions; + //! \~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; +}; + +#define PICODEINFO (PICodeInfo::__Storage__::instance()) -extern PIP_EXPORT PIMap * 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; - PICodeInfo::enumsInfo = new PIMap; - PICodeInfo::accessValueFunctions = new PIMap; - PICodeInfo::accessTypeFunctions = new PIMap; - } - static bool _inited_; -}; - -static __PICodeInfoInitializer__ __picodeinfoinitializer__; #endif // PICODEINFO_H diff --git a/main.cpp b/main.cpp index 17cc3dd0..e1910edc 100644 --- a/main.cpp +++ b/main.cpp @@ -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 funcs; + ((void (*)(PIMap &))f)(funcs); + piCout << "size =" << funcs.size(); + for (auto i: funcs) { + piCout << i.first; + i.second(); + } + } + loader.unload(); + } return 0; } diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index b5ffd4fe..4525ecde 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::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";