1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-17 00:20:06 +02:00

Change ModuleInterface for support of drag-and-drop of plug-in files

This commit is contained in:
Paul Licameli 2017-12-28 18:29:03 -05:00
parent 6463e12576
commit 8cfb8d2400
18 changed files with 194 additions and 92 deletions

View File

@ -42,6 +42,14 @@
#ifndef __AUDACITY_MODULEINTERFACE_H__
#define __AUDACITY_MODULEINTERFACE_H__
#include <functional>
#ifdef __WXMAC__
// Needs this for std::function
// Make this go away when Mac moves to a proper C++11 library
#include "../../src/MemoryX.h"
#endif
#include "audacity/Types.h"
#include "audacity/IdentInterface.h"
#include "audacity/PluginInterface.h"
@ -75,23 +83,45 @@ public:
// Called just prior to deletion to allow releasing any resources.
virtual void Terminate() = 0;
// "Paths" returned by FindPluginPaths() and passed back to
// DiscoverPluginsAtPath() have module-specific meaning.
// They are not necessarily file system paths to existent files that
// could be placed in any folder and queried for
// plugin information. This function returns true when that is the case.
virtual bool PathsAreFiles() = 0;
// Returns empty, or else, where to copy a plug-in file or bundle.
// Drag-and-drop is supported only if PathsAreFiles() is true and this
// function returns nonempty.
virtual wxString InstallPath() = 0;
// Modules providing a single or static set of plugins may use
// AutoRegisterPlugins() to register those plugins.
virtual bool AutoRegisterPlugins(PluginManagerInterface & pluginManager) = 0;
// For modules providing an interface to other dynamically loaded plugins,
// the module returns a list of path names that will be presented to the
// user for enablement.
virtual wxArrayString FindPlugins(PluginManagerInterface & pluginManager) = 0;
// user as "New" for enablement.
virtual wxArrayString FindPluginPaths(PluginManagerInterface & pluginManager) = 0;
// Once the user selects desired paths from FindPlugins(), a call to RegisterPlugin()
// will be made to request registration of that plugin. If the module must create
// Once the user selects desired paths from FindPluginPaths(),
// a call to DiscoverPluginsAtPath()
// will be made to request registration of one or more plugins. If the module must create
// an instance of the plugin to register it, then then instance should be deleted
// after registration.
// Error message does not need to mention the path.
virtual bool RegisterPlugin(PluginManagerInterface & pluginManager,
const wxString & path,
wxString &errMsg) = 0;
// May discover more than one plug-in at the path, and
// may call-back with paths not equal to path (perhaps appending
// other information to it).
// Error message does not need to mention the path and may be nonempty
// even if some plugins are also discovered successfully.
// Return value is the number of plugins found.
using RegistrationCallback =
std::function< void(ModuleInterface *, EffectIdentInterface *) >;
virtual unsigned DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback =
PluginManagerInterface::DefaultRegistrationCallback)
= 0;
// For modules providing an interface to other dynamically loaded plugins,
// the module returns true if the plugin is still valid, otherwise false.

View File

@ -54,6 +54,9 @@ class PluginManagerInterface /* not final */
{
public:
static const PluginID &DefaultRegistrationCallback(
ModuleInterface *provider, EffectIdentInterface *ident );
virtual bool IsPluginRegistered(const wxString & path) = 0;
virtual const PluginID & RegisterPlugin(ModuleInterface *module) = 0;

View File

@ -514,7 +514,7 @@ void ModuleManager::FindAllPlugins(PluginIDList & providers, wxArrayString & pat
ModuleInterface *module =
static_cast<ModuleInterface *>(CreateProviderInstance(providerID, modPaths[i]));
wxArrayString newpaths = module->FindPlugins(pm);
wxArrayString newpaths = module->FindPluginPaths(pm);
for (size_t i = 0, cnt = newpaths.size(); i < cnt; i++)
{
providers.push_back(providerID);
@ -536,7 +536,7 @@ wxArrayString ModuleManager::FindPluginsForProvider(const PluginID & providerID,
}
}
return mDynModules[providerID]->FindPlugins(PluginManager::Get());
return mDynModules[providerID]->FindPluginPaths(PluginManager::Get());
}
bool ModuleManager::RegisterPlugin(const PluginID & providerID, const wxString & path, wxString &errMsg)
@ -547,8 +547,9 @@ bool ModuleManager::RegisterPlugin(const PluginID & providerID, const wxString &
return false;
}
return mDynModules[providerID]->RegisterPlugin(PluginManager::Get(), path,
errMsg);
auto nFound = mDynModules[providerID]->DiscoverPluginsAtPath(path, errMsg);
return nFound > 0;
}
IdentInterface *ModuleManager::CreateProviderInstance(const PluginID & providerID,

View File

@ -1379,6 +1379,12 @@ void PluginDescriptor::SetImporterExtensions(const wxArrayString & extensions)
//
// ============================================================================
const PluginID &PluginManagerInterface::DefaultRegistrationCallback(
ModuleInterface *provider, EffectIdentInterface *pInterface )
{
return PluginManager::Get().RegisterPlugin(provider, pInterface);
}
bool PluginManager::IsPluginRegistered(const wxString & path)
{
for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); ++iter)

View File

@ -297,7 +297,8 @@ bool BuiltinEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
if (!pm.IsPluginRegistered(path))
{
// No checking of error ?
RegisterPlugin(pm, path, ignoredErrMsg);
DiscoverPluginsAtPath(path, ignoredErrMsg,
PluginManagerInterface::DefaultRegistrationCallback);
}
}
@ -305,25 +306,25 @@ bool BuiltinEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
return false;
}
wxArrayString BuiltinEffectsModule::FindPlugins(PluginManagerInterface & WXUNUSED(pm))
wxArrayString BuiltinEffectsModule::FindPluginPaths(PluginManagerInterface & WXUNUSED(pm))
{
return mNames;
}
bool BuiltinEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
const wxString & path,
wxString &errMsg)
unsigned BuiltinEffectsModule::DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
{
errMsg.clear();
auto effect = Instantiate(path);
if (effect)
{
pm.RegisterPlugin(this, effect.get());
return true;
callback(this, effect.get());
return 1;
}
errMsg = _("Unknown built-in effect name");
return false;
return 0;
}
bool BuiltinEffectsModule::IsPluginValid(const wxString & path, bool bFast)

View File

@ -41,10 +41,15 @@ public:
bool Initialize() override;
void Terminate() override;
bool PathsAreFiles() override { return false; }
wxString InstallPath() override { return {}; }
bool AutoRegisterPlugins(PluginManagerInterface & pm) override;
wxArrayString FindPlugins(PluginManagerInterface & pm) override;
bool RegisterPlugin(PluginManagerInterface & pm,
const wxString & path, wxString &errMsg) override;
wxArrayString FindPluginPaths(PluginManagerInterface & pm) override;
unsigned DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
override;
bool IsPluginValid(const wxString & path, bool bFast) override;

View File

@ -351,13 +351,21 @@ void VSTEffectsModule::Terminate()
return;
}
wxString VSTEffectsModule::InstallPath()
{
// Not yet ready for VST drag-and-drop...
// return FileNames::PlugInDir();
return {};
}
bool VSTEffectsModule::AutoRegisterPlugins(PluginManagerInterface & WXUNUSED(pm))
{
// We don't auto-register
return true;
}
wxArrayString VSTEffectsModule::FindPlugins(PluginManagerInterface & pm)
wxArrayString VSTEffectsModule::FindPluginPaths(PluginManagerInterface & pm)
{
wxArrayString pathList;
wxArrayString files;
@ -466,10 +474,12 @@ wxArrayString VSTEffectsModule::FindPlugins(PluginManagerInterface & pm)
return files;
}
bool VSTEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
const wxString & path, wxString &errMsg)
unsigned VSTEffectsModule::DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
{
bool error = false;
unsigned nFound = 0;
errMsg.clear();
// TODO: Fix this for external usage
const wxString &cmdpath = PlatformCompatibility::GetExecutablePath();
@ -620,7 +630,8 @@ bool VSTEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
if (!skip && cont)
{
valid = true;
pm.RegisterPlugin(this, &proc);
callback( this, &proc );
++nFound;
}
}
break;
@ -636,7 +647,7 @@ bool VSTEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
if (error)
errMsg = _("Could not load the library");
return valid;
return nFound;
}
bool VSTEffectsModule::IsPluginValid(const wxString & path, bool bFast)

View File

@ -391,10 +391,15 @@ public:
bool Initialize() override;
void Terminate() override;
bool PathsAreFiles() override { return true; }
wxString InstallPath() override;
bool AutoRegisterPlugins(PluginManagerInterface & pm) override;
wxArrayString FindPlugins(PluginManagerInterface & pm) override;
bool RegisterPlugin(PluginManagerInterface & pm,
const wxString & path, wxString &errMsg) override;
wxArrayString FindPluginPaths(PluginManagerInterface & pm) override;
unsigned DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
override;
bool IsPluginValid(const wxString & path, bool bFast) override;

View File

@ -158,7 +158,7 @@ bool AudioUnitEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
return true;
}
wxArrayString AudioUnitEffectsModule::FindPlugins(PluginManagerInterface & pm)
wxArrayString AudioUnitEffectsModule::FindPluginPaths(PluginManagerInterface & pm)
{
wxArrayString effects;
@ -171,9 +171,9 @@ wxArrayString AudioUnitEffectsModule::FindPlugins(PluginManagerInterface & pm)
return effects;
}
bool AudioUnitEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
const wxString & path,
wxString &errMsg)
unsigned AudioUnitEffectsModule::DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
{
errMsg.clear();
wxString name;
@ -181,7 +181,7 @@ bool AudioUnitEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
if (component == NULL)
{
errMsg = _("Could not find component");
return false;
return 0;
}
AudioUnitEffect effect(path, name, component);
@ -190,12 +190,11 @@ bool AudioUnitEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
// TODO: Is it worth it to discriminate all the ways SetHost might
// return false?
errMsg = _("Could not initialize component");
return false;
return 0;
}
pm.RegisterPlugin(this, &effect);
return true;
callback(this, &effect);
return 1;
}
bool AudioUnitEffectsModule::IsPluginValid(

View File

@ -243,10 +243,15 @@ public:
bool Initialize() override;
void Terminate() override;
bool PathsAreFiles() override { return false; }
wxString InstallPath() override { return {}; }
bool AutoRegisterPlugins(PluginManagerInterface & pm) override;
wxArrayString FindPlugins(PluginManagerInterface & pm) override;
bool RegisterPlugin(PluginManagerInterface & pm,
const wxString & path, wxString &errMsg) override;
wxArrayString FindPluginPaths(PluginManagerInterface & pm) override;
unsigned DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
override;
bool IsPluginValid(const wxString & path, bool bFast) override;

View File

@ -49,6 +49,7 @@ effects from this one class.
#include <wx/version.h>
#include "LadspaEffect.h" // This class's header file
#include "../../FileNames.h"
#include "../../Internat.h"
#include "../../ShuttleGui.h"
#include "../../widgets/valnum.h"
@ -154,6 +155,12 @@ void LadspaEffectsModule::Terminate()
return;
}
wxString LadspaEffectsModule::InstallPath()
{
// To do: better choice
return FileNames::PlugInDir();
}
bool LadspaEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
{
// Autoregister effects that we "think" are ones that have been shipped with
@ -171,7 +178,8 @@ bool LadspaEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
if (!pm.IsPluginRegistered(files[j]))
{
// No checking for error ?
RegisterPlugin(pm, files[j], ignoredErrMsg);
DiscoverPluginsAtPath(files[j], ignoredErrMsg,
PluginManagerInterface::DefaultRegistrationCallback);
}
}
}
@ -180,7 +188,7 @@ bool LadspaEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
return false;
}
wxArrayString LadspaEffectsModule::FindPlugins(PluginManagerInterface & pm)
wxArrayString LadspaEffectsModule::FindPluginPaths(PluginManagerInterface & pm)
{
wxArrayString pathList = GetSearchPaths();
wxArrayString files;
@ -205,9 +213,9 @@ wxArrayString LadspaEffectsModule::FindPlugins(PluginManagerInterface & pm)
return files;
}
bool LadspaEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
const wxString & path,
wxString &errMsg)
unsigned LadspaEffectsModule::DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
{
errMsg.clear();
// Since we now have builtin VST support, ignore the VST bridge as it
@ -215,7 +223,7 @@ bool LadspaEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
wxFileName ff(path);
if (ff.GetName().CmpNoCase(wxT("vst-bridge")) == 0) {
errMsg = _("Audacity no longer uses vst-bridge");
return false;
return 0;
}
// As a courtesy to some plug-ins that might be bridges to
@ -227,8 +235,8 @@ bool LadspaEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
wxString saveOldCWD = ff.GetCwd();
ff.SetCwd();
bool error = false;
int index = 0;
int nLoaded = 0;
LADSPA_Descriptor_Function mainFn = NULL;
wxDynamicLibrary lib;
if (lib.Load(path, wxDL_NOW)) {
@ -241,15 +249,16 @@ bool LadspaEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
for (data = mainFn(index); data; data = mainFn(++index)) {
LadspaEffect effect(path, index);
if (effect.SetHost(NULL)) {
pm.RegisterPlugin(this, &effect);
}
else {
// If pm.RegisterPlugin is skipped, be sure to report error
error = true;
++nLoaded;
callback( this, &effect );
}
else
errMsg = _("Could not load the library");
}
}
}
else
errMsg = _("Could not load the library");
if (lib.IsLoaded()) {
// PRL: I suspect Bug1257 -- Crash when enabling Amplio2 -- is the fault of a timing-
@ -263,10 +272,7 @@ bool LadspaEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
wxSetWorkingDirectory(saveOldCWD);
hadpath ? wxSetEnv(wxT("PATH"), envpath) : wxUnsetEnv(wxT("PATH"));
if (error)
errMsg = _("Could not load the library");
return index > 0;
return nLoaded;
}
bool LadspaEffectsModule::IsPluginValid(const wxString & path, bool bFast)

View File

@ -223,10 +223,15 @@ public:
bool Initialize() override;
void Terminate() override;
bool PathsAreFiles() override { return true; }
wxString InstallPath() override;
bool AutoRegisterPlugins(PluginManagerInterface & pm) override;
wxArrayString FindPlugins(PluginManagerInterface & pm) override;
bool RegisterPlugin(PluginManagerInterface & pm, const wxString & path,
wxString &errMsg) override;
wxArrayString FindPluginPaths(PluginManagerInterface & pm) override;
unsigned DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
override;
bool IsPluginValid(const wxString & path, bool bFast) override;

View File

@ -218,7 +218,7 @@ bool LV2EffectsModule::AutoRegisterPlugins(PluginManagerInterface & WXUNUSED(pm)
return false;
}
wxArrayString LV2EffectsModule::FindPlugins(PluginManagerInterface & WXUNUSED(pm))
wxArrayString LV2EffectsModule::FindPluginPaths(PluginManagerInterface & WXUNUSED(pm))
{
// Retrieve data about all LV2 plugins
const LilvPlugins *plugs = lilv_world_get_all_plugins(gWorld);
@ -242,8 +242,9 @@ wxArrayString LV2EffectsModule::FindPlugins(PluginManagerInterface & WXUNUSED(pm
return plugins;
}
bool LV2EffectsModule::RegisterPlugin(PluginManagerInterface & pm,
const wxString & path, wxString &errMsg)
unsigned LV2EffectsModule::DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
{
errMsg.clear();
const LilvPlugin *plug = GetPlugin(path);
@ -252,13 +253,13 @@ bool LV2EffectsModule::RegisterPlugin(PluginManagerInterface & pm,
LV2Effect effect(plug);
if (effect.SetHost(NULL))
{
pm.RegisterPlugin(this, &effect);
return true;
callback( this, &effect );
return 1;
}
}
errMsg = _("Could not load the library");
return false;
return 0;
}
bool LV2EffectsModule::IsPluginValid(const wxString & path, bool bFast)

View File

@ -88,10 +88,15 @@ public:
bool Initialize() override;
void Terminate() override;
bool PathsAreFiles() override { return false; }
wxString InstallPath() override { return {}; }
bool AutoRegisterPlugins(PluginManagerInterface & pm) override;
wxArrayString FindPlugins(PluginManagerInterface & pm) override;
bool RegisterPlugin(PluginManagerInterface & pm,
const wxString & path, wxString &errMsg) override;
wxArrayString FindPluginPaths(PluginManagerInterface & pm) override;
unsigned DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
override;
bool IsPluginValid(const wxString & path, bool bFast) override;

View File

@ -15,6 +15,7 @@
#include "Nyquist.h"
#include "LoadNyquist.h"
#include "../../FileNames.h"
// ============================================================================
// List of effects that ship with Audacity. These will be autoregistered.
@ -159,6 +160,11 @@ void NyquistEffectsModule::Terminate()
return;
}
wxString NyquistEffectsModule::InstallPath()
{
return FileNames::PlugInDir();
}
bool NyquistEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
{
// Autoregister effects that we "think" are ones that have been shipped with
@ -170,7 +176,8 @@ bool NyquistEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
if (!pm.IsPluginRegistered(NYQUIST_PROMPT_ID))
{
// No checking of error ?
RegisterPlugin(pm, NYQUIST_PROMPT_ID, ignoredErrMsg);
DiscoverPluginsAtPath(NYQUIST_PROMPT_ID, ignoredErrMsg,
PluginManagerInterface::DefaultRegistrationCallback);
}
for (size_t i = 0; i < WXSIZEOF(kShippedEffects); i++)
@ -182,7 +189,8 @@ bool NyquistEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
if (!pm.IsPluginRegistered(files[j]))
{
// No checking of error ?
RegisterPlugin(pm, files[j], ignoredErrMsg);
DiscoverPluginsAtPath(files[j], ignoredErrMsg,
PluginManagerInterface::DefaultRegistrationCallback);
}
}
}
@ -191,7 +199,7 @@ bool NyquistEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
return false;
}
wxArrayString NyquistEffectsModule::FindPlugins(PluginManagerInterface & pm)
wxArrayString NyquistEffectsModule::FindPluginPaths(PluginManagerInterface & pm)
{
wxArrayString pathList = NyquistEffect::GetNyquistSearchPath();
wxArrayString files;
@ -207,20 +215,20 @@ wxArrayString NyquistEffectsModule::FindPlugins(PluginManagerInterface & pm)
return files;
}
bool NyquistEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
const wxString & path,
wxString &errMsg)
unsigned NyquistEffectsModule::DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
{
errMsg.clear();
NyquistEffect effect(path);
if (effect.IsOk())
{
pm.RegisterPlugin(this, &effect);
return true;
callback(this, &effect);
return 1;
}
errMsg = effect.InitializationError();
return false;
return 0;
}
bool NyquistEffectsModule::IsPluginValid(const wxString & path, bool bFast)

View File

@ -38,10 +38,15 @@ public:
bool Initialize() override;
void Terminate() override;
bool PathsAreFiles() override { return true; }
wxString InstallPath() override;
bool AutoRegisterPlugins(PluginManagerInterface & pm) override;
wxArrayString FindPlugins(PluginManagerInterface & pm) override;
bool RegisterPlugin(PluginManagerInterface & pm,
const wxString & path, wxString &errMsg) override;
wxArrayString FindPluginPaths(PluginManagerInterface & pm) override;
unsigned DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
override;
bool IsPluginValid(const wxString & path, bool bFast) override;

View File

@ -122,7 +122,7 @@ bool VampEffectsModule::AutoRegisterPlugins(PluginManagerInterface & WXUNUSED(pm
return false;
}
wxArrayString VampEffectsModule::FindPlugins(PluginManagerInterface & WXUNUSED(pm))
wxArrayString VampEffectsModule::FindPluginPaths(PluginManagerInterface & WXUNUSED(pm))
{
wxArrayString names;
@ -199,8 +199,9 @@ wxArrayString VampEffectsModule::FindPlugins(PluginManagerInterface & WXUNUSED(p
return names;
}
bool VampEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
const wxString & path, wxString &errMsg)
unsigned VampEffectsModule::DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
{
errMsg.clear();
int output;
@ -210,13 +211,13 @@ bool VampEffectsModule::RegisterPlugin(PluginManagerInterface & pm,
if (vp)
{
VampEffect effect(std::move(vp), path, output, hasParameters);
pm.RegisterPlugin(this, &effect);
callback( this, &effect );
return true;
return 1;
}
errMsg = _("Could not load the library");
return false;
return 0;
}
bool VampEffectsModule::IsPluginValid(const wxString & path, bool bFast)

View File

@ -42,10 +42,15 @@ public:
bool Initialize() override;
void Terminate() override;
bool PathsAreFiles() override { return false; }
wxString InstallPath() override { return {}; }
bool AutoRegisterPlugins(PluginManagerInterface & pm) override;
wxArrayString FindPlugins(PluginManagerInterface & pm) override;
bool RegisterPlugin(PluginManagerInterface & pm,
const wxString & path, wxString &errMsg) override;
wxArrayString FindPluginPaths(PluginManagerInterface & pm) override;
unsigned DiscoverPluginsAtPath(
const wxString & path, wxString &errMsg,
const RegistrationCallback &callback)
override;
bool IsPluginValid(const wxString & path, bool bFast) override;