From b7aef483b70491c663d8c9a881bbd6aa6aa7522e Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sat, 3 Oct 2020 13:32:43 +0300 Subject: [PATCH] PIVariantSimple now has no error when assign to non-copyable typeName patch pip_cmg according to last PIByteArray changes plugin system fix --- libs/main/code/picodeinfo.h | 7 ++++ libs/main/core/pivariantsimple.h | 19 +++++++--- libs/main/system/piplugin.cpp | 55 ++++++++++++++++++++++++----- libs/main/system/piplugin.h | 25 ++++++++----- utils/code_model_generator/main.cpp | 2 +- 5 files changed, 86 insertions(+), 22 deletions(-) diff --git a/libs/main/code/picodeinfo.h b/libs/main/code/picodeinfo.h index 97506149..c95d58b0 100644 --- a/libs/main/code/picodeinfo.h +++ b/libs/main/code/picodeinfo.h @@ -174,6 +174,13 @@ inline const char * getMemberType(const char * class_name, const char * member_n PIP_EXPORT PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name); + +template::value, int>::type = 0> +void serialize(PIByteArray & ret, const T & v) {ret << v;} + +template::value, int>::type = 0> +void serialize(PIByteArray & ret, const T & v) {} + } class PIP_EXPORT __PICodeInfoInitializer__ { diff --git a/libs/main/core/pivariantsimple.h b/libs/main/core/pivariantsimple.h index 64114a4e..c9b354be 100644 --- a/libs/main/core/pivariantsimple.h +++ b/libs/main/core/pivariantsimple.h @@ -40,12 +40,21 @@ public: virtual void deleteT(void *& ptr) {;} //virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} //virtual void fromData(void *& ptr, PIByteArray ba) {;} - static PIMap & registered() {static PIMap ret; return ret;} + //static PIMap & registered() {static PIMap ret; return ret;} +}; + + +template +class __VariantFunctions__: public __VariantFunctionsBase__ { +public: + __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} + PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} + uint hash() const final {static uint ret = typeName().hash(); return ret;} }; template -class __VariantFunctions__: public __VariantFunctionsBase__ { +class __VariantFunctions__::value>::type>: public __VariantFunctionsBase__ { public: __VariantFunctionsBase__ * instance() final {static __VariantFunctions__ ret; return &ret;} PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;} @@ -58,6 +67,7 @@ public: //void fromData(void *& ptr, PIByteArray ba) final {ba >> *(T*)ptr;} }; + class PIVariantSimple { public: PIVariantSimple() {ptr = 0; f = 0;} @@ -129,6 +139,7 @@ public: private: template bool isMyType() const { + if (!f) return false; uint mh = f->hash(), th = __VariantFunctions__().instance()->hash(); if (mh == 0 || th == 0) return false; return mh == th; @@ -146,13 +157,13 @@ private: }; - +/* #define REGISTER_PIVARIANTSIMPLE_STREAM(Type) \ STATIC_INITIALIZER_BEGIN() \ __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); \ __VariantFunctionsBase__::registered()[f->hash()] = f; \ STATIC_INITIALIZER_END() - +*/ #endif // PIVARIANTSIMPLE_H diff --git a/libs/main/system/piplugin.cpp b/libs/main/system/piplugin.cpp index b651d6b9..a711e7d7 100644 --- a/libs/main/system/piplugin.cpp +++ b/libs/main/system/piplugin.cpp @@ -27,6 +27,36 @@ #define STR(s) STR_WF(s) +PIPluginInfo::PIPluginInfo() { + in_plugin = false; +} + + +void PIPluginInfo::setUserVersion(const PIString & v) { + user_version[in_plugin ? 1 : 0] = v; +} + + +void PIPluginInfo::setStaticSection(int type, void * ptr) { + static_sections[in_plugin ? 1 : 0][type] = ptr; +} + + +PIString PIPluginInfo::userVersion(bool plugin) const { + return user_version[plugin ? 1 : 0]; +} + + +PIMap PIPluginInfo::staticSections(bool plugin) const { + return static_sections[plugin ? 1 : 0]; +} + + +void PIPluginInfo::enterPlugin() { + in_plugin = true; +} + + PIPluginInfo * PIPluginInfo::instance() { static PIPluginInfo ret; return &ret; @@ -78,8 +108,8 @@ bool PIPluginLoader::load(const PIString & name) { unload(); return false; } - if (PIPluginInfo::instance()->user_version.size_s() > 1) { - PIString pversion = plugin_info->user_version, lversion = PIPluginInfo::instance()->user_version; + if (PIPluginInfo::instance()->userVersion(false).size_s() > 1) { + PIString pversion = plugin_info->userVersion(true), lversion = PIPluginInfo::instance()->userVersion(false); if (pversion != lversion) { piCout << "Load plugin \"" << name << "\" error: invalid user version: plugin" << pversion << "!=" << lversion; unload(); @@ -88,12 +118,16 @@ bool PIPluginLoader::load(const PIString & name) { } func_static_merge = (FunctionStaticMerge)lib.resolve(STR(__PIP_PLUGIN_STATIC_MERGE_FUNC__)); if (func_static_merge) { - piCout << PIPluginInfo::instance()->static_sections.keys() << plugin_info->static_sections.keys(); - auto it = PIPluginInfo::instance()->static_sections.makeIterator(); + auto pss = plugin_info->staticSections(true), lss = PIPluginInfo::instance()->staticSections(false); + piCout << lss.keys() << pss.keys(); + + auto it = lss.makeIterator(); while (it.next()) { - if (!plugin_info->static_sections.contains(it.key())) + if (!pss.contains(it.key())) continue; - func_static_merge(it.key(), plugin_info->static_sections.value(it.key()), it.value()); + void * from = pss.value(it.key()), * to = it.value(); + if (from != to) + func_static_merge(it.key(), from, to); } } loaded = true; @@ -121,11 +155,14 @@ void * PIPluginLoader::resolve(const char * name) { void PIPluginLoader::mergeStatic() { if (!loaded || !func_static_merge || !plugin_info) return; - auto it = PIPluginInfo::instance()->static_sections.makeIterator(); + auto pss = plugin_info->staticSections(true), lss = PIPluginInfo::instance()->staticSections(false); + auto it = lss.makeIterator(); while (it.next()) { - if (!plugin_info->static_sections.contains(it.key())) + if (!pss.contains(it.key())) continue; - func_static_merge(it.key(), it.value(), plugin_info->static_sections.value(it.key())); + void * from = it.value(), * to = pss.value(it.key()); + if (from != to) + func_static_merge(it.key(), from, to); } } diff --git a/libs/main/system/piplugin.h b/libs/main/system/piplugin.h index 7ed670d2..99a1576c 100644 --- a/libs/main/system/piplugin.h +++ b/libs/main/system/piplugin.h @@ -31,15 +31,15 @@ #ifdef DOXYGEN +//! Declare plugin export functions, should be used before other PIP_PLUGIN_* macros +#define PIP_PLUGIN + //! Set user version to check it while loading #define PIP_PLUGIN_SET_USER_VERSION(v) //! Add pointer to future merge with plugin. Type is integer #define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) -//! Declare plugin export functions -#define PIP_PLUGIN - //! Declare function to merge static sections. This is functions //! with 3 arguments: (int type, void * from, void * to). //! This function invoked first while loading plugin with @@ -75,6 +75,9 @@ STATIC_INITIALIZER_END #define PIP_PLUGIN \ + STATIC_INITIALIZER_BEGIN \ + PIPluginInfo::instance()->enterPlugin(); \ + STATIC_INITIALIZER_END \ extern "C" { \ PIP_PLUGIN_EXPORT int __PIP_PLUGIN_LOADER_VERSION_FUNC__() {return __PIP_PLUGIN_LOADER_VERSION__;} \ PIP_PLUGIN_EXPORT PIPluginInfo * __PIP_PLUGIN_PLUGIN_INFO_FUNC__() {return PIPluginInfo::instance();} \ @@ -93,15 +96,21 @@ class PIP_EXPORT PIPluginInfo { public: - PIPluginInfo() {} + PIPluginInfo(); - void setUserVersion(const PIString & v) {user_version = v;} - void setStaticSection(int type, void * ptr) {static_sections[type] = ptr;} + void setUserVersion(const PIString & v); + void setStaticSection(int type, void * ptr); + PIString userVersion(bool plugin) const; + PIMap staticSections(bool plugin) const; + void enterPlugin(); static PIPluginInfo * instance(); - PIString user_version; - PIMap static_sections; +private: + PIString user_version[2]; + PIMap static_sections[2]; + bool in_plugin; + }; diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index b207d679..8742ef26 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -325,7 +325,7 @@ void makeGetterValue(PIFile & f, const PICodeParser::Entity * e) { piForeachC (PICodeParser::Member & m, e->members) { if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue; - f << "\tif (strcmp(name, \"" << m.name << "\") == 0) {ret << o->" << m.name << "; return ret;}\n"; + f << "\tif (strcmp(name, \"" << m.name << "\") == 0) {serialize(ret, o->" << m.name << "); return ret;}\n"; } f << "\treturn ret;\n}\n"; }