comparison plugin/PiperVampPluginFactory.cpp @ 1376:d9511f9e04d7 dev/refactor-piper-related

Introduce some POD structs for describing an external server application and the desired libraries to load from it, and disambiguating between empty list request and invalid list request. This allows for overriding PiperVampPluginFactory behaviour for using a PluginScan to populate the list request.
author Lucas Thompson <lucas.thompson@qmul.ac.uk>
date Fri, 10 Feb 2017 11:15:19 +0000
parents da5f4d37988d
children f1c4ca3ccaa3
comparison
equal deleted inserted replaced
1375:da5f4d37988d 1376:d9511f9e04d7
37 #include <QFileInfo> 37 #include <QFileInfo>
38 #include <QTextStream> 38 #include <QTextStream>
39 #include <QCoreApplication> 39 #include <QCoreApplication>
40 40
41 #include <iostream> 41 #include <iostream>
42 #include <algorithm>
42 43
43 #include "base/Profiler.h" 44 #include "base/Profiler.h"
44 #include "base/HelperExecPath.h" 45 #include "base/HelperExecPath.h"
45 46
46 using namespace std; 47 using namespace std;
52 void log(std::string message) const override { 53 void log(std::string message) const override {
53 SVDEBUG << "PiperVampPluginFactory: " << message << endl; 54 SVDEBUG << "PiperVampPluginFactory: " << message << endl;
54 } 55 }
55 }; 56 };
56 57
57 PiperVampPluginFactory::PiperVampPluginFactory(std::initializer_list<QString> servers) : 58 PiperVampPluginFactory::PiperVampPluginFactory(std::initializer_list<ServerDescription> servers) :
58 m_logger(new Logger) 59 m_logger(new Logger)
59 { 60 {
60 HelperExecPath hep(HelperExecPath::AllInstalled); 61 HelperExecPath hep(HelperExecPath::AllInstalled);
61 62
62 for (auto server: servers) { 63 for (auto server: servers) {
63 for (auto platformHelper: hep.getHelperExecutables(server)) 64 for (auto platformHelper: hep.getHelperExecutables(QString::fromStdString(server.name)))
64 m_servers.push_back(platformHelper); 65 m_servers.push_back(platformHelper);
66 if (server.hasDesiredExtractors) {
67 setDesiredExtractors(server.name, server.extractors);
68 }
65 } 69 }
66 70
67 for (auto n: m_servers) { 71 for (auto n: m_servers) {
68 SVDEBUG << "NOTE: PiperVampPluginFactory: Found server: " 72 SVDEBUG << "NOTE: PiperVampPluginFactory: Found server: "
69 << n.executable << endl; 73 << n.executable << endl;
70 } 74 }
71 75
72 if (m_servers.empty()) { 76 if (m_servers.empty()) {
73 SVDEBUG << "NOTE: No Piper Vamp servers found in installation;" 77 SVDEBUG << "NOTE: No Piper Vamp servers found in installation;"
74 << " found none of the following:" << endl; 78 << " found none of the following:" << endl;
75 for (auto serverName: servers) 79 for (auto server: servers)
76 for (auto d: hep.getHelperCandidatePaths(serverName)) { 80 for (auto d: hep.getHelperCandidatePaths(QString::fromStdString(server.name))) {
77 SVDEBUG << "NOTE: " << d << endl; 81 SVDEBUG << "NOTE: " << d << endl;
78 } 82 }
79 } 83 }
80 } 84 }
81 85
82 PiperVampPluginFactory::PiperVampPluginFactory() : 86 PiperVampPluginFactory::PiperVampPluginFactory() :
83 PiperVampPluginFactory({"piper-vamp-simple-server"}) {} 87 PiperVampPluginFactory({{"piper-vamp-simple-server"}}) {}
84 88
85 PiperVampPluginFactory::~PiperVampPluginFactory() 89 PiperVampPluginFactory::~PiperVampPluginFactory()
86 { 90 {
87 delete m_logger; 91 delete m_logger;
92 }
93
94 void
95 PiperVampPluginFactory::setDesiredExtractors(ServerName name,
96 DesiredExtractors extractors)
97 {
98 const bool isValidServerName = std::find_if(
99 m_servers.begin(),
100 m_servers.end(),
101 [&name](const HelperExecPath::HelperExec &h) -> bool {
102 return QFileInfo(h.executable).fileName().toStdString() == name;
103 }) != m_servers.end();
104 if ( isValidServerName ) {
105 m_overrideDesiredExtractors[name] = extractors;
106 }
88 } 107 }
89 108
90 vector<QString> 109 vector<QString>
91 PiperVampPluginFactory::getPluginIdentifiers(QString &errorMessage) 110 PiperVampPluginFactory::getPluginIdentifiers(QString &errorMessage)
92 { 111 {
186 PiperVampPluginFactory::populateFrom(const HelperExecPath::HelperExec &server, 205 PiperVampPluginFactory::populateFrom(const HelperExecPath::HelperExec &server,
187 QString &errorMessage) 206 QString &errorMessage)
188 { 207 {
189 QString tag = server.tag; 208 QString tag = server.tag;
190 string executable = server.executable.toStdString(); 209 string executable = server.executable.toStdString();
191 210 const string serverName = QFileInfo(server.executable).fileName().toStdString();
192 PluginScan *scan = PluginScan::getInstance();
193 auto candidateLibraries =
194 scan->getCandidateLibrariesFor(PluginScan::VampPlugin);
195
196 SVDEBUG << "PiperVampPluginFactory: Populating from " << executable << endl;
197 SVDEBUG << "INFO: Have " << candidateLibraries.size()
198 << " candidate Vamp plugin libraries from scanner" << endl;
199 211
200 vector<string> from; 212 DesiredSubset from;
201 for (const auto &c: candidateLibraries) { 213
202 if (c.helperTag == tag) { 214 if (m_overrideDesiredExtractors.find(serverName) != m_overrideDesiredExtractors.end()) {
203 string soname = QFileInfo(c.libraryPath).baseName().toStdString(); 215 const auto desired = m_overrideDesiredExtractors.at(serverName);
204 SVDEBUG << "INFO: For tag \"" << tag << "\" giving library " << soname << endl; 216 if (desired.allAvailable) {
205 from.push_back(soname); 217 if (desired.from.empty()) {
206 } 218 from = {};
207 } 219 } else {
208 220 // ambiguous struct
209 if (from.empty()) { 221 return;
210 SVDEBUG << "PiperVampPluginFactory: No candidate libraries for tag \"" 222 }
211 << tag << "\"";
212 if (scan->scanSucceeded()) {
213 // we have to assume that they all failed to load (i.e. we
214 // exclude them all) rather than sending an empty list
215 // (which would mean no exclusions)
216 SVDEBUG << ", skipping" << endl;
217 return;
218 } else { 223 } else {
219 SVDEBUG << ", but it seems the scan failed, so bumbling on anyway" << endl; 224 if (desired.from.empty()) {
225 // ambigous
226 return;
227 } else {
228 from = desired.from;
229 }
230 }
231 } else {
232 PluginScan *scan = PluginScan::getInstance();
233 auto candidateLibraries =
234 scan->getCandidateLibrariesFor(PluginScan::VampPlugin);
235
236 SVDEBUG << "PiperVampPluginFactory: Populating from " << executable << endl;
237 SVDEBUG << "INFO: Have " << candidateLibraries.size()
238 << " candidate Vamp plugin libraries from scanner" << endl;
239 for (const auto &c: candidateLibraries) {
240 if (c.helperTag == tag) {
241 string soname = QFileInfo(c.libraryPath).baseName().toStdString();
242 SVDEBUG << "INFO: For tag \"" << tag << "\" giving library " << soname << endl;
243 from.push_back(soname);
244 }
245 }
246
247 if (from.empty()) {
248 SVDEBUG << "PiperVampPluginFactory: No candidate libraries for tag \""
249 << tag << "\"";
250 if (scan->scanSucceeded()) {
251 // we have to assume that they all failed to load (i.e. we
252 // exclude them all) rather than sending an empty list
253 // (which would mean no exclusions)
254 SVDEBUG << ", skipping" << endl;
255 return;
256 } else {
257 SVDEBUG << ", but it seems the scan failed, so bumbling on anyway" << endl;
258 }
220 } 259 }
221 } 260 }
222 261
223 piper_vamp::client::ProcessQtTransport transport(executable, "capnp", m_logger); 262 piper_vamp::client::ProcessQtTransport transport(executable, "capnp", m_logger);
224 if (!transport.isOK()) { 263 if (!transport.isOK()) {