changeset 1472:5d7057af0c68 plugin-path-config

Add class to get/set/remember the plugin path for each plugin type
author Chris Cannam
date Fri, 25 May 2018 16:04:42 +0100 (2018-05-25)
parents 85e9b7b31a8d
children f52bf66b9096
files files.pri plugin/DSSIPluginFactory.h plugin/LADSPAPluginFactory.h plugin/PluginPathSetter.cpp plugin/PluginPathSetter.h
diffstat 5 files changed, 232 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/files.pri	Thu May 24 16:30:55 2018 +0100
+++ b/files.pri	Fri May 25 16:04:42 2018 +0100
@@ -108,6 +108,7 @@
            plugin/NativeVampPluginFactory.h \
            plugin/PiperVampPluginFactory.h \
            plugin/PluginIdentifier.h \
+           plugin/PluginPathSetter.h \
            plugin/PluginXml.h \
            plugin/RealTimePluginFactory.h \
            plugin/RealTimePluginInstance.h \
@@ -220,6 +221,7 @@
            plugin/NativeVampPluginFactory.cpp \
            plugin/PiperVampPluginFactory.cpp \
            plugin/PluginIdentifier.cpp \
+           plugin/PluginPathSetter.cpp \
            plugin/PluginXml.cpp \
            plugin/RealTimePluginFactory.cpp \
            plugin/RealTimePluginInstance.cpp \
--- a/plugin/DSSIPluginFactory.h	Thu May 24 16:30:55 2018 +0100
+++ b/plugin/DSSIPluginFactory.h	Fri May 25 16:04:42 2018 +0100
@@ -44,6 +44,8 @@
                                                       int blockSize,
                                                       int channels);
 
+    static std::vector<QString> getPluginPath();
+
 protected:
     DSSIPluginFactory();
     friend class RealTimePluginFactory;
@@ -52,8 +54,6 @@
         return PluginScan::DSSIPlugin;
     }
 
-    virtual std::vector<QString> getPluginPath();
-
     virtual std::vector<QString> getLRDFPath(QString &baseUri);
 
     virtual void discoverPluginsFrom(QString soName);
--- a/plugin/LADSPAPluginFactory.h	Thu May 24 16:30:55 2018 +0100
+++ b/plugin/LADSPAPluginFactory.h	Fri May 25 16:04:42 2018 +0100
@@ -63,6 +63,8 @@
     float getPortQuantization(const LADSPA_Descriptor *, int port);
     int getPortDisplayHint(const LADSPA_Descriptor *, int port);
 
+    static std::vector<QString> getPluginPath();
+
 protected:
     LADSPAPluginFactory();
     friend class RealTimePluginFactory;
@@ -71,8 +73,6 @@
         return PluginScan::LADSPAPlugin;
     }
 
-    virtual std::vector<QString> getPluginPath();
-
     virtual std::vector<QString> getLRDFPath(QString &baseUri);
 
     virtual void discoverPluginsFrom(QString soName);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/PluginPathSetter.cpp	Fri May 25 16:04:42 2018 +0100
@@ -0,0 +1,168 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "PluginPathSetter.h"
+
+#include <vamp-hostsdk/PluginHostAdapter.h>
+
+#include "RealTimePluginFactory.h"
+#include "LADSPAPluginFactory.h"
+#include "DSSIPluginFactory.h"
+
+#include <QSettings>
+#include <QMutexLocker>
+
+QMutex
+PluginPathSetter::m_mutex;
+
+PluginPathSetter::Paths
+PluginPathSetter::m_defaultPaths;
+
+PluginPathSetter::Paths
+PluginPathSetter::getDefaultPaths()
+{
+    QMutexLocker locker(&m_mutex);
+
+    if (!m_defaultPaths.empty()) {
+        return m_defaultPaths;
+    }
+        
+    Paths paths;
+
+    auto vampPath = Vamp::PluginHostAdapter::getPluginPath();
+
+    QStringList qVampPath;
+    for (auto s: vampPath) {
+        qVampPath.push_back(QString::fromStdString(s));
+    }
+    paths["Vamp"] = { qVampPath, "VAMP_PATH", true };
+
+    auto dssiPath = DSSIPluginFactory::getPluginPath();
+
+    QStringList qDssiPath;
+    for (auto s: dssiPath) {
+        qDssiPath.push_back(s);
+    }
+    paths["DSSI"] = { qDssiPath, "DSSI_PATH", true };
+            
+    auto ladspaPath = LADSPAPluginFactory::getPluginPath();
+
+    QStringList qLadspaPath;
+    for (auto s: ladspaPath) {
+        qLadspaPath.push_back(s);
+    }
+    paths["LADSPA"] = { qLadspaPath, "LADSPA_PATH", true };
+
+    m_defaultPaths = paths;
+    return m_defaultPaths;
+}
+
+PluginPathSetter::Paths
+PluginPathSetter::getPaths()
+{
+    Paths paths = getDefaultPaths();
+       
+    QSettings settings;
+    settings.beginGroup("Plugins");
+
+    for (auto p: paths) {
+
+        QString tag = p.first;
+
+        QStringList directories =
+            settings.value(QString("directories-%1").arg(tag),
+                           p.second.directories)
+            .toStringList();
+        QString envVariable =
+            settings.value(QString("env-variable-%1").arg(tag),
+                           p.second.envVariable)
+            .toString();
+        bool useEnvVariable =
+            settings.value(QString("use-env-variable-%1").arg(tag),
+                           p.second.useEnvVariable)
+            .toBool();
+        std::string envVarStr = envVariable.toStdString();
+        
+        QString currentValue = qEnvironmentVariable(envVarStr.c_str());
+        if (currentValue != QString() && useEnvVariable) {
+            directories = currentValue.split(
+#ifdef Q_OS_WIN
+               ";"
+#else
+               ":"
+#endif
+                );
+        }
+        
+        paths[tag] = { directories, envVariable, useEnvVariable };
+    }
+
+    settings.endGroup();
+
+    return paths;
+}
+
+void
+PluginPathSetter::savePathSettings(Paths paths)
+{
+    QSettings settings;
+    settings.beginGroup("Plugins");
+
+    for (auto p: paths) {
+        QString tag = p.first;
+        settings.setValue(QString("directories-%1").arg(tag),
+                          p.second.directories);
+        settings.setValue(QString("env-variable-%1").arg(tag),
+                          p.second.envVariable);
+        settings.setValue(QString("use-env-variable-%1").arg(tag),
+                          p.second.useEnvVariable);
+    }
+
+    settings.endGroup();
+}
+
+void
+PluginPathSetter::setEnvironmentVariables()
+{
+    // Set the relevant environment variables from user configuration,
+    // so that later lookups through the standard APIs will follow the
+    // same paths as we have in the user config
+
+    // First ensure the default paths have been recorded for later, so
+    // we don't erroneously re-read them from the environment
+    // variables we've just set
+    (void)getDefaultPaths();
+    
+    Paths paths = getPaths();
+
+    for (auto p: paths) {
+        QString envVariable = p.second.envVariable;
+        std::string envVarStr = envVariable.toStdString();
+        QString currentValue = qEnvironmentVariable(envVarStr.c_str());
+        if (currentValue != QString() && p.second.useEnvVariable) {
+            // don't override
+            continue;
+        }
+        QString separator =
+#ifdef Q_OS_WIN
+            ";"
+#else
+            ":"
+#endif
+            ;
+        QString proposedValue = p.second.directories.join(separator);
+        qputenv(envVarStr.c_str(), proposedValue.toUtf8());
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/PluginPathSetter.h	Fri May 25 16:04:42 2018 +0100
@@ -0,0 +1,58 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef SV_PLUGIN_PATH_SETTER_H
+#define SV_PLUGIN_PATH_SETTER_H
+
+#include <QString>
+#include <QStringList>
+#include <QMutex>
+
+#include <map>
+
+class PluginPathSetter
+{
+public:
+    /// Text used to identify a plugin type, e.g. "LADSPA", "Vamp"
+    typedef QString PluginTypeLabel;
+
+    struct PathConfig {
+        QStringList directories;
+        QString envVariable; // e.g. "LADSPA_PATH" etc
+        bool useEnvVariable; // true if env variable overrides directories list
+    };
+
+    typedef std::map<PluginTypeLabel, PathConfig> Paths;
+
+    /// Return paths arising from environment variables only, without
+    /// any user-defined preferences
+    static Paths getDefaultPaths();
+
+    /// Return paths arising from user settings + environment
+    /// variables as appropriate
+    static Paths getPaths();
+
+    /// Save the given paths to the settings
+    static void savePathSettings(Paths paths);
+
+    /// Update *_PATH environment variables from the settings, on
+    /// application startup
+    static void setEnvironmentVariables();
+
+private:
+    static Paths m_defaultPaths;
+    static QMutex m_mutex;
+};
+
+#endif