From 7be47230e33e381991001f6f28b7468e877d581a Mon Sep 17 00:00:00 2001 From: Lukas W Date: Thu, 29 Jan 2015 13:48:52 +0100 Subject: [PATCH 1/7] Introduce PluginFactory class This singleton class handles management of plugin search paths and plugin discovery. Search paths are (if they exist): * /../lib/lmms: This is the common location on Unixoids (Not included in Windows builds) * /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. --- include/ConfigManager.h | 6 - include/EffectSelectDialog.h | 1 - include/Plugin.h | 6 +- include/PluginBrowser.h | 3 - include/PluginFactory.h | 84 ++++++++++++++ plugins/CMakeLists.txt | 3 + plugins/LadspaEffect/CMakeLists.txt | 2 + plugins/flp_import/CMakeLists.txt | 1 + plugins/flp_import/FlpImport.cpp | 14 +-- src/core/CMakeLists.txt | 1 + src/core/ConfigManager.cpp | 6 - src/core/EffectChain.cpp | 14 +-- src/core/Engine.cpp | 16 +-- src/core/ImportFilter.cpp | 14 +-- src/core/LadspaManager.cpp | 2 +- src/core/Plugin.cpp | 56 +-------- src/core/PluginFactory.cpp | 173 ++++++++++++++++++++++++++++ src/core/RemotePlugin.cpp | 3 +- src/gui/EffectSelectDialog.cpp | 15 ++- src/gui/MainWindow.cpp | 15 +-- src/gui/PluginBrowser.cpp | 24 ++-- 21 files changed, 321 insertions(+), 138 deletions(-) create mode 100644 include/PluginFactory.h create mode 100644 src/core/PluginFactory.cpp diff --git a/include/ConfigManager.h b/include/ConfigManager.h index b22792288..ecb6815ce 100644 --- a/include/ConfigManager.h +++ b/include/ConfigManager.h @@ -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; diff --git a/include/EffectSelectDialog.h b/include/EffectSelectDialog.h index 658966bdf..995f14fb1 100644 --- a/include/EffectSelectDialog.h +++ b/include/EffectSelectDialog.h @@ -55,7 +55,6 @@ protected slots: private: Ui::EffectSelectDialog * ui; - Plugin::DescriptorList m_pluginDescriptors; EffectKeyList m_effectKeys; EffectKey m_currentSelection; diff --git a/include/Plugin.h b/include/Plugin.h index 40a075c67..0b207a584 100644 --- a/include/Plugin.h +++ b/include/Plugin.h @@ -137,9 +137,8 @@ public: SubPluginFeatures *subPluginFeatures; } ; - // typedef a list so we can easily work with list of plugin descriptors - typedef QList DescriptorList; + typedef QList 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 ); diff --git a/include/PluginBrowser.h b/include/PluginBrowser.h index ee399e25a..9f54d86ec 100644 --- a/include/PluginBrowser.h +++ b/include/PluginBrowser.h @@ -55,9 +55,6 @@ class PluginDescList : public QWidget Q_OBJECT public: PluginDescList(QWidget* parent); - -private: - Plugin::DescriptorList m_pluginDescriptors; }; diff --git a/include/PluginFactory.h b/include/PluginFactory.h new file mode 100644 index 000000000..7b59e2a2f --- /dev/null +++ b/include/PluginFactory.h @@ -0,0 +1,84 @@ +/* + * PluginFactory.h + * + * Copyright (c) 2015 Lukas W + * + * 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 +#include + +#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 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 m_errors; + + static PluginFactory* s_instance; +}; + +#define pluginFactory PluginFactory::instance() + +#endif // PLUGINFACTORY_H diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index d7b4cf11e..8de6bb09c 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -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) diff --git a/plugins/LadspaEffect/CMakeLists.txt b/plugins/LadspaEffect/CMakeLists.txt index 80802ec35..37a32ff24 100644 --- a/plugins/LadspaEffect/CMakeLists.txt +++ b/plugins/LadspaEffect/CMakeLists.txt @@ -1,3 +1,5 @@ +SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ladspa") + IF(WANT_CAPS) ADD_SUBDIRECTORY(caps) ENDIF(WANT_CAPS) diff --git a/plugins/flp_import/CMakeLists.txt b/plugins/flp_import/CMakeLists.txt index 1a2c2c7e4..e4bfed8a7 100644 --- a/plugins/flp_import/CMakeLists.txt +++ b/plugins/flp_import/CMakeLists.txt @@ -2,4 +2,5 @@ INCLUDE(BuildPlugin) INCLUDE_DIRECTORIES(unrtf) +ADD_DEFINITIONS(--std=c++0x) BUILD_PLUGIN(flpimport FlpImport.cpp unrtf.cpp FlpImport.h) diff --git a/plugins/flp_import/FlpImport.cpp b/plugins/flp_import/FlpImport.cpp index c23097d2c..3173aabae 100644 --- a/plugins/flp_import/FlpImport.cpp +++ b/plugins/flp_import/FlpImport.cpp @@ -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 ); } } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ae23ae6d9..e974d151f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -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 diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp index c556870c3..22df6f3d5 100644 --- a/src/core/ConfigManager.cpp +++ b/src/core/ConfigManager.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") ) diff --git a/src/core/EffectChain.cpp b/src/core/EffectChain.cpp index f310f94dc..0a2d1d710 100644 --- a/src/core/EffectChain.cpp +++ b/src/core/EffectChain.cpp @@ -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( *it ) ) + if( DummyEffect* dummy = dynamic_cast(effect) ) { - _this.appendChild( dynamic_cast( *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() ) { diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index 5730e977e..483e3706f 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -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; } } } diff --git a/src/core/ImportFilter.cpp b/src/core/ImportFilter.cpp index e126de512..6b0e6b6ef 100644 --- a/src/core/ImportFilter.cpp +++ b/src/core/ImportFilter.cpp @@ -2,7 +2,7 @@ * ImportFilter.cpp - base-class for all import-filters (MIDI, FLP etc) * * Copyright (c) 2006-2014 Tobias Doerffel - * + * * 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( p ) != NULL && dynamic_cast( p )->tryImport( tc ) == true ) { diff --git a/src/core/LadspaManager.cpp b/src/core/LadspaManager.cpp index 8dcb20158..a397efc86 100644 --- a/src/core/LadspaManager.cpp +++ b/src/core/LadspaManager.cpp @@ -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" ); diff --git a/src/core/Plugin.cpp b/src/core/Plugin.cpp index abdc44a96..729fb11c0 100644 --- a/src/core/Plugin.cpp +++ b/src/core/Plugin.cpp @@ -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 ); diff --git a/src/core/PluginFactory.cpp b/src/core/PluginFactory.cpp new file mode 100644 index 000000000..abf6827f2 --- /dev/null +++ b/src/core/PluginFactory.cpp @@ -0,0 +1,173 @@ +/* + * PluginFactory.cpp + * + * Copyright (c) 2015 Lukas W + * + * 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 +#include +#include +#include +#include + +#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::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; +} + diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index 84555fb3c..a9c02c0dc 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -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 diff --git a/src/gui/EffectSelectDialog.cpp b/src/gui/EffectSelectDialog.cpp index 9cfa9ee08..1905dc615 100644 --- a/src/gui/EffectSelectDialog.cpp +++ b/src/gui/EffectSelectDialog.cpp @@ -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 ); } } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index cccc7bd39..dd00a9d8e 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -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() ) diff --git a/src/gui/PluginBrowser.cpp b/src/gui/PluginBrowser.cpp index 96f33ae75..bff6a7919 100644 --- a/src/gui/PluginBrowser.cpp +++ b/src/gui/PluginBrowser.cpp @@ -22,25 +22,27 @@ * */ +#include "PluginBrowser.h" + +#include // for std::sort + #include #include #include #include #include -#include "PluginBrowser.h" -#include // 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 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); } From dc1f8dc365073379ec2ea844a17ce5eda2a18890 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Thu, 29 Jan 2015 13:54:09 +0100 Subject: [PATCH 2/7] Add data search path support Also add LMMS_DATA_DIR env var to "data:" search paths. When lmms is launched from its build directory (without `make install`ing), LMMS_DATA_DIR can be passed to point lmms to the "data" directory in the source tree. --- src/core/BandLimitedWave.cpp | 2 +- src/core/ConfigManager.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/BandLimitedWave.cpp b/src/core/BandLimitedWave.cpp index de608ba1d..b60cbd633 100644 --- a/src/core/BandLimitedWave.cpp +++ b/src/core/BandLimitedWave.cpp @@ -67,7 +67,7 @@ void BandLimitedWave::generateWaves() int i; // set wavetable directory - s_wavetableDir = ConfigManager::inst()->dataDir() + "wavetables/"; + s_wavetableDir = "data:wavetables/"; // set wavetable files QFile saw_file( s_wavetableDir + "saw.bin" ); diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp index 22df6f3d5..bc9a50b48 100644 --- a/src/core/ConfigManager.cpp +++ b/src/core/ConfigManager.cpp @@ -63,6 +63,9 @@ ConfigManager::ConfigManager() : m_flDir( QDir::home().absolutePath() ), m_recoveryFile( QDir(m_workingDir).absoluteFilePath("recover.mmp") ) { + if (! qgetenv("LMMS_DATA_DIR").isEmpty()) + QDir::addSearchPath("data", QString::fromLocal8Bit(qgetenv("LMMS_DATA_DIR"))); + QDir::addSearchPath("data", m_dataDir); } From c28b0b5407e95814bca7742b15d3a4240339feb0 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Thu, 29 Jan 2015 14:00:29 +0100 Subject: [PATCH 3/7] PluginFactory: Map plugins by type --- include/PluginFactory.h | 4 +++- plugins/flp_import/FlpImport.cpp | 6 +----- src/core/Engine.cpp | 9 +++------ src/core/ImportFilter.cpp | 17 +++++++---------- src/core/PluginFactory.cpp | 13 +++++++++---- src/gui/EffectSelectDialog.cpp | 6 +----- src/gui/MainWindow.cpp | 11 ++++------- src/gui/PluginBrowser.cpp | 11 ++++------- 8 files changed, 32 insertions(+), 45 deletions(-) diff --git a/include/PluginFactory.h b/include/PluginFactory.h index 7b59e2a2f..2ddd6f9e2 100644 --- a/include/PluginFactory.h +++ b/include/PluginFactory.h @@ -44,6 +44,7 @@ public: bool isNull() const {return library == 0;} }; typedef QList PluginInfoList; + typedef QMultiMap DescriptorMap; PluginFactory(); ~PluginFactory(); @@ -54,6 +55,7 @@ public: /// Returns a list of all found plugins' descriptors. const Plugin::DescriptorList descriptors() const; + const Plugin::DescriptorList descriptors(Plugin::PluginTypes type) const; /// Returns a list of all found plugins' PluginFactory::PluginInfo objects. const PluginInfoList& pluginInfos() const; @@ -71,7 +73,7 @@ public slots: void discoverPlugins(); private: - Plugin::DescriptorList m_descriptorList; + DescriptorMap m_descriptors; PluginInfoList m_pluginInfos; QHash m_errors; diff --git a/plugins/flp_import/FlpImport.cpp b/plugins/flp_import/FlpImport.cpp index 3173aabae..312dfb0a7 100644 --- a/plugins/flp_import/FlpImport.cpp +++ b/plugins/flp_import/FlpImport.cpp @@ -1638,12 +1638,8 @@ p->putValue( jt->pos, value, false ); // process all effects EffectKeyList effKeys; - for (const Plugin::Descriptor* desc : pluginFactory->descriptors()) + for (const Plugin::Descriptor* desc : pluginFactory->descriptors(Plugin::Effect)) { - if( desc->type != Plugin::Effect ) - { - continue; - } if( desc->subPluginFeatures ) { desc->subPluginFeatures->listSubPluginKeys( desc, effKeys ); diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index 483e3706f..2c2a7b57a 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -123,14 +123,11 @@ void Engine::updateFramesPerTick() void Engine::initPluginFileHandling() { - for (const Plugin::Descriptor* desc : pluginFactory->descriptors()) + for (const Plugin::Descriptor* desc : pluginFactory->descriptors(Plugin::Instrument)) { - if( desc->type == Plugin::Instrument ) + for(const QString& ext : QString(desc->supportedFileTypes).split(',')) { - for(const QString& ext : QString(desc->supportedFileTypes).split(',')) - { - s_pluginFileHandling[ext] = desc->name; - } + s_pluginFileHandling[ext] = desc->name; } } } diff --git a/src/core/ImportFilter.cpp b/src/core/ImportFilter.cpp index 6b0e6b6ef..7b5644721 100644 --- a/src/core/ImportFilter.cpp +++ b/src/core/ImportFilter.cpp @@ -60,20 +60,17 @@ void ImportFilter::import( const QString & _file_to_import, const bool j = Engine::projectJournal()->isJournalling(); Engine::projectJournal()->setJournalling( false ); - for (const Plugin::Descriptor* desc : pluginFactory->descriptors()) + for (const Plugin::Descriptor* desc : pluginFactory->descriptors(Plugin::ImportFilter)) { - if( desc->type == Plugin::ImportFilter ) + Plugin * p = Plugin::instantiate( desc->name, NULL, s ); + if( dynamic_cast( p ) != NULL && + dynamic_cast( p )->tryImport( tc ) == true ) { - Plugin * p = Plugin::instantiate( desc->name, NULL, s ); - if( dynamic_cast( p ) != NULL && - dynamic_cast( p )->tryImport( tc ) == true ) - { - delete p; - successful = true; - break; - } delete p; + successful = true; + break; } + delete p; } Engine::projectJournal()->setJournalling( j ); diff --git a/src/core/PluginFactory.cpp b/src/core/PluginFactory.cpp index abf6827f2..dfae2fa51 100644 --- a/src/core/PluginFactory.cpp +++ b/src/core/PluginFactory.cpp @@ -89,7 +89,12 @@ PluginFactory* PluginFactory::instance() const Plugin::DescriptorList PluginFactory::descriptors() const { - return m_descriptorList; + return m_descriptors.values(); +} + +const Plugin::DescriptorList PluginFactory::descriptors(Plugin::PluginTypes type) const +{ + return m_descriptors.values(type); } const QList& PluginFactory::pluginInfos() const @@ -115,7 +120,7 @@ QString PluginFactory::errorString(QString pluginName) const void PluginFactory::discoverPlugins() { - Plugin::DescriptorList descriptors; + DescriptorMap descriptors; PluginInfoList pluginInfos; const QFileInfoList& files = QDir("plugins:").entryInfoList(nameFilters); @@ -159,7 +164,7 @@ void PluginFactory::discoverPlugins() info.descriptor = pluginDescriptor; pluginInfos << info; - descriptors << pluginDescriptor; + descriptors.insert(info.descriptor->type, info.descriptor); } @@ -168,6 +173,6 @@ void PluginFactory::discoverPlugins() delete info.library; } m_pluginInfos = pluginInfos; - m_descriptorList = descriptors; + m_descriptors = descriptors; } diff --git a/src/gui/EffectSelectDialog.cpp b/src/gui/EffectSelectDialog.cpp index 1905dc615..fb70da6ab 100644 --- a/src/gui/EffectSelectDialog.cpp +++ b/src/gui/EffectSelectDialog.cpp @@ -46,12 +46,8 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) : EffectKeyList subPluginEffectKeys; - for (const Plugin::Descriptor* desc: pluginFactory->descriptors()) + for (const Plugin::Descriptor* desc: pluginFactory->descriptors(Plugin::Effect)) { - if( desc->type != Plugin::Effect ) - { - continue; - } if( desc->subPluginFeatures ) { desc->subPluginFeatures->listSubPluginKeys( diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index dd00a9d8e..b7f5c1443 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -297,14 +297,11 @@ void MainWindow::finalize() m_toolsMenu = new QMenu( this ); - for( const Plugin::Descriptor* desc : pluginFactory->descriptors() ) + for( const Plugin::Descriptor* desc : pluginFactory->descriptors(Plugin::Tool) ) { - if( desc->type == Plugin::Tool ) - { - m_toolsMenu->addAction( desc->logo->pixmap(), desc->displayName ); - m_tools.push_back( ToolPlugin::instantiate( desc->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() ) { diff --git a/src/gui/PluginBrowser.cpp b/src/gui/PluginBrowser.cpp index bff6a7919..549b20bf9 100644 --- a/src/gui/PluginBrowser.cpp +++ b/src/gui/PluginBrowser.cpp @@ -95,16 +95,13 @@ PluginDescList::PluginDescList(QWidget *parent) : { QVBoxLayout* layout = new QVBoxLayout(this); - QList descs = pluginFactory->descriptors(); + QList descs = pluginFactory->descriptors(Plugin::Instrument); std::sort(descs.begin(), descs.end(), pluginBefore); for (const Plugin::Descriptor* desc : descs) { - if( desc->type == Plugin::Instrument ) - { - PluginDescWidget* p = new PluginDescWidget( *desc, this ); - p->show(); - layout->addWidget(p); - } + PluginDescWidget* p = new PluginDescWidget( *desc, this ); + p->show(); + layout->addWidget(p); } setLayout(layout); From 2a0c08afa2b9a4a86b0d0b6c293ad115e84dbbf5 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Thu, 29 Jan 2015 16:37:10 +0100 Subject: [PATCH 4/7] Fix windows build --- cmake/modules/BuildPlugin.cmake | 2 +- include/PluginFactory.h | 3 ++- plugins/LadspaEffect/calf/CMakeLists.txt | 2 +- plugins/LadspaEffect/caps/CMakeLists.txt | 2 +- plugins/LadspaEffect/cmt/CMakeLists.txt | 2 +- plugins/LadspaEffect/swh/CMakeLists.txt | 2 +- plugins/LadspaEffect/tap/CMakeLists.txt | 2 +- plugins/vst_base/CMakeLists.txt | 2 +- plugins/vst_base/Win64/CMakeLists.txt | 2 +- plugins/zynaddsubfx/CMakeLists.txt | 4 ++-- src/core/ConfigManager.cpp | 2 +- 11 files changed, 13 insertions(+), 12 deletions(-) diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index 3add78661..438eebb90 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -57,7 +57,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) ENDIF(LMMS_BUILD_APPLE) IF(LMMS_BUILD_WIN32) SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES PREFIX "") - ADD_CUSTOM_COMMAND(TARGET ${PLUGIN_NAME} POST_BUILD COMMAND ${STRIP} ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_NAME}.dll) + ADD_CUSTOM_COMMAND(TARGET ${PLUGIN_NAME} POST_BUILD COMMAND ${STRIP} $) ENDIF(LMMS_BUILD_WIN32) SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${ER_H} ${plugin_MOC_out}") diff --git a/include/PluginFactory.h b/include/PluginFactory.h index 2ddd6f9e2..5b4e22c33 100644 --- a/include/PluginFactory.h +++ b/include/PluginFactory.h @@ -28,11 +28,12 @@ #include #include +#include "export.h" #include "Plugin.h" class QLibrary; -class PluginFactory +class EXPORT PluginFactory { public: struct PluginInfo diff --git a/plugins/LadspaEffect/calf/CMakeLists.txt b/plugins/LadspaEffect/calf/CMakeLists.txt index d685f5302..3bd4ae0f8 100644 --- a/plugins/LadspaEffect/calf/CMakeLists.txt +++ b/plugins/LadspaEffect/calf/CMakeLists.txt @@ -13,7 +13,7 @@ ENDIF() SET_TARGET_PROPERTIES(calf PROPERTIES COMPILE_FLAGS "-O2 -finline-functions ${INLINE_FLAGS}") IF(LMMS_BUILD_WIN32) - ADD_CUSTOM_COMMAND(TARGET calf POST_BUILD COMMAND "${STRIP}" "\"${CMAKE_CURRENT_BINARY_DIR}/calf.dll\"") + ADD_CUSTOM_COMMAND(TARGET calf POST_BUILD COMMAND "${STRIP}" "$") ENDIF(LMMS_BUILD_WIN32) IF(NOT LMMS_BUILD_APPLE) SET_TARGET_PROPERTIES(calf PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined") diff --git a/plugins/LadspaEffect/caps/CMakeLists.txt b/plugins/LadspaEffect/caps/CMakeLists.txt index 4576a5c4a..415908e2b 100644 --- a/plugins/LadspaEffect/caps/CMakeLists.txt +++ b/plugins/LadspaEffect/caps/CMakeLists.txt @@ -9,7 +9,7 @@ SET_TARGET_PROPERTIES(caps PROPERTIES PREFIX "") SET_TARGET_PROPERTIES(caps PROPERTIES COMPILE_FLAGS "-O2 -funroll-loops -Wno-write-strings") IF(LMMS_BUILD_WIN32) - ADD_CUSTOM_COMMAND(TARGET caps POST_BUILD COMMAND "${STRIP}" "\"${CMAKE_CURRENT_BINARY_DIR}/caps.dll\"") + ADD_CUSTOM_COMMAND(TARGET caps POST_BUILD COMMAND "${STRIP}" \"$\") ENDIF(LMMS_BUILD_WIN32) IF(NOT LMMS_BUILD_APPLE) SET_TARGET_PROPERTIES(caps PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined") diff --git a/plugins/LadspaEffect/cmt/CMakeLists.txt b/plugins/LadspaEffect/cmt/CMakeLists.txt index 382bfc4c4..81bb13dc2 100644 --- a/plugins/LadspaEffect/cmt/CMakeLists.txt +++ b/plugins/LadspaEffect/cmt/CMakeLists.txt @@ -7,7 +7,7 @@ SET_TARGET_PROPERTIES(cmt PROPERTIES PREFIX "") SET_TARGET_PROPERTIES(cmt PROPERTIES COMPILE_FLAGS "-Wall -O3 -fno-strict-aliasing") IF(LMMS_BUILD_WIN32) - ADD_CUSTOM_COMMAND(TARGET cmt POST_BUILD COMMAND "${STRIP}" "\"${CMAKE_CURRENT_BINARY_DIR}/cmt.dll\"") + ADD_CUSTOM_COMMAND(TARGET cmt POST_BUILD COMMAND "${STRIP}" \"$\") ELSE(LMMS_BUILD_WIN32) SET_TARGET_PROPERTIES(cmt PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -fPIC") ENDIF(LMMS_BUILD_WIN32) diff --git a/plugins/LadspaEffect/swh/CMakeLists.txt b/plugins/LadspaEffect/swh/CMakeLists.txt index 080f446e0..7d57d9cdb 100644 --- a/plugins/LadspaEffect/swh/CMakeLists.txt +++ b/plugins/LadspaEffect/swh/CMakeLists.txt @@ -15,7 +15,7 @@ FOREACH(_item ${PLUGIN_SOURCES}) SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES PREFIX "") SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES COMPILE_FLAGS "-O3 -Wall -fomit-frame-pointer -fstrength-reduce -funroll-loops -ffast-math -c -fno-strict-aliasing") IF(LMMS_BUILD_WIN32) - ADD_CUSTOM_COMMAND(TARGET "${_plugin}" POST_BUILD COMMAND "${STRIP}" "\"${CMAKE_CURRENT_BINARY_DIR}/${_plugin}.dll\"") + ADD_CUSTOM_COMMAND(TARGET "${_plugin}" POST_BUILD COMMAND "${STRIP}" \"$\") ELSE(LMMS_BUILD_WIN32) SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -fPIC -DPIC") ENDIF(LMMS_BUILD_WIN32) diff --git a/plugins/LadspaEffect/tap/CMakeLists.txt b/plugins/LadspaEffect/tap/CMakeLists.txt index d88c6990b..e8bc12017 100644 --- a/plugins/LadspaEffect/tap/CMakeLists.txt +++ b/plugins/LadspaEffect/tap/CMakeLists.txt @@ -7,7 +7,7 @@ FOREACH(_item ${PLUGIN_SOURCES}) INSTALL(TARGETS "${_plugin}" LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES PREFIX "") IF(LMMS_BUILD_WIN32) - ADD_CUSTOM_COMMAND(TARGET "${_plugin}" POST_BUILD COMMAND "${STRIP}" "\"${CMAKE_CURRENT_BINARY_DIR}/${_plugin}.dll\"") + ADD_CUSTOM_COMMAND(TARGET "${_plugin}" POST_BUILD COMMAND "${STRIP}" \"$\") ENDIF(LMMS_BUILD_WIN32) IF(LMMS_BUILD_APPLE) SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Bsymbolic -lm") diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 8f29acc7a..26967fca1 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -12,7 +12,7 @@ IF(LMMS_BUILD_WIN32) ENDIF() TARGET_LINK_LIBRARIES(RemoteVstPlugin -lpthread -lgdi32 -lws2_32) SET_TARGET_PROPERTIES(RemoteVstPlugin PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O3") - ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin POST_BUILD COMMAND "${STRIP}" "${CMAKE_CURRENT_BINARY_DIR}/RemoteVstPlugin.exe") + ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin POST_BUILD COMMAND "${STRIP}" "$") INSTALL(TARGETS RemoteVstPlugin RUNTIME DESTINATION "${PLUGIN_DIR}") IF(LMMS_BUILD_WIN64) diff --git a/plugins/vst_base/Win64/CMakeLists.txt b/plugins/vst_base/Win64/CMakeLists.txt index b16d50292..270f8e68b 100644 --- a/plugins/vst_base/Win64/CMakeLists.txt +++ b/plugins/vst_base/Win64/CMakeLists.txt @@ -4,7 +4,7 @@ SET(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER32}") ADD_EXECUTABLE(RemoteVstPlugin32 "${CMAKE_CURRENT_SOURCE_DIR}/../RemoteVstPlugin.cpp") TARGET_LINK_LIBRARIES(RemoteVstPlugin32 -lQtCore4 -lpthread -lgdi32 -lws2_32) -ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin32 POST_BUILD COMMAND "${STRIP}" "\"${CMAKE_CURRENT_BINARY_DIR}/RemoteVstPlugin32.exe\"") +ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin32 POST_BUILD COMMAND "${STRIP}" "$") SET_TARGET_PROPERTIES(RemoteVstPlugin32 PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O3") INSTALL(TARGETS RemoteVstPlugin32 RUNTIME DESTINATION "${PLUGIN_DIR}/32") diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index 9f751f38c..af575f82b 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -148,6 +148,6 @@ ENDIF(LMMS_BUILD_LINUX) IF(LMMS_BUILD_WIN32) - ADD_CUSTOM_COMMAND(TARGET ZynAddSubFxCore POST_BUILD COMMAND "${STRIP}" "\"${CMAKE_CURRENT_BINARY_DIR}/libZynAddSubFxCore.dll\"") - ADD_CUSTOM_COMMAND(TARGET RemoteZynAddSubFx POST_BUILD COMMAND "${STRIP}" "\"${CMAKE_CURRENT_BINARY_DIR}/RemoteZynAddSubFx.exe\"") + ADD_CUSTOM_COMMAND(TARGET ZynAddSubFxCore POST_BUILD COMMAND "${STRIP}" \"$\") + ADD_CUSTOM_COMMAND(TARGET RemoteZynAddSubFx POST_BUILD COMMAND "${STRIP}" \"$\") ENDIF(LMMS_BUILD_WIN32) diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp index bc9a50b48..c0ef424a2 100644 --- a/src/core/ConfigManager.cpp +++ b/src/core/ConfigManager.cpp @@ -350,7 +350,7 @@ void ConfigManager::loadConfigFile() ( !m_ladDir.contains( ':' ) && !QDir( m_ladDir ).exists() ) ) { #if defined(LMMS_BUILD_WIN32) - m_ladDir = m_pluginDir + "ladspa" + QDir::separator(); + m_ladDir = qApp->applicationDirPath() + "/plugins/ladspa" + QDir::separator(); #elif defined(LMMS_BUILD_APPLE) m_ladDir = qApp->applicationDirPath() + "/../lib/lmms/ladspa/"; #else From 863df4e3e6d994c29f6fd1d6df04c3833ed1d2d0 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Thu, 5 Feb 2015 17:21:57 +0100 Subject: [PATCH 5/7] Add support for reading theme path from environment variable --- src/core/ConfigManager.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp index c0ef424a2..2f5c29001 100644 --- a/src/core/ConfigManager.cpp +++ b/src/core/ConfigManager.cpp @@ -372,9 +372,11 @@ void ConfigManager::loadConfigFile() } #endif - - QDir::setSearchPaths( "resources", QStringList() << artworkDir() - << defaultArtworkDir() ); + QStringList searchPaths; + if(! qgetenv("LMMS_THEME_PATH").isNull()) + searchPaths << qgetenv("LMMS_THEME_PATH"); + searchPaths << artworkDir() << defaultArtworkDir(); + QDir::setSearchPaths( "resources", searchPaths); if( !QDir( m_workingDir ).exists() && QApplication::type() == QApplication::GuiClient && From 35e1c4ed899dde640e298129fde8c957fef05671 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Thu, 5 Feb 2015 17:22:23 +0100 Subject: [PATCH 6/7] Refactor: Move plugin file support handling to PluginFactory --- include/Engine.h | 12 ++------ include/PluginFactory.h | 7 ++++- src/core/Engine.cpp | 19 ------------- src/core/PluginFactory.cpp | 41 ++++++++++++++++++++-------- src/core/PresetPreviewPlayHandle.cpp | 4 +-- src/gui/FileBrowser.cpp | 7 +++-- src/gui/TrackContainerView.cpp | 4 +-- src/tracks/InstrumentTrack.cpp | 3 +- 8 files changed, 48 insertions(+), 49 deletions(-) diff --git a/include/Engine.h b/include/Engine.h index ad7abe399..1e87f336e 100644 --- a/include/Engine.h +++ b/include/Engine.h @@ -45,6 +45,8 @@ public: static void init(); static void destroy(); + // TODO: Remove me. Replace calls like `if( Engine::hasGUI() )` with + // `if (gui)` (gui defined in "GuiApplication.h" static bool hasGUI(); // core @@ -89,12 +91,6 @@ public: } static void updateFramesPerTick(); - static const QMap & pluginFileHandling() - { - return s_pluginFileHandling; - } - - private: // small helper function which sets the pointer to NULL before actually deleting // the object it refers to @@ -118,10 +114,6 @@ private: static Ladspa2LMMS * s_ladspaManager; - static QMap s_pluginFileHandling; - - static void initPluginFileHandling(); - friend class GuiApplication; }; diff --git a/include/PluginFactory.h b/include/PluginFactory.h index 5b4e22c33..7cf4806e2 100644 --- a/include/PluginFactory.h +++ b/include/PluginFactory.h @@ -38,13 +38,15 @@ class EXPORT PluginFactory public: struct PluginInfo { + PluginInfo() : library(nullptr), descriptor(nullptr) {} + const QString name() const; QFileInfo file; QLibrary* library; Plugin::Descriptor* descriptor; bool isNull() const {return library == 0;} }; - typedef QList PluginInfoList; + typedef QList PluginInfoList; typedef QMultiMap DescriptorMap; PluginFactory(); @@ -60,6 +62,8 @@ public: /// Returns a list of all found plugins' PluginFactory::PluginInfo objects. const PluginInfoList& pluginInfos() const; + /// Returns a plugin that support the given file extension + const PluginInfo pluginSupportingExtension(const QString& ext); /// Returns the PluginInfo object of the plugin with the given name. /// If the plugin is not found, an empty PluginInfo is returned (use @@ -76,6 +80,7 @@ public slots: private: DescriptorMap m_descriptors; PluginInfoList m_pluginInfos; + QMap m_pluginByExt; QHash m_errors; diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index 2c2a7b57a..de0a4e6e0 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -46,7 +46,6 @@ Song * Engine::s_song = NULL; ProjectJournal * Engine::s_projectJournal = NULL; Ladspa2LMMS * Engine::s_ladspaManager = NULL; DummyTrackContainer * Engine::s_dummyTC = NULL; -QMap Engine::s_pluginFileHandling; @@ -56,8 +55,6 @@ void Engine::init() // generate (load from file) bandlimited wavetables BandLimitedWave::generateWaves(); - initPluginFileHandling(); - s_projectJournal = new ProjectJournal; s_mixer = new Mixer; s_song = new Song; @@ -117,19 +114,3 @@ void Engine::updateFramesPerTick() s_framesPerTick = s_mixer->processingSampleRate() * 60.0f * 4 / DefaultTicksPerTact / s_song->getTempo(); } - - - - -void Engine::initPluginFileHandling() -{ - for (const Plugin::Descriptor* desc : pluginFactory->descriptors(Plugin::Instrument)) - { - for(const QString& ext : QString(desc->supportedFileTypes).split(',')) - { - s_pluginFileHandling[ext] = desc->name; - } - } -} - - diff --git a/src/core/PluginFactory.cpp b/src/core/PluginFactory.cpp index dfae2fa51..43083164f 100644 --- a/src/core/PluginFactory.cpp +++ b/src/core/PluginFactory.cpp @@ -97,17 +97,23 @@ const Plugin::DescriptorList PluginFactory::descriptors(Plugin::PluginTypes type return m_descriptors.values(type); } -const QList& PluginFactory::pluginInfos() const +const PluginFactory::PluginInfoList& PluginFactory::pluginInfos() const { return m_pluginInfos; } +const PluginFactory::PluginInfo PluginFactory::pluginSupportingExtension(const QString& ext) +{ + PluginInfo* info = m_pluginByExt.value(ext, nullptr); + return info == nullptr ? PluginInfo() : *info; +} + const PluginFactory::PluginInfo PluginFactory::pluginInfo(const char* name) const { - for (const PluginInfo& info : m_pluginInfos) + for (const PluginInfo* info : m_pluginInfos) { - if (qstrcmp(info.descriptor->name, name) == 0) - return info; + if (qstrcmp(info->descriptor->name, name) == 0) + return *info; } return PluginInfo(); } @@ -122,6 +128,7 @@ void PluginFactory::discoverPlugins() { DescriptorMap descriptors; PluginInfoList pluginInfos; + m_pluginByExt.clear(); const QFileInfoList& files = QDir("plugins:").entryInfoList(nameFilters); @@ -158,21 +165,33 @@ void PluginFactory::discoverPlugins() continue; } - PluginInfo info; - info.file = file; - info.library = library; - info.descriptor = pluginDescriptor; + PluginInfo* info = new PluginInfo; + info->file = file; + info->library = library; + info->descriptor = pluginDescriptor; pluginInfos << info; - descriptors.insert(info.descriptor->type, info.descriptor); + for (const QString& ext : QString(info->descriptor->supportedFileTypes).split(',')) + { + m_pluginByExt.insert(ext, info); + } + + descriptors.insert(info->descriptor->type, info->descriptor); } - for (PluginInfo& info : m_pluginInfos) + for (PluginInfo* info : m_pluginInfos) { - delete info.library; + delete info->library; + delete info; } m_pluginInfos = pluginInfos; m_descriptors = descriptors; } + + +const QString PluginFactory::PluginInfo::name() const +{ + return descriptor ? descriptor->name : QString(); +} diff --git a/src/core/PresetPreviewPlayHandle.cpp b/src/core/PresetPreviewPlayHandle.cpp index 09ebaca16..4282b29a2 100644 --- a/src/core/PresetPreviewPlayHandle.cpp +++ b/src/core/PresetPreviewPlayHandle.cpp @@ -33,6 +33,7 @@ #include "MidiPort.h" #include "DataFile.h" #include "NotePlayHandle.h" +#include "PluginFactory.h" #include "ProjectJournal.h" #include "TrackContainer.h" @@ -134,8 +135,7 @@ PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file, if( i == NULL || !i->descriptor()->supportsFileType( ext ) ) { i = s_previewTC->previewInstrumentTrack()-> - loadInstrument( - Engine::pluginFileHandling()[ext] ); + loadInstrument(pluginFactory->pluginSupportingExtension(ext).name()); } if( i != NULL ) { diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 0d19ec6aa..704264b62 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -45,6 +45,7 @@ #include "InstrumentTrack.h" #include "MainWindow.h" #include "DataFile.h" +#include "PluginFactory.h" #include "PresetPreviewPlayHandle.h" #include "SamplePlayHandle.h" #include "Song.h" @@ -586,7 +587,7 @@ void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it ) !i->descriptor()->supportsFileType( e ) ) { i = it->loadInstrument( - Engine::pluginFileHandling()[e] ); + pluginFactory->pluginSupportingExtension(e).name() ); } i->loadFile( f->fullName() ); break; @@ -1019,7 +1020,7 @@ void FileItem::determineFileType( void ) m_type = PresetFile; m_handling = LoadAsPreset; } - else if( ext == "xiz" && Engine::pluginFileHandling().contains( ext ) ) + else if( ext == "xiz" && ! pluginFactory->pluginSupportingExtension(ext).isNull() ) { m_type = PresetFile; m_handling = LoadByPlugin; @@ -1053,7 +1054,7 @@ void FileItem::determineFileType( void ) } if( m_handling == NotSupported && - !ext.isEmpty() && Engine::pluginFileHandling().contains( ext ) ) + !ext.isEmpty() && ! pluginFactory->pluginSupportingExtension(ext).isNull() ) { m_handling = LoadByPlugin; // classify as sample if not classified by anything yet but can diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index 23250dc10..7df7e3039 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -46,6 +46,7 @@ #include "StringPairDrag.h" #include "Track.h" #include "GuiApplication.h" +#include "PluginFactory.h" TrackContainerView::TrackContainerView( TrackContainer * _tc ) : @@ -352,8 +353,7 @@ void TrackContainerView::dropEvent( QDropEvent * _de ) Track::create( Track::InstrumentTrack, m_tc ) ); Instrument * i = it->loadInstrument( - Engine::pluginFileHandling()[FileItem::extension( - value )]); + pluginFactory->pluginSupportingExtension(FileItem::extension(value)).name()); i->loadFile( value ); //it->toggledInstrumentTrackButton( true ); _de->accept(); diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index cd598529e..4715fc7d7 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -71,6 +71,7 @@ #include "DataFile.h" #include "NotePlayHandle.h" #include "Pattern.h" +#include "PluginFactory.h" #include "PluginView.h" #include "SamplePlayHandle.h" #include "Song.h" @@ -1558,7 +1559,7 @@ void InstrumentTrackWindow::dropEvent( QDropEvent* event ) if( !i->descriptor()->supportsFileType( ext ) ) { - i = m_track->loadInstrument( Engine::pluginFileHandling()[ext] ); + i = m_track->loadInstrument( pluginFactory->pluginSupportingExtension(ext).name() ); } i->loadFile( value ); From cc454b2b53432797459cf997361480f36ca2fc6a Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 30 May 2015 22:59:18 +0200 Subject: [PATCH 7/7] Fix pixmap discovery --- src/gui/embed.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/gui/embed.cpp b/src/gui/embed.cpp index 4e6ecaa13..7d99bb0f1 100644 --- a/src/gui/embed.cpp +++ b/src/gui/embed.cpp @@ -71,19 +71,12 @@ QPixmap getIconPixmap( const char * pixmapName, int width, int height ) #ifdef PLUGIN_NAME for ( i = 0; i < candidates.size() && pixmap.isNull(); ++i ) { name = candidates.at( i ); - pixmap = QPixmap( ConfigManager::inst()->artworkDir() + "plugins/" + - STRINGIFY( PLUGIN_NAME ) + "_" + name ); + pixmap = QPixmap( "resources:plugins/" STRINGIFY( PLUGIN_NAME ) "_" + name ); } #endif for ( i = 0; i < candidates.size() && pixmap.isNull(); ++i ) { name = candidates.at( i ); - pixmap = QPixmap( ConfigManager::inst()->artworkDir() + name ); - } - - // nothing found, so look in default-artwork-dir - for ( i = 0; i < candidates.size() && pixmap.isNull(); ++i ) { - name = candidates.at( i ); - pixmap = QPixmap( ConfigManager::inst()->defaultArtworkDir() + name ); + pixmap = QPixmap( "resources:" + name ); } for ( i = 0; i < candidates.size() && pixmap.isNull(); ++i ) {