From d8493f960a32d0d6d0db83cbfe8c38dfedd4a27b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 1 Jun 2016 20:50:24 -0700 Subject: [PATCH] Add command line option to enable/disable plugins --- interface/src/Application.cpp | 29 +++++++- interface/src/Application.h | 2 +- interface/src/main.cpp | 28 ++++---- .../plugins/src/plugins/PluginManager.cpp | 66 ++++++++++++++++++- libraries/plugins/src/plugins/PluginManager.h | 15 +++-- 5 files changed, 117 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e789b7c508..62f3a3a9c5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -4936,7 +4937,33 @@ void Application::postLambdaEvent(std::function f) { } } -void Application::initPlugins() { +void Application::initPlugins(const QStringList& arguments) { + QCommandLineOption display("display", "Default display", "display"); + QCommandLineOption disableDisplays("disable-displays", "Displays to disable", "display"); + QCommandLineOption disableInputs("disable-inputs", "Inputs to disable", "input"); + + QCommandLineParser parser; + parser.addOption(display); + parser.addOption(disableDisplays); + parser.addOption(disableInputs); + parser.parse(arguments); + + if (parser.isSet(display)) { + auto defaultDisplay = parser.value(display); + qInfo() << "Setting prefered display plugin:" << defaultDisplay; + } + + if (parser.isSet(disableDisplays)) { + auto disabledDisplays = parser.value(disableDisplays).split(',', QString::SkipEmptyParts); + qInfo() << "Disabling following display plugins:" << disabledDisplays; + PluginManager::getInstance()->disableDisplays(disabledDisplays); + } + + if (parser.isSet(disableInputs)) { + auto disabledInputs = parser.value(disableInputs).split(',', QString::SkipEmptyParts); + qInfo() << "Disabling following input plugins:" << disabledInputs; + PluginManager::getInstance()->disableInputs(disabledInputs); + } } void Application::shutdownPlugins() { diff --git a/interface/src/Application.h b/interface/src/Application.h index a17250a58e..ed7b582bfc 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -101,7 +101,7 @@ public: }; // FIXME? Empty methods, do we still need them? - static void initPlugins(); + static void initPlugins(const QStringList& arguments); static void shutdownPlugins(); Application(int& argc, char** argv, QElapsedTimer& startup_time); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 13f9470fda..6866d5637c 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -8,6 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include #include @@ -17,6 +19,12 @@ #include #include +#ifdef HAS_BUGSPLAT +#include +#include +#include +#endif + #include #include @@ -25,13 +33,7 @@ #include "InterfaceLogging.h" #include "UserActivityLogger.h" #include "MainWindow.h" -#include -#ifdef HAS_BUGSPLAT -#include -#include -#include -#endif int main(int argc, const char* argv[]) { #if HAS_BUGSPLAT @@ -46,6 +48,12 @@ int main(int argc, const char* argv[]) { bool instanceMightBeRunning = true; + QStringList arguments; + for (int i = 0; i < argc; ++i) { + arguments << argv[i]; + } + + #ifdef Q_OS_WIN // Try to create a shared memory block - if it can't be created, there is an instance of // interface already running. We only do this on Windows for now because of the potential @@ -64,12 +72,6 @@ int main(int argc, const char* argv[]) { // Try to connect - if we can't connect, interface has probably just gone down if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) { - - QStringList arguments; - for (int i = 0; i < argc; ++i) { - arguments << argv[i]; - } - QCommandLineParser parser; QCommandLineOption urlOption("url", "", "value"); parser.addOption(urlOption); @@ -135,7 +137,7 @@ int main(int argc, const char* argv[]) { // Oculus initialization MUST PRECEDE OpenGL context creation. // The nature of the Application constructor means this has to be either here, // or in the main window ctor, before GL startup. - Application::initPlugins(); + Application::initPlugins(arguments); int exitCode; { diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index eb6465aab2..9047b1c271 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -25,6 +25,49 @@ PluginManager* PluginManager::getInstance() { return &_manager; } +QString getPluginNameFromMetaData(QJsonObject object) { + static const char* METADATA_KEY = "MetaData"; + static const char* NAME_KEY = "name"; + + if (!object.contains(METADATA_KEY) || !object[METADATA_KEY].isObject()) { + return QString(); + } + + auto metaDataObject = object[METADATA_KEY].toObject(); + + if (!metaDataObject.contains(NAME_KEY) || !metaDataObject[NAME_KEY].isString()) { + return QString(); + } + + return metaDataObject[NAME_KEY].toString(); +} + +QString getPluginIIDFromMetaData(QJsonObject object) { + static const char* IID_KEY = "IID"; + + if (!object.contains(IID_KEY) || !object[IID_KEY].isString()) { + return QString(); + } + + return object[IID_KEY].toString(); +} + +QStringList disabledDisplays; +QStringList disabledInputs; + +bool isDisabled(QJsonObject metaData) { + auto name = getPluginNameFromMetaData(metaData); + auto iid = getPluginIIDFromMetaData(metaData); + + if (iid == DisplayProvider_iid) { + return disabledDisplays.contains(name); + } else if (iid == InputProvider_iid) { + return disabledInputs.contains(name); + } + + return false; +} + using Loader = QSharedPointer; using LoaderList = QList; @@ -43,11 +86,21 @@ const LoaderList& getLoadedPlugins() { qDebug() << "Loading runtime plugins from " << pluginPath; auto candidates = pluginDir.entryList(); for (auto plugin : candidates) { - qDebug() << "Attempting plugins " << plugin; + qDebug() << "Attempting plugin" << qPrintable(plugin); QSharedPointer loader(new QPluginLoader(pluginPath + plugin)); + + if (isDisabled(loader->metaData())) { + qWarning() << "Plugin" << qPrintable(plugin) << "is disabled"; + // Skip this one, it's disabled + continue; + } + if (loader->load()) { - qDebug() << "Plugins " << plugin << " success"; + qDebug() << "Plugin" << qPrintable(plugin) << "loaded successfully"; loadedPlugins.push_back(loader); + } else { + qDebug() << "Plugin" << qPrintable(plugin) << "failed to load:"; + qDebug() << " " << qPrintable(loader->errorString()); } } } @@ -124,6 +177,15 @@ const InputPluginList& PluginManager::getInputPlugins() { return inputPlugins; } + +void PluginManager::disableDisplays(const QStringList& displays) { + disabledDisplays << displays; +} + +void PluginManager::disableInputs(const QStringList& inputs) { + disabledInputs << inputs; +} + void PluginManager::saveSettings() { saveInputPluginSettings(getInputPlugins()); } diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index cf0b8efe64..351087dce8 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -13,11 +13,14 @@ class PluginManager : public QObject { public: - static PluginManager* getInstance(); - PluginManager(); + static PluginManager* getInstance(); + PluginManager(); - const DisplayPluginList& getDisplayPlugins(); - void disableDisplayPlugin(const QString& name); - const InputPluginList& getInputPlugins(); - void saveSettings(); + const DisplayPluginList& getDisplayPlugins(); + const InputPluginList& getInputPlugins(); + + void disableDisplayPlugin(const QString& name); + void disableDisplays(const QStringList& displays); + void disableInputs(const QStringList& inputs); + void saveSettings(); };