Add command line option to enable/disable plugins

This commit is contained in:
Atlante45 2016-06-01 20:50:24 -07:00
parent 3dadb515f3
commit d8493f960a
5 changed files with 117 additions and 23 deletions

View file

@ -19,6 +19,7 @@
#include <glm/gtc/type_ptr.hpp>
#include <QtCore/QAbstractNativeEventFilter>
#include <QtCore/QCommandLineParser>
#include <QtCore/QMimeData>
#include <QtCore/QThreadPool>
@ -4936,7 +4937,33 @@ void Application::postLambdaEvent(std::function<void()> 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() {

View file

@ -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);

View file

@ -8,6 +8,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <thread>
#include <QCommandLineParser>
#include <QDebug>
#include <QDir>
@ -17,6 +19,12 @@
#include <QSharedMemory>
#include <QTranslator>
#ifdef HAS_BUGSPLAT
#include <BuildInfo.h>
#include <BugSplat.h>
#include <CrashReporter.h>
#endif
#include <gl/OpenGLVersionChecker.h>
#include <SharedUtil.h>
@ -25,13 +33,7 @@
#include "InterfaceLogging.h"
#include "UserActivityLogger.h"
#include "MainWindow.h"
#include <thread>
#ifdef HAS_BUGSPLAT
#include <BuildInfo.h>
#include <BugSplat.h>
#include <CrashReporter.h>
#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;
{

View file

@ -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<QPluginLoader>;
using LoaderList = QList<Loader>;
@ -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<QPluginLoader> 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());
}

View file

@ -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();
};