Introduce PluginFactory class
This singleton class handles management of plugin search paths and plugin
discovery. Search paths are (if they exist):
* <lmms-exe-dir>/../lib/lmms: This is the common location on Unixoids
(Not included in Windows builds)
* <lmms-exe-dir>/plugins: For portable and Windows installations
* The path given by the compile define LMMS_PLUGIN_DIR
* Environment variable LMMS_PLUGIN_DIR if given
This commit also tweaks the build script to output built plugins to
"${CMAKE_BINARY_DIR}/plugins". This way lmms can find plugins during
development without the need to use `make install`.
Plugin::getDescriptorsOfAvailPlugins and ConfigManager::pluginDir were
removed.
This commit is contained in:
@@ -120,11 +120,6 @@ public:
|
||||
return m_dataDir + LOCALE_PATH;
|
||||
}
|
||||
|
||||
const QString & pluginDir() const
|
||||
{
|
||||
return m_pluginDir;
|
||||
}
|
||||
|
||||
const QString & vstDir() const
|
||||
{
|
||||
return m_vstDir;
|
||||
@@ -202,7 +197,6 @@ private:
|
||||
QString m_workingDir;
|
||||
QString m_dataDir;
|
||||
QString m_artworkDir;
|
||||
QString m_pluginDir;
|
||||
QString m_vstDir;
|
||||
QString m_flDir;
|
||||
QString m_ladDir;
|
||||
|
||||
@@ -55,7 +55,6 @@ protected slots:
|
||||
private:
|
||||
Ui::EffectSelectDialog * ui;
|
||||
|
||||
Plugin::DescriptorList m_pluginDescriptors;
|
||||
EffectKeyList m_effectKeys;
|
||||
EffectKey m_currentSelection;
|
||||
|
||||
|
||||
@@ -137,9 +137,8 @@ public:
|
||||
SubPluginFeatures *subPluginFeatures;
|
||||
|
||||
} ;
|
||||
|
||||
// typedef a list so we can easily work with list of plugin descriptors
|
||||
typedef QList<Descriptor> DescriptorList;
|
||||
typedef QList<Descriptor*> DescriptorList;
|
||||
|
||||
// contructor of a plugin
|
||||
Plugin( const Descriptor* descriptor, Model* parent );
|
||||
@@ -177,9 +176,6 @@ public:
|
||||
// if specified plugin couldn't be loaded, it creates a dummy-plugin
|
||||
static Plugin * instantiate( const QString& pluginName, Model *parent, void * data );
|
||||
|
||||
// fills given list with descriptors of all available plugins
|
||||
static void getDescriptorsOfAvailPlugins( DescriptorList& pluginDescriptors );
|
||||
|
||||
// create a view for the model
|
||||
PluginView* createView( QWidget* parent );
|
||||
|
||||
|
||||
@@ -55,9 +55,6 @@ class PluginDescList : public QWidget
|
||||
Q_OBJECT
|
||||
public:
|
||||
PluginDescList(QWidget* parent);
|
||||
|
||||
private:
|
||||
Plugin::DescriptorList m_pluginDescriptors;
|
||||
};
|
||||
|
||||
|
||||
|
||||
84
include/PluginFactory.h
Normal file
84
include/PluginFactory.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* PluginFactory.h
|
||||
*
|
||||
* Copyright (c) 2015 Lukas W <lukaswhl/at/gmail.com>
|
||||
*
|
||||
* This file is part of LMMS - http://lmms.io
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLUGINFACTORY_H
|
||||
#define PLUGINFACTORY_H
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QList>
|
||||
|
||||
#include "Plugin.h"
|
||||
|
||||
class QLibrary;
|
||||
|
||||
class PluginFactory
|
||||
{
|
||||
public:
|
||||
struct PluginInfo
|
||||
{
|
||||
QFileInfo file;
|
||||
QLibrary* library;
|
||||
Plugin::Descriptor* descriptor;
|
||||
|
||||
bool isNull() const {return library == 0;}
|
||||
};
|
||||
typedef QList<PluginInfo> PluginInfoList;
|
||||
|
||||
PluginFactory();
|
||||
~PluginFactory();
|
||||
|
||||
/// Returns the singleton instance of PluginFactory. You won't need to call
|
||||
/// this directly, use pluginFactory instead.
|
||||
static PluginFactory* instance();
|
||||
|
||||
/// Returns a list of all found plugins' descriptors.
|
||||
const Plugin::DescriptorList descriptors() const;
|
||||
|
||||
/// Returns a list of all found plugins' PluginFactory::PluginInfo objects.
|
||||
const PluginInfoList& pluginInfos() const;
|
||||
|
||||
/// Returns the PluginInfo object of the plugin with the given name.
|
||||
/// If the plugin is not found, an empty PluginInfo is returned (use
|
||||
/// PluginInfo::isNull() to check this).
|
||||
const PluginInfo pluginInfo(const char* name) const;
|
||||
|
||||
/// When loading a library fails during discovery, the error string is saved.
|
||||
/// It can be retrieved by calling this function.
|
||||
QString errorString(QString pluginName) const;
|
||||
|
||||
public slots:
|
||||
void discoverPlugins();
|
||||
|
||||
private:
|
||||
Plugin::DescriptorList m_descriptorList;
|
||||
PluginInfoList m_pluginInfos;
|
||||
|
||||
QHash<QString, QString> m_errors;
|
||||
|
||||
static PluginFactory* s_instance;
|
||||
};
|
||||
|
||||
#define pluginFactory PluginFactory::instance()
|
||||
|
||||
#endif // PLUGINFACTORY_H
|
||||
@@ -1,3 +1,6 @@
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
ADD_SUBDIRECTORY(Amplifier)
|
||||
ADD_SUBDIRECTORY(audio_file_processor)
|
||||
ADD_SUBDIRECTORY(BassBooster)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ladspa")
|
||||
|
||||
IF(WANT_CAPS)
|
||||
ADD_SUBDIRECTORY(caps)
|
||||
ENDIF(WANT_CAPS)
|
||||
|
||||
@@ -2,4 +2,5 @@ INCLUDE(BuildPlugin)
|
||||
|
||||
INCLUDE_DIRECTORIES(unrtf)
|
||||
|
||||
ADD_DEFINITIONS(--std=c++0x)
|
||||
BUILD_PLUGIN(flpimport FlpImport.cpp unrtf.cpp FlpImport.h)
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "Oscillator.h"
|
||||
#include "Pattern.h"
|
||||
#include "Piano.h"
|
||||
#include "PluginFactory.h"
|
||||
#include "ProjectJournal.h"
|
||||
#include "ProjectNotes.h"
|
||||
#include "Song.h"
|
||||
@@ -1637,22 +1638,19 @@ p->putValue( jt->pos, value, false );
|
||||
|
||||
// process all effects
|
||||
EffectKeyList effKeys;
|
||||
Plugin::DescriptorList pluginDescs;
|
||||
Plugin::getDescriptorsOfAvailPlugins( pluginDescs );
|
||||
for( Plugin::DescriptorList::ConstIterator it = pluginDescs.begin();
|
||||
it != pluginDescs.end(); ++it )
|
||||
for (const Plugin::Descriptor* desc : pluginFactory->descriptors())
|
||||
{
|
||||
if( it->type != Plugin::Effect )
|
||||
if( desc->type != Plugin::Effect )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if( it->subPluginFeatures )
|
||||
if( desc->subPluginFeatures )
|
||||
{
|
||||
it->subPluginFeatures->listSubPluginKeys( &( *it ), effKeys );
|
||||
desc->subPluginFeatures->listSubPluginKeys( desc, effKeys );
|
||||
}
|
||||
else
|
||||
{
|
||||
effKeys << EffectKey( &( *it ), it->name );
|
||||
effKeys << EffectKey( desc, desc->name );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ set(LMMS_SRCS
|
||||
core/Piano.cpp
|
||||
core/PlayHandle.cpp
|
||||
core/Plugin.cpp
|
||||
core/PluginFactory.cpp
|
||||
core/PresetPreviewPlayHandle.cpp
|
||||
core/ProjectJournal.cpp
|
||||
core/ProjectRenderer.cpp
|
||||
|
||||
@@ -59,12 +59,6 @@ ConfigManager::ConfigManager() :
|
||||
#endif
|
||||
),
|
||||
m_artworkDir( defaultArtworkDir() ),
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
m_pluginDir( qApp->applicationDirPath()
|
||||
+ QDir::separator() + "plugins" + QDir::separator() ),
|
||||
#else
|
||||
m_pluginDir( qApp->applicationDirPath() + '/' + PLUGIN_DIR ),
|
||||
#endif
|
||||
m_vstDir( m_workingDir + "vst" + QDir::separator() ),
|
||||
m_flDir( QDir::home().absolutePath() ),
|
||||
m_recoveryFile( QDir(m_workingDir).absoluteFilePath("recover.mmp") )
|
||||
|
||||
@@ -57,17 +57,17 @@ void EffectChain::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
_this.setAttribute( "enabled", m_enabledModel.value() );
|
||||
_this.setAttribute( "numofeffects", m_effects.count() );
|
||||
|
||||
for( EffectList::Iterator it = m_effects.begin(); it != m_effects.end(); it++ )
|
||||
for( Effect* effect : m_effects)
|
||||
{
|
||||
if( dynamic_cast<DummyEffect *>( *it ) )
|
||||
if( DummyEffect* dummy = dynamic_cast<DummyEffect*>(effect) )
|
||||
{
|
||||
_this.appendChild( dynamic_cast<DummyEffect *>( *it )->originalPluginData() );
|
||||
_this.appendChild( dummy->originalPluginData() );
|
||||
}
|
||||
else
|
||||
{
|
||||
QDomElement ef = ( *it )->saveState( _doc, _this );
|
||||
ef.setAttribute( "name", ( *it )->descriptor()->name );
|
||||
ef.appendChild( ( *it )->key().saveXML( _doc ) );
|
||||
QDomElement ef = effect->saveState( _doc, _this );
|
||||
ef.setAttribute( "name", QString::fromUtf8( effect->descriptor()->name ) );
|
||||
ef.appendChild( effect->key().saveXML( _doc ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ void EffectChain::loadSettings( const QDomElement & _this )
|
||||
const QString name = effectData.attribute( "name" );
|
||||
EffectKey key( effectData.elementsByTagName( "key" ).item( 0 ).toElement() );
|
||||
|
||||
Effect* e = Effect::instantiate( name, this, &key );
|
||||
Effect* e = Effect::instantiate( name.toUtf8(), this, &key );
|
||||
|
||||
if( e != NULL && e->isOkay() && e->nodeName() == node.nodeName() )
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "PresetPreviewPlayHandle.h"
|
||||
#include "ProjectJournal.h"
|
||||
#include "Plugin.h"
|
||||
#include "PluginFactory.h"
|
||||
#include "Song.h"
|
||||
#include "BandLimitedWave.h"
|
||||
|
||||
@@ -122,20 +123,13 @@ void Engine::updateFramesPerTick()
|
||||
|
||||
void Engine::initPluginFileHandling()
|
||||
{
|
||||
Plugin::DescriptorList pluginDescriptors;
|
||||
Plugin::getDescriptorsOfAvailPlugins( pluginDescriptors );
|
||||
for( Plugin::DescriptorList::ConstIterator it = pluginDescriptors.begin();
|
||||
it != pluginDescriptors.end(); ++it )
|
||||
for (const Plugin::Descriptor* desc : pluginFactory->descriptors())
|
||||
{
|
||||
if( it->type == Plugin::Instrument )
|
||||
if( desc->type == Plugin::Instrument )
|
||||
{
|
||||
const QStringList & ext =
|
||||
QString( it->supportedFileTypes ).
|
||||
split( QChar( ',' ) );
|
||||
for( QStringList::const_iterator itExt = ext.begin();
|
||||
itExt != ext.end(); ++itExt )
|
||||
for(const QString& ext : QString(desc->supportedFileTypes).split(','))
|
||||
{
|
||||
s_pluginFileHandling[*itExt] = it->name;
|
||||
s_pluginFileHandling[ext] = desc->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* ImportFilter.cpp - base-class for all import-filters (MIDI, FLP etc)
|
||||
*
|
||||
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
*
|
||||
* This file is part of LMMS - http://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -28,10 +28,10 @@
|
||||
#include "ImportFilter.h"
|
||||
#include "Engine.h"
|
||||
#include "TrackContainer.h"
|
||||
#include "PluginFactory.h"
|
||||
#include "ProjectJournal.h"
|
||||
|
||||
|
||||
|
||||
ImportFilter::ImportFilter( const QString & _file_name,
|
||||
const Descriptor * _descriptor ) :
|
||||
Plugin( _descriptor, NULL ),
|
||||
@@ -52,9 +52,6 @@ ImportFilter::~ImportFilter()
|
||||
void ImportFilter::import( const QString & _file_to_import,
|
||||
TrackContainer* tc )
|
||||
{
|
||||
DescriptorList d;
|
||||
Plugin::getDescriptorsOfAvailPlugins( d );
|
||||
|
||||
bool successful = false;
|
||||
|
||||
char * s = qstrdup( _file_to_import.toUtf8().constData() );
|
||||
@@ -63,12 +60,11 @@ void ImportFilter::import( const QString & _file_to_import,
|
||||
const bool j = Engine::projectJournal()->isJournalling();
|
||||
Engine::projectJournal()->setJournalling( false );
|
||||
|
||||
for( Plugin::DescriptorList::ConstIterator it = d.begin();
|
||||
it != d.end(); ++it )
|
||||
for (const Plugin::Descriptor* desc : pluginFactory->descriptors())
|
||||
{
|
||||
if( it->type == Plugin::ImportFilter )
|
||||
if( desc->type == Plugin::ImportFilter )
|
||||
{
|
||||
Plugin * p = Plugin::instantiate( it->name, NULL, s );
|
||||
Plugin * p = Plugin::instantiate( desc->name, NULL, s );
|
||||
if( dynamic_cast<ImportFilter *>( p ) != NULL &&
|
||||
dynamic_cast<ImportFilter *>( p )->tryImport( tc ) == true )
|
||||
{
|
||||
|
||||
@@ -43,7 +43,7 @@ LadspaManager::LadspaManager()
|
||||
split( LADSPA_PATH_SEPERATOR );
|
||||
ladspaDirectories += ConfigManager::inst()->ladspaDir().split( ',' );
|
||||
|
||||
ladspaDirectories.push_back( ConfigManager::inst()->pluginDir() + "ladspa" );
|
||||
ladspaDirectories.push_back( "plugins:ladspa" );
|
||||
#ifndef LMMS_BUILD_WIN32
|
||||
ladspaDirectories.push_back( qApp->applicationDirPath() + '/' + LIB_DIR + "ladspa" );
|
||||
ladspaDirectories.push_back( "/usr/lib/ladspa" );
|
||||
|
||||
@@ -91,25 +91,25 @@ AutomatableModel * Plugin::childModel( const QString & )
|
||||
|
||||
|
||||
|
||||
|
||||
Plugin * Plugin::instantiate( const QString & pluginName, Model * parent,
|
||||
#include "PluginFactory.h"
|
||||
Plugin * Plugin::instantiate( const QString& pluginName, Model * parent,
|
||||
void * data )
|
||||
{
|
||||
QLibrary pluginLibrary( ConfigManager::inst()->pluginDir() + pluginName );
|
||||
if( pluginLibrary.load() == false )
|
||||
const PluginFactory::PluginInfo& pi = pluginFactory->pluginInfo(pluginName.toUtf8());
|
||||
if( pi.isNull() )
|
||||
{
|
||||
if( Engine::hasGUI() )
|
||||
{
|
||||
QMessageBox::information( NULL,
|
||||
tr( "Plugin not found" ),
|
||||
tr( "The plugin \"%1\" wasn't found or could not be loaded!\nReason: \"%2\"" ).
|
||||
arg( pluginName ).arg( pluginLibrary.errorString() ),
|
||||
arg( pluginName ).arg( pluginFactory->errorString(pluginName) ),
|
||||
QMessageBox::Ok | QMessageBox::Default );
|
||||
}
|
||||
return new DummyPlugin();
|
||||
}
|
||||
|
||||
InstantiationHook instantiationHook = ( InstantiationHook ) pluginLibrary.resolve( "lmms_plugin_main" );
|
||||
InstantiationHook instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" );
|
||||
if( instantiationHook == NULL )
|
||||
{
|
||||
if( Engine::hasGUI() )
|
||||
@@ -133,50 +133,6 @@ void Plugin::collectErrorForUI( QString err_msg )
|
||||
|
||||
|
||||
|
||||
void Plugin::getDescriptorsOfAvailPlugins( DescriptorList& pluginDescriptors )
|
||||
{
|
||||
QDir directory( ConfigManager::inst()->pluginDir() );
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
QFileInfoList list = directory.entryInfoList( QStringList( "*.dll" ) );
|
||||
#else
|
||||
QFileInfoList list = directory.entryInfoList( QStringList( "lib*.so" ) );
|
||||
#endif
|
||||
foreach( const QFileInfo& f, list )
|
||||
{
|
||||
QLibrary( f.absoluteFilePath() ).load();
|
||||
}
|
||||
|
||||
foreach( const QFileInfo& f, list )
|
||||
{
|
||||
QLibrary pluginLibrary( f.absoluteFilePath() );
|
||||
if( pluginLibrary.load() == false ||
|
||||
pluginLibrary.resolve( "lmms_plugin_main" ) == NULL )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QString descriptorName = f.baseName() + "_plugin_descriptor";
|
||||
if( descriptorName.left( 3 ) == "lib" )
|
||||
{
|
||||
descriptorName = descriptorName.mid( 3 );
|
||||
}
|
||||
|
||||
Descriptor* pluginDescriptor = (Descriptor *) pluginLibrary.resolve( descriptorName.toUtf8().constData() );
|
||||
if( pluginDescriptor == NULL )
|
||||
{
|
||||
qWarning() << tr( "LMMS plugin %1 does not have a plugin descriptor named %2!" ).
|
||||
arg( f.absoluteFilePath() ).arg( descriptorName );
|
||||
continue;
|
||||
}
|
||||
|
||||
pluginDescriptors += *pluginDescriptor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PluginView * Plugin::createView( QWidget * parent )
|
||||
{
|
||||
PluginView * pv = instantiateView( parent );
|
||||
|
||||
173
src/core/PluginFactory.cpp
Normal file
173
src/core/PluginFactory.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* PluginFactory.cpp
|
||||
*
|
||||
* Copyright (c) 2015 Lukas W <lukaswhl/at/gmail.com>
|
||||
*
|
||||
* This file is part of LMMS - http://lmms.io
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PluginFactory.h"
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QLibrary>
|
||||
|
||||
#include "Plugin.h"
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
QStringList nameFilters("*.dll");
|
||||
#else
|
||||
QStringList nameFilters("lib*.so");
|
||||
#endif
|
||||
|
||||
PluginFactory* PluginFactory::s_instance = nullptr;
|
||||
|
||||
PluginFactory::PluginFactory()
|
||||
{
|
||||
// Adds a search path relative to the main executable to if the path exists.
|
||||
auto addRelativeIfExists = [this] (const QString& path) {
|
||||
QDir dir(qApp->applicationDirPath());
|
||||
if (!path.isEmpty() && dir.cd(path)) {
|
||||
QDir::addSearchPath("plugins", dir.absolutePath());
|
||||
}
|
||||
};
|
||||
|
||||
// We're either running LMMS installed on an Unixoid or we're running a
|
||||
// portable version like we do on Windows.
|
||||
// We want to find our plugins in both cases:
|
||||
// (a) Installed (Unix):
|
||||
// e.g. binary at /usr/bin/lmms - plugin dir at /usr/lib/lmms/
|
||||
// (b) Portable:
|
||||
// e.g. binary at "C:/Program Files/LMMS/lmms.exe"
|
||||
// plugins at "C:/Program Files/LMMS/plugins/"
|
||||
|
||||
#ifndef LMMS_BUILD_WIN32
|
||||
addRelativeIfExists("../lib/lmms"); // Installed
|
||||
#endif
|
||||
addRelativeIfExists("plugins"); // Portable
|
||||
#ifdef PLUGIN_DIR // We may also have received a relative directory via a define
|
||||
addRelativeIfExists(PLUGIN_DIR);
|
||||
#endif
|
||||
// Or via an environment variable:
|
||||
QString env_path;
|
||||
if (!(env_path = qgetenv("LMMS_PLUGIN_DIR")).isEmpty())
|
||||
QDir::addSearchPath("plugins", env_path);
|
||||
|
||||
discoverPlugins();
|
||||
}
|
||||
|
||||
PluginFactory::~PluginFactory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PluginFactory* PluginFactory::instance()
|
||||
{
|
||||
if (s_instance == nullptr)
|
||||
s_instance = new PluginFactory();
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
const Plugin::DescriptorList PluginFactory::descriptors() const
|
||||
{
|
||||
return m_descriptorList;
|
||||
}
|
||||
|
||||
const QList<PluginFactory::PluginInfo>& PluginFactory::pluginInfos() const
|
||||
{
|
||||
return m_pluginInfos;
|
||||
}
|
||||
|
||||
const PluginFactory::PluginInfo PluginFactory::pluginInfo(const char* name) const
|
||||
{
|
||||
for (const PluginInfo& info : m_pluginInfos)
|
||||
{
|
||||
if (qstrcmp(info.descriptor->name, name) == 0)
|
||||
return info;
|
||||
}
|
||||
return PluginInfo();
|
||||
}
|
||||
|
||||
QString PluginFactory::errorString(QString pluginName) const
|
||||
{
|
||||
static QString notfound = qApp->translate("PluginFactory", "Plugin not found.");
|
||||
return m_errors.value(pluginName, notfound);
|
||||
}
|
||||
|
||||
void PluginFactory::discoverPlugins()
|
||||
{
|
||||
Plugin::DescriptorList descriptors;
|
||||
PluginInfoList pluginInfos;
|
||||
|
||||
const QFileInfoList& files = QDir("plugins:").entryInfoList(nameFilters);
|
||||
|
||||
// Cheap dependency handling: zynaddsubfx needs ZynAddSubFxCore. By loading
|
||||
// all libraries twice we ensure that libZynAddSubFxCore is found.
|
||||
for (const QFileInfo& file : files)
|
||||
{
|
||||
QLibrary(file.absoluteFilePath()).load();
|
||||
}
|
||||
|
||||
for (const QFileInfo& file : files)
|
||||
{
|
||||
QLibrary* library = new QLibrary(file.absoluteFilePath());
|
||||
|
||||
if (! library->load()) {
|
||||
m_errors[file.baseName()] = library->errorString();
|
||||
continue;
|
||||
}
|
||||
if (library->resolve("lmms_plugin_main") == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString descriptorName = file.baseName() + "_plugin_descriptor";
|
||||
if( descriptorName.left(3) == "lib" )
|
||||
{
|
||||
descriptorName = descriptorName.mid(3);
|
||||
}
|
||||
|
||||
Plugin::Descriptor* pluginDescriptor = (Plugin::Descriptor*) library->resolve(descriptorName.toUtf8().constData());
|
||||
if(pluginDescriptor == nullptr)
|
||||
{
|
||||
qWarning() << qApp->translate("PluginFactory", "LMMS plugin %1 does not have a plugin descriptor named %2!").
|
||||
arg(file.absoluteFilePath()).arg(descriptorName);
|
||||
continue;
|
||||
}
|
||||
|
||||
PluginInfo info;
|
||||
info.file = file;
|
||||
info.library = library;
|
||||
info.descriptor = pluginDescriptor;
|
||||
pluginInfos << info;
|
||||
|
||||
descriptors << pluginDescriptor;
|
||||
}
|
||||
|
||||
|
||||
for (PluginInfo& info : m_pluginInfos)
|
||||
{
|
||||
delete info.library;
|
||||
}
|
||||
m_pluginInfos = pluginInfos;
|
||||
m_descriptorList = descriptors;
|
||||
}
|
||||
|
||||
@@ -130,8 +130,7 @@ bool RemotePlugin::init( const QString &pluginExecutable,
|
||||
reset( new shmFifo(), new shmFifo() );
|
||||
m_failed = false;
|
||||
}
|
||||
QString exec = ConfigManager::inst()->pluginDir() +
|
||||
pluginExecutable;
|
||||
QString exec = QFileInfo(QDir("plugins:"), pluginExecutable).absoluteFilePath();
|
||||
|
||||
QStringList args;
|
||||
// swap in and out for bidirectional communication
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "gui_templates.h"
|
||||
#include "embed.h"
|
||||
#include "PluginFactory.h"
|
||||
|
||||
|
||||
EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
|
||||
@@ -42,31 +43,29 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
|
||||
setWindowIcon( embed::getIconPixmap( "setup_audio" ) );
|
||||
|
||||
// query effects
|
||||
Plugin::getDescriptorsOfAvailPlugins( m_pluginDescriptors );
|
||||
|
||||
EffectKeyList subPluginEffectKeys;
|
||||
|
||||
for( Plugin::DescriptorList::ConstIterator it = m_pluginDescriptors.begin();
|
||||
it != m_pluginDescriptors.end(); ++it )
|
||||
for (const Plugin::Descriptor* desc: pluginFactory->descriptors())
|
||||
{
|
||||
if( it->type != Plugin::Effect )
|
||||
if( desc->type != Plugin::Effect )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if( it->subPluginFeatures )
|
||||
if( desc->subPluginFeatures )
|
||||
{
|
||||
it->subPluginFeatures->listSubPluginKeys(
|
||||
desc->subPluginFeatures->listSubPluginKeys(
|
||||
// as iterators are always stated to be not
|
||||
// equal with pointers, we dereference the
|
||||
// iterator and take the address of the item,
|
||||
// so we're on the safe side and the compiler
|
||||
// likely will reduce that to just "it"
|
||||
&( *it ),
|
||||
desc,
|
||||
subPluginEffectKeys );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_effectKeys << EffectKey( &( *it ), it->name );
|
||||
m_effectKeys << EffectKey( desc, desc->name );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "SideBar.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "Mixer.h"
|
||||
#include "PluginFactory.h"
|
||||
#include "PluginView.h"
|
||||
#include "ProjectNotes.h"
|
||||
#include "SetupDialog.h"
|
||||
@@ -296,17 +297,13 @@ void MainWindow::finalize()
|
||||
|
||||
|
||||
m_toolsMenu = new QMenu( this );
|
||||
Plugin::DescriptorList pluginDescriptors;
|
||||
Plugin::getDescriptorsOfAvailPlugins( pluginDescriptors );
|
||||
for( Plugin::DescriptorList::ConstIterator it = pluginDescriptors.begin();
|
||||
it != pluginDescriptors.end(); ++it )
|
||||
for( const Plugin::Descriptor* desc : pluginFactory->descriptors() )
|
||||
{
|
||||
if( it->type == Plugin::Tool )
|
||||
if( desc->type == Plugin::Tool )
|
||||
{
|
||||
m_toolsMenu->addAction( it->logo->pixmap(),
|
||||
it->displayName );
|
||||
m_tools.push_back( ToolPlugin::instantiate( it->name,
|
||||
/*this*/NULL )->createView( this ) );
|
||||
m_toolsMenu->addAction( desc->logo->pixmap(), desc->displayName );
|
||||
m_tools.push_back( ToolPlugin::instantiate( desc->name, /*this*/NULL )
|
||||
->createView(this) );
|
||||
}
|
||||
}
|
||||
if( !m_toolsMenu->isEmpty() )
|
||||
|
||||
@@ -22,25 +22,27 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PluginBrowser.h"
|
||||
|
||||
#include <algorithm> // for std::sort
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
#include <QCursor>
|
||||
#include <QMouseEvent>
|
||||
#include <QScrollArea>
|
||||
|
||||
#include "PluginBrowser.h"
|
||||
#include <algorithm> // for std::sort
|
||||
|
||||
#include "embed.h"
|
||||
#include "debug.h"
|
||||
#include "templates.h"
|
||||
#include "gui_templates.h"
|
||||
#include "StringPairDrag.h"
|
||||
#include "PluginFactory.h"
|
||||
|
||||
|
||||
bool pluginBefore( const Plugin::Descriptor& d1, const Plugin::Descriptor& d2 )
|
||||
bool pluginBefore( const Plugin::Descriptor* d1, const Plugin::Descriptor* d2 )
|
||||
{
|
||||
return qstricmp( d1.displayName, d2.displayName ) < 0 ? true : false;
|
||||
return qstricmp( d1->displayName, d2->displayName ) < 0 ? true : false;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,15 +95,13 @@ PluginDescList::PluginDescList(QWidget *parent) :
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
Plugin::getDescriptorsOfAvailPlugins( m_pluginDescriptors );
|
||||
std::sort(m_pluginDescriptors.begin(), m_pluginDescriptors.end(), pluginBefore);
|
||||
|
||||
for( Plugin::DescriptorList::const_iterator it = m_pluginDescriptors.constBegin();
|
||||
it != m_pluginDescriptors.constEnd(); ++it )
|
||||
QList<Plugin::Descriptor*> descs = pluginFactory->descriptors();
|
||||
std::sort(descs.begin(), descs.end(), pluginBefore);
|
||||
for (const Plugin::Descriptor* desc : descs)
|
||||
{
|
||||
if( it->type == Plugin::Instrument )
|
||||
if( desc->type == Plugin::Instrument )
|
||||
{
|
||||
PluginDescWidget* p = new PluginDescWidget( *it, this );
|
||||
PluginDescWidget* p = new PluginDescWidget( *desc, this );
|
||||
p->show();
|
||||
layout->addWidget(p);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user