coming
天行健 君子以自强不息
记录我的成长
文章目录
该类负责对plugins文件夹下的动态链接库进行组织,与其中函数的调用。定义于src/musikcore/plugin/PluginFactory.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| class PluginFactory { public: static PluginFactory& Instance(); template <typename T> struct ReleaseDeleter { void operator()(T* t) { t->Release(); } };
template <typename T> struct NullDeleter { void operator()(T* t) { } }; template <class T, class D> void QueryInterface( const std::string& functionName, std::function<void(mymusic::core::sdk::IPlugin*, std::shared_ptr<T>, const std::string&)> handler) { std::unique_lock<std::mutex> lock(this->mutex);
typedef T * STDCALL(PluginInterfaceCall);
for (std::shared_ptr<Descriptor> descriptor : this->plugins) { if (functionName == "GetPlugin" || prefs->GetBool(descriptor->key.c_str(), true)) { PluginInterfaceCall funcPtr = #ifdef WIN32 (PluginInterfaceCall) GetProcAddress((HMODULE)(descriptor->nativeHandle), functionName.c_str()); #else (PluginInterfaceCall)dlsym(descriptor->nativeHandle, functionName.c_str()); #endif if (funcPtr) { T* result = funcPtr();
if (result) { handler(descriptor->plugin, std::shared_ptr<T>(result, D()), descriptor->filename); } } } } } template <class T, class D> std::vector<std::shared_ptr<T> > QueryInterface(const std::string& functionName) { std::vector<std::shared_ptr<T> > plugins;
QueryInterface<T, D>( functionName, [&plugins]( mymusic::core::sdk::IPlugin* unused, std::shared_ptr<T> plugin, const std::string& fn) { plugins.push_back(plugin); });
return plugins; } template <class T> void QueryFunction( const std::string& functionName, std::function<void(mymusic::core::sdk::IPlugin*, T)> handler) { std::unique_lock<std::mutex> lock(this->mutex);
for (std::shared_ptr<Descriptor> descriptor : this->plugins) { if (prefs->GetBool(descriptor->key.c_str(), true)) { T funcPtr = #ifdef WIN32 (T) GetProcAddress((HMODULE)(descriptor->nativeHandle), functionName.c_str()); #else (T)dlsym(descriptor->nativeHandle, functionName.c_str()); #endif if (funcPtr) { handler(descriptor->plugin, funcPtr); } } } } std::shared_ptr<mymusic::core::sdk::IPlugin> QueryGuid(const std::string& guid) { using T = mymusic::core::sdk::IPlugin; std::shared_ptr<T> result; using Deleter = PluginFactory::ReleaseDeleter<T>; Instance().QueryInterface<T, Deleter>( "GetPlugin", [&result, guid](T* unused, std::shared_ptr<T> plugin, const std::string& fn) { if (std::string(plugin->Guid()) == guid) { result = plugin; } }); return result; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| private: struct Descriptor { mymusic::core::sdk::IPlugin* plugin; void* nativeHandle; std::string filename; std::string key; }; PluginFactory(); ~PluginFactory();
void LoadPlugins(); std::vector<std::shared_ptr<Descriptor> > plugins; std::mutex mutex; std::shared_ptr<mymusic::core::sdk::IPreferences> prefs; };
|
本文代表个人观点,内容仅供参考。若有不恰当之处,望不吝赐教!