diff --git a/solanaceae/plugin/plugin_manager.cpp b/solanaceae/plugin/plugin_manager.cpp index d9fc1ab..88d5ab1 100644 --- a/solanaceae/plugin/plugin_manager.cpp +++ b/solanaceae/plugin/plugin_manager.cpp @@ -5,23 +5,24 @@ #include // def -std::map g_instance_map {}; +std::map> g_instance_map {}; extern "C" { -void* g_resolveInstance__internal(const char* id) { +void* g_resolveInstance__internal(const char* id, const char* version) { if (auto it = g_instance_map.find(id); it != g_instance_map.end()) { - return it->second; + if (auto it_v = it->second.find(version); it_v != it->second.end()) { + return it_v->second; + } } return nullptr; } -void g_provideInstance__internal(const char* id, const char* plugin_name, void* instance) { - g_instance_map[id] = instance; - std::cout << "PLM '" << plugin_name << "' provided '" << id << "'\n"; +void g_provideInstance__internal(const char* id, const char* version, const char* plugin_name, void* instance) { + g_instance_map[id][version] = instance; + std::cout << "PLM: '" << plugin_name << "' provided '" << id << "' version '" << version << "'\n"; } - } // extern C PluginManager::~PluginManager(void) { diff --git a/solanaceae/plugin/plugin_manager.hpp b/solanaceae/plugin/plugin_manager.hpp index 90afd20..be1b280 100644 --- a/solanaceae/plugin/plugin_manager.hpp +++ b/solanaceae/plugin/plugin_manager.hpp @@ -10,20 +10,50 @@ #include // TODO: save plug name to instance -extern std::map g_instance_map; +// id -> version -> ptr +extern std::map> g_instance_map; extern "C" { -void* g_resolveInstance__internal(const char* id); +void* g_resolveInstance__internal(const char* id, const char* version); -void g_provideInstance__internal(const char* id, const char* plugin_name, void* instance); +void g_provideInstance__internal(const char* id, const char* version, const char* plugin_name, void* instance); } // extern C +namespace internal { + template + class g_type_version { + typedef char yes[1]; + typedef char no [2]; + + template static yes& test_version(decltype(&C::version)); + template static no& test_version(...); + + static bool const has_version = sizeof(test_version(nullptr)) == sizeof(yes); + static constexpr const char* get_version(void) { + if constexpr (has_version) { + return T::version; + } else { + return "UNK"; // default version + } + } + + public: + static constexpr const char* version = get_version(); + }; +} // internal + + // templated helper, use or make sure vtable is right +template +void g_provideInstance(const char* id, const char* version, const char* plugin_name, T* instance) { + g_provideInstance__internal(id, version, plugin_name, instance); +} + template void g_provideInstance(const char* id, const char* plugin_name, T* instance) { - g_provideInstance__internal(id, plugin_name, instance); + g_provideInstance__internal(id, internal::g_type_version::version, plugin_name, instance); } // only on host! diff --git a/solanaceae/plugin/solana_plugin_v1.h b/solanaceae/plugin/solana_plugin_v1.h index db07139..86680b1 100644 --- a/solanaceae/plugin/solana_plugin_v1.h +++ b/solanaceae/plugin/solana_plugin_v1.h @@ -3,7 +3,7 @@ #include -#define SOLANA_PLUGIN_VERSION 8 +#define SOLANA_PLUGIN_VERSION 9 #if defined(_MSC_VER) || defined(__MINGW32__) #define SOLANA_PLUGIN_EXPORT __declspec(dllexport) @@ -27,10 +27,9 @@ extern "C" { // public plugin stuff here struct SolanaAPI { - void* (*resolveInstance)(const char* id); - + void* (*resolveInstance)(const char* id, const char* version); // resolve_all_instances(const char* id) - void (*provideInstance)(const char* id, const char* plugin_name, void* instance); + void (*provideInstance)(const char* id, const char* version, const char* plugin_name, void* instance); }; // ---------- info ----------