1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
/**********************************************************************
Audacity: A Digital Audio Editor
ModuleManager.h
Dominic Mazzoni
James Crook
**********************************************************************/
#ifndef __AUDACITY_MODULEMANAGER_H__
#define __AUDACITY_MODULEMANAGER_H__
#include "IteratorX.h"
#include <functional>
#include <map>
#include <memory>
#include <vector>
#include <wx/string.h>
#include "Identifier.h"
class wxArrayString;
class wxDynamicLibrary;
class ComponentInterface;
class PluginProvider;
class wxWindow;
using PluginID = wxString;
class TranslatableString;
//
// Module Manager
//
// wxPluginManager would be MUCH better, but it's an "undocumented" framework.
//
#include "ModuleConstants.h"
typedef int (*fnModuleDispatch)(ModuleDispatchTypes type);
class Module
{
public:
Module(const FilePath & name);
virtual ~Module();
void ShowLoadFailureError(const wxString &Error);
bool Load(wxString &deferredErrorMessage);
void Unload();
bool HasDispatch() { return mDispatch != NULL; };
int Dispatch(ModuleDispatchTypes type);
void * GetSymbol(const wxString &name);
const FilePath &GetName() const { return mName; }
private:
const FilePath mName;
std::unique_ptr<wxDynamicLibrary> mLib;
fnModuleDispatch mDispatch;
};
class MODULE_MANAGER_API PluginProviderUniqueHandle final
{
std::unique_ptr<PluginProvider> mPtr;
public:
PluginProviderUniqueHandle() = default;
explicit PluginProviderUniqueHandle(std::unique_ptr<PluginProvider> ptr) : mPtr(std::move(ptr)) { }
~PluginProviderUniqueHandle();
PluginProviderUniqueHandle(PluginProviderUniqueHandle&&) = default;
PluginProviderUniqueHandle& operator=(PluginProviderUniqueHandle&&) = default;
PluginProviderUniqueHandle(const PluginProviderUniqueHandle&) = delete;
PluginProviderUniqueHandle& operator=(const PluginProviderUniqueHandle&) = delete;
PluginProvider* get() noexcept { return mPtr.get(); }
const PluginProvider* get() const noexcept { return mPtr.get(); }
PluginProvider* operator->() noexcept { return mPtr.get(); }
const PluginProvider* operator->() const noexcept { return mPtr.get(); }
};
using PluginProviderHandlesMap = std::map<wxString, PluginProviderUniqueHandle>;
class MODULE_MANAGER_API ModuleManager final
{
public:
// -------------------------------------------------------------------------
// ModuleManager implementation
// -------------------------------------------------------------------------
static ModuleManager & Get();
// This string persists in configuration files
// So config compatibility will break if it is changed across Audacity versions
static wxString GetPluginTypeString();
static PluginID GetID(const PluginProvider *provider);
private:
static void FindModules(FilePaths &files);
using DelayedErrors =
std::vector< std::pair< std::unique_ptr<Module>, wxString > >;
static void TryLoadModules(
const FilePaths &files, FilePaths &decided, DelayedErrors &errors);
public:
void Initialize();
int Dispatch(ModuleDispatchTypes type);
// PluginManager use
// Can be called before Initialize()
bool DiscoverProviders();
// Supports range-for iteration
auto Providers() const
{ return make_iterator_range(mProviders.cbegin(), mProviders.cend()); }
auto Providers()
{ return make_iterator_range(mProviders.begin(), mProviders.end()); }
bool RegisterEffectPlugin(const PluginID & provider, const PluginPath & path,
TranslatableString &errMsg);
PluginProvider *CreateProviderInstance(
const PluginID & provider, const PluginPath & path);
std::unique_ptr<ComponentInterface>
LoadPlugin(const PluginID & provider, const PluginPath & path);
bool IsProviderValid(const PluginID & provider, const PluginPath & path);
bool CheckPluginExist(const PluginID& providerId, const PluginPath& path);
private:
// I'm a singleton class
ModuleManager();
~ModuleManager();
ModuleManager(const ModuleManager&) = delete;
ModuleManager &operator=(const ModuleManager&) = delete;
void InitializeBuiltins();
friend std::unique_ptr<ModuleManager> std::make_unique<ModuleManager>();
friend std::default_delete<ModuleManager>;
static std::unique_ptr<ModuleManager> mInstance;
// Providers can each report availability of any number of Plug-Ins
// identified by "paths", and are also factories of ComponentInterface
// objects for each path
PluginProviderHandlesMap mProviders;
// Other libraries that receive notifications of events described by
// ModuleDispatchTypes:
std::vector<std::unique_ptr<Module>> mModules;
};
// ----------------------------------------------------------------------------
// A factory of PluginProvider objects
// ----------------------------------------------------------------------------
using PluginProviderFactory = std::unique_ptr<PluginProvider> (*)();
MODULE_MANAGER_API
void RegisterProviderFactory(PluginProviderFactory factory);
MODULE_MANAGER_API
void UnregisterProviderFactory(PluginProviderFactory factory);
// Guarantee the registry exists before any registrations, so it will
// be destroyed only after the un-registrations
static struct Init{
Init() { RegisterProviderFactory(nullptr); } } sInitBuiltinModules;
#endif /* __AUDACITY_MODULEMANAGER_H__ */
|