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