Mercurial > hg > vamp-plugin-sdk
comparison vamp-sdk/hostext/PluginLoader.cpp @ 69:3456fe86d385
* Switch PluginLoader to an m_impl structure to make it generally nicer
author | cannam |
---|---|
date | Wed, 06 Jun 2007 09:49:50 +0000 |
parents | 9d3272c7db60 |
children | 64697dca0d48 |
comparison
equal
deleted
inserted
replaced
68:47d6e670a810 | 69:3456fe86d385 |
---|---|
64 | 64 |
65 namespace Vamp { | 65 namespace Vamp { |
66 | 66 |
67 namespace HostExt { | 67 namespace HostExt { |
68 | 68 |
69 class PluginLoader::Impl | |
70 { | |
71 public: | |
72 virtual ~Impl() { } | |
73 | |
74 PluginKeyList listPlugins(); | |
75 | |
76 Plugin *loadPlugin(PluginKey key, | |
77 float inputSampleRate, | |
78 int adapterFlags); | |
79 | |
80 PluginKey composePluginKey(string libraryName, string identifier); | |
81 | |
82 PluginCategoryHierarchy getPluginCategory(PluginKey key); | |
83 | |
84 std::string getLibraryPathForPlugin(PluginKey key); | |
85 | |
86 protected: | |
87 class PluginDeletionNotifyAdapter : public PluginWrapper { | |
88 public: | |
89 PluginDeletionNotifyAdapter(Plugin *plugin, Impl *loader); | |
90 virtual ~PluginDeletionNotifyAdapter(); | |
91 protected: | |
92 Impl *m_loader; | |
93 }; | |
94 | |
95 virtual void pluginDeleted(PluginDeletionNotifyAdapter *adapter); | |
96 | |
97 std::map<PluginKey, std::string> m_pluginLibraryNameMap; | |
98 void generateLibraryMap(); | |
99 | |
100 std::map<PluginKey, PluginCategoryHierarchy> m_taxonomy; | |
101 void generateTaxonomy(); | |
102 | |
103 std::map<Plugin *, void *> m_pluginLibraryHandleMap; | |
104 | |
105 void *loadLibrary(std::string path); | |
106 void unloadLibrary(void *handle); | |
107 void *lookupInLibrary(void *handle, const char *symbol); | |
108 | |
109 std::string splicePath(std::string a, std::string b); | |
110 std::vector<std::string> listFiles(std::string dir, std::string ext); | |
111 }; | |
112 | |
69 PluginLoader * | 113 PluginLoader * |
70 PluginLoader::m_instance = 0; | 114 PluginLoader::m_instance = 0; |
71 | 115 |
72 PluginLoader::PluginLoader() | 116 PluginLoader::PluginLoader() |
73 { | 117 { |
118 m_impl = new Impl(); | |
74 } | 119 } |
75 | 120 |
76 PluginLoader::~PluginLoader() | 121 PluginLoader::~PluginLoader() |
77 { | 122 { |
123 delete m_impl; | |
78 } | 124 } |
79 | 125 |
80 PluginLoader * | 126 PluginLoader * |
81 PluginLoader::getInstance() | 127 PluginLoader::getInstance() |
82 { | 128 { |
84 return m_instance; | 130 return m_instance; |
85 } | 131 } |
86 | 132 |
87 vector<PluginLoader::PluginKey> | 133 vector<PluginLoader::PluginKey> |
88 PluginLoader::listPlugins() | 134 PluginLoader::listPlugins() |
135 { | |
136 return m_impl->listPlugins(); | |
137 } | |
138 | |
139 Plugin * | |
140 PluginLoader::loadPlugin(PluginKey key, | |
141 float inputSampleRate, | |
142 int adapterFlags) | |
143 { | |
144 return m_impl->loadPlugin(key, inputSampleRate, adapterFlags); | |
145 } | |
146 | |
147 PluginLoader::PluginKey | |
148 PluginLoader::composePluginKey(string libraryName, string identifier) | |
149 { | |
150 return m_impl->composePluginKey(libraryName, identifier); | |
151 } | |
152 | |
153 PluginLoader::PluginCategoryHierarchy | |
154 PluginLoader::getPluginCategory(PluginKey key) | |
155 { | |
156 return m_impl->getPluginCategory(key); | |
157 } | |
158 | |
159 string | |
160 PluginLoader::getLibraryPathForPlugin(PluginKey key) | |
161 { | |
162 return m_impl->getLibraryPathForPlugin(key); | |
163 } | |
164 | |
165 vector<PluginLoader::PluginKey> | |
166 PluginLoader::Impl::listPlugins() | |
89 { | 167 { |
90 if (m_pluginLibraryNameMap.empty()) generateLibraryMap(); | 168 if (m_pluginLibraryNameMap.empty()) generateLibraryMap(); |
91 | 169 |
92 vector<PluginKey> plugins; | 170 vector<PluginKey> plugins; |
93 for (map<PluginKey, string>::iterator mi = | 171 for (map<PluginKey, string>::iterator mi = |
98 | 176 |
99 return plugins; | 177 return plugins; |
100 } | 178 } |
101 | 179 |
102 void | 180 void |
103 PluginLoader::generateLibraryMap() | 181 PluginLoader::Impl::generateLibraryMap() |
104 { | 182 { |
105 vector<string> path = PluginHostAdapter::getPluginPath(); | 183 vector<string> path = PluginHostAdapter::getPluginPath(); |
106 | 184 |
107 for (size_t i = 0; i < path.size(); ++i) { | 185 for (size_t i = 0; i < path.size(); ++i) { |
108 | 186 |
141 } | 219 } |
142 } | 220 } |
143 } | 221 } |
144 | 222 |
145 PluginLoader::PluginKey | 223 PluginLoader::PluginKey |
146 PluginLoader::composePluginKey(string libraryName, string identifier) | 224 PluginLoader::Impl::composePluginKey(string libraryName, string identifier) |
147 { | 225 { |
148 string basename = libraryName; | 226 string basename = libraryName; |
149 | 227 |
150 string::size_type li = basename.rfind('/'); | 228 string::size_type li = basename.rfind('/'); |
151 if (li != string::npos) basename = basename.substr(li + 1); | 229 if (li != string::npos) basename = basename.substr(li + 1); |
155 | 233 |
156 return basename + ":" + identifier; | 234 return basename + ":" + identifier; |
157 } | 235 } |
158 | 236 |
159 PluginLoader::PluginCategoryHierarchy | 237 PluginLoader::PluginCategoryHierarchy |
160 PluginLoader::getPluginCategory(PluginKey plugin) | 238 PluginLoader::Impl::getPluginCategory(PluginKey plugin) |
161 { | 239 { |
162 if (m_taxonomy.empty()) generateTaxonomy(); | 240 if (m_taxonomy.empty()) generateTaxonomy(); |
163 if (m_taxonomy.find(plugin) == m_taxonomy.end()) return PluginCategoryHierarchy(); | 241 if (m_taxonomy.find(plugin) == m_taxonomy.end()) { |
242 return PluginCategoryHierarchy(); | |
243 } | |
164 return m_taxonomy[plugin]; | 244 return m_taxonomy[plugin]; |
165 } | 245 } |
166 | 246 |
167 string | 247 string |
168 PluginLoader::getLibraryPathForPlugin(PluginKey plugin) | 248 PluginLoader::Impl::getLibraryPathForPlugin(PluginKey plugin) |
169 { | 249 { |
170 if (m_pluginLibraryNameMap.empty()) generateLibraryMap(); | 250 if (m_pluginLibraryNameMap.empty()) generateLibraryMap(); |
171 if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) return ""; | 251 if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) return ""; |
172 return m_pluginLibraryNameMap[plugin]; | 252 return m_pluginLibraryNameMap[plugin]; |
173 } | 253 } |
174 | 254 |
175 Plugin * | 255 Plugin * |
176 PluginLoader::loadPlugin(PluginKey key, float inputSampleRate, int adapterFlags) | 256 PluginLoader::Impl::loadPlugin(PluginKey key, |
257 float inputSampleRate, int adapterFlags) | |
177 { | 258 { |
178 string fullPath = getLibraryPathForPlugin(key); | 259 string fullPath = getLibraryPathForPlugin(key); |
179 if (fullPath == "") return 0; | 260 if (fullPath == "") return 0; |
180 | 261 |
181 string::size_type ki = key.find(':'); | 262 string::size_type ki = key.find(':'); |
234 | 315 |
235 return 0; | 316 return 0; |
236 } | 317 } |
237 | 318 |
238 void | 319 void |
239 PluginLoader::generateTaxonomy() | 320 PluginLoader::Impl::generateTaxonomy() |
240 { | 321 { |
241 // cerr << "PluginLoader::generateTaxonomy" << endl; | 322 // cerr << "PluginLoader::Impl::generateTaxonomy" << endl; |
242 | 323 |
243 vector<string> path = PluginHostAdapter::getPluginPath(); | 324 vector<string> path = PluginHostAdapter::getPluginPath(); |
244 string libfragment = "/lib/"; | 325 string libfragment = "/lib/"; |
245 vector<string> catpath; | 326 vector<string> catpath; |
246 | 327 |
322 } | 403 } |
323 } | 404 } |
324 } | 405 } |
325 | 406 |
326 void * | 407 void * |
327 PluginLoader::loadLibrary(string path) | 408 PluginLoader::Impl::loadLibrary(string path) |
328 { | 409 { |
329 void *handle = 0; | 410 void *handle = 0; |
330 #ifdef _WIN32 | 411 #ifdef _WIN32 |
331 handle = LoadLibrary(path.c_str()); | 412 handle = LoadLibrary(path.c_str()); |
332 if (!handle) { | 413 if (!handle) { |
342 #endif | 423 #endif |
343 return handle; | 424 return handle; |
344 } | 425 } |
345 | 426 |
346 void | 427 void |
347 PluginLoader::unloadLibrary(void *handle) | 428 PluginLoader::Impl::unloadLibrary(void *handle) |
348 { | 429 { |
349 #ifdef _WIN32 | 430 #ifdef _WIN32 |
350 FreeLibrary((HINSTANCE)handle); | 431 FreeLibrary((HINSTANCE)handle); |
351 #else | 432 #else |
352 dlclose(handle); | 433 dlclose(handle); |
353 #endif | 434 #endif |
354 } | 435 } |
355 | 436 |
356 void * | 437 void * |
357 PluginLoader::lookupInLibrary(void *handle, const char *symbol) | 438 PluginLoader::Impl::lookupInLibrary(void *handle, const char *symbol) |
358 { | 439 { |
359 #ifdef _WIN32 | 440 #ifdef _WIN32 |
360 return (void *)GetProcAddress((HINSTANCE)handle, symbol); | 441 return (void *)GetProcAddress((HINSTANCE)handle, symbol); |
361 #else | 442 #else |
362 return (void *)dlsym(handle, symbol); | 443 return (void *)dlsym(handle, symbol); |
363 #endif | 444 #endif |
364 } | 445 } |
365 | 446 |
366 string | 447 string |
367 PluginLoader::splicePath(string a, string b) | 448 PluginLoader::Impl::splicePath(string a, string b) |
368 { | 449 { |
369 #ifdef _WIN32 | 450 #ifdef _WIN32 |
370 return a + "\\" + b; | 451 return a + "\\" + b; |
371 #else | 452 #else |
372 return a + "/" + b; | 453 return a + "/" + b; |
373 #endif | 454 #endif |
374 } | 455 } |
375 | 456 |
376 vector<string> | 457 vector<string> |
377 PluginLoader::listFiles(string dir, string extension) | 458 PluginLoader::Impl::listFiles(string dir, string extension) |
378 { | 459 { |
379 vector<string> files; | 460 vector<string> files; |
380 size_t extlen = extension.length(); | 461 size_t extlen = extension.length(); |
381 | 462 |
382 #ifdef _WIN32 | 463 #ifdef _WIN32 |
417 | 498 |
418 return files; | 499 return files; |
419 } | 500 } |
420 | 501 |
421 void | 502 void |
422 PluginLoader::pluginDeleted(PluginDeletionNotifyAdapter *adapter) | 503 PluginLoader::Impl::pluginDeleted(PluginDeletionNotifyAdapter *adapter) |
423 { | 504 { |
424 void *handle = m_pluginLibraryHandleMap[adapter]; | 505 void *handle = m_pluginLibraryHandleMap[adapter]; |
425 if (handle) unloadLibrary(handle); | 506 if (handle) unloadLibrary(handle); |
426 m_pluginLibraryHandleMap.erase(adapter); | 507 m_pluginLibraryHandleMap.erase(adapter); |
427 } | 508 } |
428 | 509 |
429 PluginLoader::PluginDeletionNotifyAdapter::PluginDeletionNotifyAdapter(Plugin *plugin, | 510 PluginLoader::Impl::PluginDeletionNotifyAdapter::PluginDeletionNotifyAdapter(Plugin *plugin, |
430 PluginLoader *loader) : | 511 Impl *loader) : |
431 PluginWrapper(plugin), | 512 PluginWrapper(plugin), |
432 m_loader(loader) | 513 m_loader(loader) |
433 { | 514 { |
434 } | 515 } |
435 | 516 |
436 PluginLoader::PluginDeletionNotifyAdapter::~PluginDeletionNotifyAdapter() | 517 PluginLoader::Impl::PluginDeletionNotifyAdapter::~PluginDeletionNotifyAdapter() |
437 { | 518 { |
438 // We need to delete the plugin before calling pluginDeleted, as | 519 // We need to delete the plugin before calling pluginDeleted, as |
439 // the delete call may require calling through to the descriptor | 520 // the delete call may require calling through to the descriptor |
440 // (for e.g. cleanup) but pluginDeleted may unload the required | 521 // (for e.g. cleanup) but pluginDeleted may unload the required |
441 // library for the call. To prevent a double deletion when our | 522 // library for the call. To prevent a double deletion when our |