forked from Sneeds-Feed-and-Seed/sneedacity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPluginManager.h
366 lines (279 loc) · 14.3 KB
/
PluginManager.h
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
/**********************************************************************
Sneedacity: A Digital Audio Editor
PluginManager.h
Leland Lucius
**********************************************************************/
#ifndef __SNEEDACITY_PLUGINMANAGER_H__
#define __SNEEDACITY_PLUGINMANAGER_H__
#include <wx/defs.h>
#include "wxArrayStringEx.h"
#include <map>
#include <memory>
#include "sneedacity/EffectInterface.h"
#include "sneedacity/ImporterInterface.h"
#include "sneedacity/PluginInterface.h"
class wxArrayString;
class FileConfig;
///////////////////////////////////////////////////////////////////////////////
//
// PluginDescriptor
//
///////////////////////////////////////////////////////////////////////////////
typedef enum : unsigned {
PluginTypeNone = 0, // 2.1.0 placeholder entries...not used by 2.1.1 or greater
PluginTypeStub =1, // Used for plugins that have not yet been registered
PluginTypeEffect =1<<1,
PluginTypeSneedacityCommand=1<<2,
PluginTypeExporter=1<<3,
PluginTypeImporter=1<<4,
PluginTypeModule=1<<5,
} PluginType;
// TODO: Convert this to multiple derived classes
class SNEEDACITY_DLL_API PluginDescriptor
{
public:
PluginDescriptor();
PluginDescriptor &operator =(PluginDescriptor &&);
virtual ~PluginDescriptor();
bool IsInstantiated() const;
PluginType GetPluginType() const;
// All plugins
// These return untranslated strings
const wxString & GetID() const;
const wxString & GetProviderID() const;
const PluginPath & GetPath() const;
const ComponentInterfaceSymbol & GetSymbol() const;
wxString GetUntranslatedVersion() const;
// There is no translated version
wxString GetVendor() const;
bool IsEnabled() const;
bool IsValid() const;
void SetEnabled(bool enable);
void SetValid(bool valid);
// Effect plugins only
// Internal string only, no translated counterpart!
// (Use Effect::GetFamilyName instead)
// This string persists in configuration files
// So config compatibility will break if it is changed across Sneedacity versions
wxString GetEffectFamily() const;
EffectType GetEffectType() const;
bool IsEffectDefault() const;
bool IsEffectInteractive() const;
bool IsEffectLegacy() const;
bool IsEffectRealtime() const;
bool IsEffectAutomatable() const;
// Importer plugins only
const wxString & GetImporterIdentifier() const;
const TranslatableString & GetImporterFilterDescription() const;
const FileExtensions & GetImporterExtensions() const;
private:
friend class PluginManager;
ComponentInterface *GetInstance();
void SetInstance(std::unique_ptr<ComponentInterface> instance);
void SetPluginType(PluginType type);
// These should be passed an untranslated value
void SetID(const PluginID & ID);
void SetProviderID(const PluginID & providerID);
void SetPath(const PluginPath & path);
void SetSymbol(const ComponentInterfaceSymbol & symbol);
// These should be passed an untranslated value wrapped in XO() so
// the value will still be extracted for translation
void SetVersion(const wxString & version);
void SetVendor(const wxString & vendor);
// "family" should be an untranslated string wrapped in wxT()
void SetEffectFamily(const wxString & family);
void SetEffectType(EffectType type);
void SetEffectDefault(bool dflt);
void SetEffectInteractive(bool interactive);
void SetEffectLegacy(bool legacy);
void SetEffectRealtime(bool realtime);
void SetEffectAutomatable(bool automatable);
void SetImporterIdentifier(const wxString & identifier);
void SetImporterFilterDescription(const TranslatableString & filterDesc);
void SetImporterExtensions(FileExtensions extensions);
// Common
// Among other purposes, PluginDescriptor acts as the resource handle,
// or smart pointer, to a resource created in a plugin library, and is responsible
// for a cleanup of this pointer.
std::unique_ptr<ComponentInterface> muInstance; // may be null for a module
ComponentInterface *mInstance;
PluginType mPluginType;
wxString mID;
PluginPath mPath;
ComponentInterfaceSymbol mSymbol;
wxString mVersion;
wxString mVendor;
wxString mProviderID;
bool mEnabled;
bool mValid;
// Effects
wxString mEffectFamily;
EffectType mEffectType;
bool mEffectInteractive;
bool mEffectDefault;
bool mEffectLegacy;
bool mEffectRealtime;
bool mEffectAutomatable;
// Importers
wxString mImporterIdentifier;
FileExtensions mImporterExtensions;
};
///////////////////////////////////////////////////////////////////////////////
//
// PluginManager
//
///////////////////////////////////////////////////////////////////////////////
typedef std::map<PluginID, PluginDescriptor> PluginMap;
typedef wxArrayString PluginIDs;
class PluginRegistrationDialog;
class SNEEDACITY_DLL_API PluginManager final : public PluginManagerInterface
{
public:
RegistryPath GetPluginEnabledSetting( const PluginID &ID ) const;
RegistryPath GetPluginEnabledSetting( const PluginDescriptor &desc ) const;
// PluginManagerInterface implementation
bool IsPluginRegistered(
const PluginPath &path, const TranslatableString *pSymbol) override;
const PluginID & RegisterPlugin(ModuleInterface *module) override;
const PluginID & RegisterPlugin(ModuleInterface *provider, ComponentInterface *command);
const PluginID & RegisterPlugin(ModuleInterface *provider, EffectDefinitionInterface *effect, int type) override;
const PluginID & RegisterPlugin(ModuleInterface *provider, ImporterInterface *importer) override;
void FindFilesInPathList(const wxString & pattern,
const FilePaths & pathList,
FilePaths & files,
bool directories = false) override;
bool HasSharedConfigGroup(const PluginID & ID, const RegistryPath & group) /* not override */;
bool GetSharedConfigSubgroups(const PluginID & ID, const RegistryPath & group, RegistryPaths &subgroups) override;
bool GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, wxString & value, const wxString & defval = _T("")) override;
bool GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, int & value, int defval = 0) override;
bool GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, bool & value, bool defval = false) override;
bool GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, float & value, float defval = 0.0) override;
bool GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, double & value, double defval = 0.0) override;
bool SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const wxString & value) override;
bool SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const int & value) override;
bool SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const bool & value) override;
bool SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const float & value) override;
bool SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const double & value) override;
bool RemoveSharedConfigSubgroup(const PluginID & ID, const RegistryPath & group) override;
bool RemoveSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key) override;
bool HasPrivateConfigGroup(const PluginID & ID, const RegistryPath & group) /* not override */;
bool GetPrivateConfigSubgroups(const PluginID & ID, const RegistryPath & group, RegistryPaths &subgroups) override;
bool GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, wxString & value, const wxString & defval = _T("")) override;
bool GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, int & value, int defval = 0) override;
bool GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, bool & value, bool defval = false) override;
bool GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, float & value, float defval = 0.0) override;
bool GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, double & value, double defval = 0.0) override;
bool SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const wxString & value) override;
bool SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const int & value) override;
bool SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const bool & value) override;
bool SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const float & value) override;
bool SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const double & value) override;
bool RemovePrivateConfigSubgroup(const PluginID & ID, const RegistryPath & group) override;
bool RemovePrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key) override;
// PluginManager implementation
void Initialize();
void Terminate();
bool DropFile(const wxString &fileName);
static PluginManager & Get();
static PluginID GetID(ComponentInterface *command);
static PluginID GetID(EffectDefinitionInterface *effect);
static PluginID GetID(ImporterInterface *importer);
// This string persists in configuration files
// So config compatibility will break if it is changed across Sneedacity versions
static wxString GetPluginTypeString(PluginType type);
int GetPluginCount(PluginType type);
const PluginDescriptor *GetPlugin(const PluginID & ID) const;
//! @name iteration over plugins of certain types, supporting range-for syntax
//! @{
class Iterator {
public:
//! Iterates all, even disabled
explicit Iterator(PluginManager &manager);
//! Iterates only enabled and matching plugins, with family enabled too if an effect
Iterator(PluginManager &manager,
int pluginType //!< bitwise or of values in PluginType
);
//! Iterates only enabled and matching effects, with family enabled too
Iterator(PluginManager &manager, EffectType type);
bool operator != (int) const {
return mIterator != mPm.mPlugins.end();
}
Iterator &operator ++ ();
auto &operator *() const { return mIterator->second; }
private:
void Advance(bool incrementing);
const PluginManager &mPm;
PluginMap::iterator mIterator;
EffectType mEffectType{ EffectTypeNone };
int mPluginType{ PluginTypeNone };
};
struct Range {
Iterator first;
Iterator begin() const { return first; }
int end() const { return 0; }
};
Range AllPlugins() { return { Iterator{ *this } }; }
Range PluginsOfType(int type) { return { Iterator{ *this, type } }; }
Range EffectsOfType(EffectType type) { return { Iterator{ *this, type } }; }
//! @}
bool IsPluginEnabled(const PluginID & ID);
void EnablePlugin(const PluginID & ID, bool enable);
const ComponentInterfaceSymbol & GetSymbol(const PluginID & ID);
ComponentInterface *GetInstance(const PluginID & ID);
void CheckForUpdates(bool bFast = false);
//! Used only by Nyquist Workbench module
const PluginID & RegisterPlugin(
std::unique_ptr<EffectDefinitionInterface> effect, PluginType type );
void UnregisterPlugin(const PluginID & ID);
//! Load from preferences
void Load();
//! Save to preferences
void Save();
private:
// private! Use Get()
PluginManager();
~PluginManager();
void LoadGroup(FileConfig *pRegistry, PluginType type);
void SaveGroup(FileConfig *pRegistry, PluginType type);
PluginDescriptor & CreatePlugin(const PluginID & id, ComponentInterface *ident, PluginType type);
FileConfig *GetSettings();
bool HasGroup(const RegistryPath & group);
bool GetSubgroups(const RegistryPath & group, RegistryPaths & subgroups);
bool GetConfig(const RegistryPath & key, wxString & value, const wxString & defval = L"");
bool GetConfig(const RegistryPath & key, int & value, int defval = 0);
bool GetConfig(const RegistryPath & key, bool & value, bool defval = false);
bool GetConfig(const RegistryPath & key, float & value, float defval = 0.0);
bool GetConfig(const RegistryPath & key, double & value, double defval = 0.0);
bool SetConfig(const RegistryPath & key, const wxString & value);
bool SetConfig(const RegistryPath & key, const int & value);
bool SetConfig(const RegistryPath & key, const bool & value);
bool SetConfig(const RegistryPath & key, const float & value);
bool SetConfig(const RegistryPath & key, const double & value);
/* Return values are keys for lookup in a config file */
RegistryPath SettingsPath(const PluginID & ID, bool shared);
RegistryPath SharedGroup(const PluginID & ID, const RegistryPath & group);
RegistryPath SharedKey(const PluginID & ID, const RegistryPath & group, const RegistryPath & key);
RegistryPath PrivateGroup(const PluginID & ID, const RegistryPath & group);
RegistryPath PrivateKey(const PluginID & ID, const RegistryPath & group, const RegistryPath & key);
// The PluginID must be kept unique. Since the wxFileConfig class does not preserve
// case, we use base64 encoding.
wxString ConvertID(const PluginID & ID);
wxString b64encode(const void *in, int len);
int b64decode(const wxString &in, void *out);
private:
friend std::default_delete<PluginManager>;
static std::unique_ptr<PluginManager> mInstance;
bool IsDirty();
void SetDirty(bool dirty = true);
std::unique_ptr<FileConfig> mSettings;
bool mDirty;
int mCurrentIndex;
PluginMap mPlugins;
};
// Defining these special names in the low-level PluginManager.h
// is unfortunate
// Internal name should be stable across versions
#define NYQUIST_PROMPT_ID wxT("Nyquist Prompt")
// User-visible name might change in later versions
#define NYQUIST_PROMPT_NAME XO("Nyquist Prompt")
#endif /* __SNEEDACITY_PLUGINMANAGER_H__ */