comparison src/vamp-hostsdk/PluginLoader.cpp @ 473:0545cd3f1738 enumerate-options

Add plugin enumeration options (for use by piper server, needs testing)
author Chris Cannam
date Wed, 02 Nov 2016 14:22:20 +0000
parents a94ab90dfd53
children 628a5b8ff634
comparison
equal deleted inserted replaced
472:79a219ba6178 473:0545cd3f1738
59 public: 59 public:
60 Impl(); 60 Impl();
61 virtual ~Impl(); 61 virtual ~Impl();
62 62
63 PluginKeyList listPlugins(); 63 PluginKeyList listPlugins();
64 PluginKeyList listPluginsIn(vector<string>);
65 PluginKeyList listPluginsNotIn(vector<string>);
64 66
65 Plugin *loadPlugin(PluginKey key, 67 Plugin *loadPlugin(PluginKey key,
66 float inputSampleRate, 68 float inputSampleRate,
67 int adapterFlags); 69 int adapterFlags);
68 70
94 96
95 virtual void pluginDeleted(PluginDeletionNotifyAdapter *adapter); 97 virtual void pluginDeleted(PluginDeletionNotifyAdapter *adapter);
96 98
97 map<PluginKey, string> m_pluginLibraryNameMap; 99 map<PluginKey, string> m_pluginLibraryNameMap;
98 bool m_allPluginsEnumerated; 100 bool m_allPluginsEnumerated;
99 void enumeratePlugins(PluginKey forPlugin = ""); 101
102 struct Enumeration {
103 enum { All, SinglePlugin, InLibraries, NotInLibraries } type;
104 PluginKey key;
105 vector<string> libraryNames;
106 Enumeration() : type(All) { }
107 };
108 vector<string> listLibraryFilesFor(Enumeration);
109
110 /// Populate m_pluginLibraryNameMap and return a list of the keys
111 /// that were added to it
112 vector<PluginKey> enumeratePlugins(Enumeration);
100 113
101 map<PluginKey, PluginCategoryHierarchy> m_taxonomy; 114 map<PluginKey, PluginCategoryHierarchy> m_taxonomy;
102 void generateTaxonomy(); 115 void generateTaxonomy();
103 116
104 map<Plugin *, void *> m_pluginLibraryHandleMap; 117 map<Plugin *, void *> m_pluginLibraryHandleMap;
142 PluginLoader::listPlugins() 155 PluginLoader::listPlugins()
143 { 156 {
144 return m_impl->listPlugins(); 157 return m_impl->listPlugins();
145 } 158 }
146 159
160 PluginLoader::PluginKeyList
161 PluginLoader::listPluginsIn(vector<string> libs)
162 {
163 return m_impl->listPluginsIn(libs);
164 }
165
166 PluginLoader::PluginKeyList
167 PluginLoader::listPluginsNotIn(vector<string> libs)
168 {
169 return m_impl->listPluginsNotIn(libs);
170 }
171
147 Plugin * 172 Plugin *
148 PluginLoader::loadPlugin(PluginKey key, 173 PluginLoader::loadPlugin(PluginKey key,
149 float inputSampleRate, 174 float inputSampleRate,
150 int adapterFlags) 175 int adapterFlags)
151 { 176 {
186 } 211 }
187 212
188 PluginLoader::PluginKeyList 213 PluginLoader::PluginKeyList
189 PluginLoader::Impl::listPlugins() 214 PluginLoader::Impl::listPlugins()
190 { 215 {
191 if (!m_allPluginsEnumerated) enumeratePlugins(); 216 if (!m_allPluginsEnumerated) enumeratePlugins({});
192 217
193 vector<PluginKey> plugins; 218 vector<PluginKey> plugins;
194 for (map<PluginKey, string>::iterator mi = m_pluginLibraryNameMap.begin(); 219 for (const auto &mi: m_pluginLibraryNameMap) {
195 mi != m_pluginLibraryNameMap.end(); ++mi) { 220 plugins.push_back(mi.first);
196 plugins.push_back(mi->first);
197 } 221 }
198 222
199 return plugins; 223 return plugins;
200 } 224 }
201 225
202 void 226 PluginLoader::PluginKeyList
203 PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin) 227 PluginLoader::Impl::listPluginsIn(vector<string> libs)
228 {
229 Enumeration enumeration;
230 enumeration.type = Enumeration::InLibraries;
231 enumeration.libraryNames = libs;
232 return enumeratePlugins(enumeration);
233 }
234
235 PluginLoader::PluginKeyList
236 PluginLoader::Impl::listPluginsNotIn(vector<string> libs)
237 {
238 Enumeration enumeration;
239 enumeration.type = Enumeration::NotInLibraries;
240 enumeration.libraryNames = libs;
241 return enumeratePlugins(enumeration);
242 }
243
244 vector<string>
245 PluginLoader::Impl::listLibraryFilesFor(Enumeration enumeration)
246 {
247 Files::Filter filter;
248
249 switch (enumeration.type) {
250
251 case Enumeration::All:
252 filter.type = Files::Filter::All;
253 break;
254
255 case Enumeration::SinglePlugin:
256 {
257 string libraryName, identifier;
258 if (!decomposePluginKey(enumeration.key, libraryName, identifier)) {
259 std::cerr << "WARNING: Vamp::HostExt::PluginLoader: "
260 << "Invalid plugin key \"" << enumeration.key
261 << "\" in enumerate" << std::endl;
262 return {};
263 }
264 filter.type = Files::Filter::Matching;
265 filter.libraryNames = { libraryName };
266 break;
267 }
268
269 case Enumeration::InLibraries:
270 filter.type = Files::Filter::Matching;
271 filter.libraryNames = enumeration.libraryNames;
272 break;
273
274 case Enumeration::NotInLibraries:
275 filter.type = Files::Filter::NotMatching;
276 filter.libraryNames = enumeration.libraryNames;
277 break;
278 }
279
280 return Files::listLibraryFilesMatching(filter);
281 }
282
283 vector<PluginLoader::PluginKey>
284 PluginLoader::Impl::enumeratePlugins(Enumeration enumeration)
204 { 285 {
205 string libraryName, identifier; 286 string libraryName, identifier;
206 vector<string> fullPaths; 287 if (enumeration.type == Enumeration::SinglePlugin) {
288 decomposePluginKey(enumeration.key, libraryName, identifier);
289 }
207 290
208 if (forPlugin != "") { 291 vector<string> fullPaths = listLibraryFilesFor(enumeration);
209 if (!decomposePluginKey(forPlugin, libraryName, identifier)) { 292
210 std::cerr << "WARNING: Vamp::HostExt::PluginLoader: Invalid plugin key \"" 293 // For these we should warn if a plugin can be loaded from a library
211 << forPlugin << "\" in enumerate" << std::endl; 294 bool specific = (enumeration.type == Enumeration::SinglePlugin ||
212 return; 295 enumeration.type == Enumeration::InLibraries);
213 } 296
214 fullPaths = Files::listLibraryFilesMatching(libraryName); 297 vector<PluginKey> added;
215 } else { 298
216 fullPaths = Files::listLibraryFiles();
217 }
218
219 for (size_t i = 0; i < fullPaths.size(); ++i) { 299 for (size_t i = 0; i < fullPaths.size(); ++i) {
220 300
221 string fullPath = fullPaths[i]; 301 string fullPath = fullPaths[i];
222 void *handle = Files::loadLibrary(fullPath); 302 void *handle = Files::loadLibrary(fullPath);
223 if (!handle) continue; 303 if (!handle) continue;
225 VampGetPluginDescriptorFunction fn = 305 VampGetPluginDescriptorFunction fn =
226 (VampGetPluginDescriptorFunction)Files::lookupInLibrary 306 (VampGetPluginDescriptorFunction)Files::lookupInLibrary
227 (handle, "vampGetPluginDescriptor"); 307 (handle, "vampGetPluginDescriptor");
228 308
229 if (!fn) { 309 if (!fn) {
230 if (forPlugin != "") { 310 if (specific) {
231 cerr << "Vamp::HostExt::PluginLoader: No vampGetPluginDescriptor function found in library \"" 311 cerr << "Vamp::HostExt::PluginLoader: "
312 << "No vampGetPluginDescriptor function found in library \""
232 << fullPath << "\"" << endl; 313 << fullPath << "\"" << endl;
233 } 314 }
234 Files::unloadLibrary(handle); 315 Files::unloadLibrary(handle);
235 continue; 316 continue;
236 } 317 }
240 bool found = false; 321 bool found = false;
241 322
242 while ((descriptor = fn(VAMP_API_VERSION, index))) { 323 while ((descriptor = fn(VAMP_API_VERSION, index))) {
243 ++index; 324 ++index;
244 if (identifier != "") { 325 if (identifier != "") {
245 if (descriptor->identifier != identifier) continue; 326 if (descriptor->identifier != identifier) {
327 continue;
328 }
246 } 329 }
247 found = true; 330 found = true;
248 PluginKey key = composePluginKey(fullPath, descriptor->identifier); 331 PluginKey key = composePluginKey(fullPath, descriptor->identifier);
249 // std::cerr << "enumerate: " << key << " (path: " << fullPath << ")" << std::endl;
250 if (m_pluginLibraryNameMap.find(key) == 332 if (m_pluginLibraryNameMap.find(key) ==
251 m_pluginLibraryNameMap.end()) { 333 m_pluginLibraryNameMap.end()) {
252 m_pluginLibraryNameMap[key] = fullPath; 334 m_pluginLibraryNameMap[key] = fullPath;
253 } 335 }
254 } 336 added.push_back(key);
255 337 }
256 if (!found && forPlugin != "") { 338
339 if (!found && specific) {
257 cerr << "Vamp::HostExt::PluginLoader: Plugin \"" 340 cerr << "Vamp::HostExt::PluginLoader: Plugin \""
258 << identifier << "\" not found in library \"" 341 << identifier << "\" not found in library \""
259 << fullPath << "\"" << endl; 342 << fullPath << "\"" << endl;
260 } 343 }
261 344
262 Files::unloadLibrary(handle); 345 Files::unloadLibrary(handle);
263 } 346 }
264 347
265 if (forPlugin == "") m_allPluginsEnumerated = true; 348 if (enumeration.type == Enumeration::All) {
349 m_allPluginsEnumerated = true;
350 }
351
352 return added;
266 } 353 }
267 354
268 PluginLoader::PluginKey 355 PluginLoader::PluginKey
269 PluginLoader::Impl::composePluginKey(string libraryName, string identifier) 356 PluginLoader::Impl::composePluginKey(string libraryName, string identifier)
270 { 357 {
300 string 387 string
301 PluginLoader::Impl::getLibraryPathForPlugin(PluginKey plugin) 388 PluginLoader::Impl::getLibraryPathForPlugin(PluginKey plugin)
302 { 389 {
303 if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) { 390 if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
304 if (m_allPluginsEnumerated) return ""; 391 if (m_allPluginsEnumerated) return "";
305 enumeratePlugins(plugin); 392 Enumeration enumeration;
393 enumeration.type = Enumeration::SinglePlugin;
394 enumeration.key = plugin;
395 enumeratePlugins(enumeration);
306 } 396 }
307 if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) { 397 if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) {
308 return ""; 398 return "";
309 } 399 }
310 return m_pluginLibraryNameMap[plugin]; 400 return m_pluginLibraryNameMap[plugin];