1 /********************************************************************** 2 3 Audacity: A Digital Audio Editor 4 5 PluginManager.h 6 7 Leland Lucius 8 9 **********************************************************************/ 10 11 #ifndef __AUDACITY_PLUGINMANAGER_H__ 12 #define __AUDACITY_PLUGINMANAGER_H__ 13 14 #include <wx/defs.h> 15 16 #include "wxArrayStringEx.h" 17 #include <map> 18 #include <memory> 19 20 #include "EffectInterface.h" 21 #include "PluginInterface.h" 22 23 class wxArrayString; 24 class FileConfig; 25 26 /////////////////////////////////////////////////////////////////////////////// 27 // 28 // PluginDescriptor 29 // 30 /////////////////////////////////////////////////////////////////////////////// 31 32 typedef enum : unsigned { 33 PluginTypeNone = 0, // 2.1.0 placeholder entries...not used by 2.1.1 or greater 34 PluginTypeStub =1, // Used for plugins that have not yet been registered 35 PluginTypeEffect =1<<1, 36 PluginTypeAudacityCommand=1<<2, 37 PluginTypeExporter=1<<3, 38 PluginTypeImporter=1<<4, 39 PluginTypeModule=1<<5, 40 } PluginType; 41 42 // TODO: Convert this to multiple derived classes 43 class AUDACITY_DLL_API PluginDescriptor 44 { 45 public: 46 PluginDescriptor(); 47 PluginDescriptor &operator =(PluginDescriptor &&); 48 virtual ~PluginDescriptor(); 49 50 bool IsInstantiated() const; 51 52 PluginType GetPluginType() const; 53 54 // All plugins 55 56 // These return untranslated strings 57 const wxString & GetID() const; 58 const wxString & GetProviderID() const; 59 const PluginPath & GetPath() const; 60 const ComponentInterfaceSymbol & GetSymbol() const; 61 62 wxString GetUntranslatedVersion() const; 63 // There is no translated version 64 65 wxString GetVendor() const; 66 67 bool IsEnabled() const; 68 bool IsValid() const; 69 70 void SetEnabled(bool enable); 71 void SetValid(bool valid); 72 73 // Effect plugins only 74 75 // Internal string only, no translated counterpart! 76 // (Use Effect::GetFamilyName instead) 77 // This string persists in configuration files 78 // So config compatibility will break if it is changed across Audacity versions 79 wxString GetEffectFamily() const; 80 81 EffectType GetEffectType() const; 82 bool IsEffectDefault() const; 83 bool IsEffectInteractive() const; 84 bool IsEffectLegacy() const; 85 bool IsEffectRealtime() const; 86 bool IsEffectAutomatable() const; 87 88 // Importer plugins only 89 90 const wxString & GetImporterIdentifier() const; 91 const TranslatableString & GetImporterFilterDescription() const; 92 const FileExtensions & GetImporterExtensions() const; 93 94 private: 95 friend class PluginManager; 96 97 ComponentInterface *GetInstance(); 98 void SetInstance(std::unique_ptr<ComponentInterface> instance); 99 100 void SetPluginType(PluginType type); 101 102 // These should be passed an untranslated value 103 void SetID(const PluginID & ID); 104 void SetProviderID(const PluginID & providerID); 105 void SetPath(const PluginPath & path); 106 void SetSymbol(const ComponentInterfaceSymbol & symbol); 107 108 // These should be passed an untranslated value wrapped in XO() so 109 // the value will still be extracted for translation 110 void SetVersion(const wxString & version); 111 void SetVendor(const wxString & vendor); 112 113 // "family" should be an untranslated string wrapped in wxT() 114 void SetEffectFamily(const wxString & family); 115 void SetEffectType(EffectType type); 116 void SetEffectDefault(bool dflt); 117 void SetEffectInteractive(bool interactive); 118 void SetEffectLegacy(bool legacy); 119 void SetEffectRealtime(bool realtime); 120 void SetEffectAutomatable(bool automatable); 121 122 void SetImporterIdentifier(const wxString & identifier); 123 void SetImporterFilterDescription(const TranslatableString & filterDesc); 124 void SetImporterExtensions(FileExtensions extensions); 125 126 // Common 127 128 // Among other purposes, PluginDescriptor acts as the resource handle, 129 // or smart pointer, to a resource created in a plugin library, and is responsible 130 // for a cleanup of this pointer. 131 std::unique_ptr<ComponentInterface> muInstance; // may be null for a module 132 ComponentInterface *mInstance; 133 134 PluginType mPluginType; 135 136 wxString mID; 137 PluginPath mPath; 138 ComponentInterfaceSymbol mSymbol; 139 wxString mVersion; 140 wxString mVendor; 141 wxString mProviderID; 142 bool mEnabled; 143 bool mValid; 144 145 // Effects 146 147 wxString mEffectFamily; 148 EffectType mEffectType; 149 bool mEffectInteractive; 150 bool mEffectDefault; 151 bool mEffectLegacy; 152 bool mEffectRealtime; 153 bool mEffectAutomatable; 154 155 // Importers 156 157 wxString mImporterIdentifier; 158 FileExtensions mImporterExtensions; 159 }; 160 161 /////////////////////////////////////////////////////////////////////////////// 162 // 163 // PluginManager 164 // 165 /////////////////////////////////////////////////////////////////////////////// 166 167 typedef std::map<PluginID, PluginDescriptor> PluginMap; 168 169 typedef wxArrayString PluginIDs; 170 171 class PluginRegistrationDialog; 172 173 class AUDACITY_DLL_API PluginManager final : public PluginManagerInterface 174 { 175 public: 176 177 RegistryPath GetPluginEnabledSetting( const PluginID &ID ) const; 178 RegistryPath GetPluginEnabledSetting( const PluginDescriptor &desc ) const; 179 180 // PluginManagerInterface implementation 181 182 bool IsPluginRegistered( 183 const PluginPath &path, const TranslatableString *pSymbol) override; 184 185 const PluginID & RegisterPlugin(ModuleInterface *module) override; 186 const PluginID & RegisterPlugin(ModuleInterface *provider, ComponentInterface *command); 187 const PluginID & RegisterPlugin(ModuleInterface *provider, EffectDefinitionInterface *effect, int type) override; 188 189 void FindFilesInPathList(const wxString & pattern, 190 const FilePaths & pathList, 191 FilePaths & files, 192 bool directories = false) override; 193 194 bool HasSharedConfigGroup(const PluginID & ID, const RegistryPath & group) /* not override */; 195 bool GetSharedConfigSubgroups(const PluginID & ID, const RegistryPath & group, RegistryPaths &subgroups) override; 196 197 bool GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, wxString & value, const wxString & defval = _T("")) override; 198 bool GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, int & value, int defval = 0) override; 199 bool GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, bool & value, bool defval = false) override; 200 bool GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, float & value, float defval = 0.0) override; 201 bool GetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, double & value, double defval = 0.0) override; 202 203 bool SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const wxString & value) override; 204 bool SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const int & value) override; 205 bool SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const bool & value) override; 206 bool SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const float & value) override; 207 bool SetSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const double & value) override; 208 209 bool RemoveSharedConfigSubgroup(const PluginID & ID, const RegistryPath & group) override; 210 bool RemoveSharedConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key) override; 211 212 bool HasPrivateConfigGroup(const PluginID & ID, const RegistryPath & group) /* not override */; 213 bool GetPrivateConfigSubgroups(const PluginID & ID, const RegistryPath & group, RegistryPaths &subgroups) override; 214 215 bool GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, wxString & value, const wxString & defval = _T("")) override; 216 bool GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, int & value, int defval = 0) override; 217 bool GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, bool & value, bool defval = false) override; 218 bool GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, float & value, float defval = 0.0) override; 219 bool GetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, double & value, double defval = 0.0) override; 220 221 bool SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const wxString & value) override; 222 bool SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const int & value) override; 223 bool SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const bool & value) override; 224 bool SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const float & value) override; 225 bool SetPrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key, const double & value) override; 226 227 bool RemovePrivateConfigSubgroup(const PluginID & ID, const RegistryPath & group) override; 228 bool RemovePrivateConfig(const PluginID & ID, const RegistryPath & group, const RegistryPath & key) override; 229 230 // PluginManager implementation 231 232 void Initialize(); 233 void Terminate(); 234 235 bool DropFile(const wxString &fileName); 236 237 static PluginManager & Get(); 238 239 static PluginID GetID(ModuleInterface *module); 240 static PluginID GetID(ComponentInterface *command); 241 static PluginID GetID(EffectDefinitionInterface *effect); 242 243 // This string persists in configuration files 244 // So config compatibility will break if it is changed across Audacity versions 245 static wxString GetPluginTypeString(PluginType type); 246 247 int GetPluginCount(PluginType type); 248 const PluginDescriptor *GetPlugin(const PluginID & ID) const; 249 250 //! @name iteration over plugins of certain types, supporting range-for syntax 251 //! @{ 252 class Iterator { 253 public: 254 //! Iterates all, even disabled 255 explicit Iterator(PluginManager &manager); 256 //! Iterates only enabled and matching plugins, with family enabled too if an effect 257 Iterator(PluginManager &manager, 258 int pluginType //!< bitwise or of values in PluginType 259 ); 260 //! Iterates only enabled and matching effects, with family enabled too 261 Iterator(PluginManager &manager, EffectType type); 262 bool operator != (int) const { 263 return mIterator != mPm.mPlugins.end(); 264 } 265 Iterator &operator ++ (); 266 auto &operator *() const { return mIterator->second; } 267 private: 268 void Advance(bool incrementing); 269 const PluginManager &mPm; 270 PluginMap::iterator mIterator; 271 EffectType mEffectType{ EffectTypeNone }; 272 int mPluginType{ PluginTypeNone }; 273 }; 274 struct Range { 275 Iterator first; beginRange276 Iterator begin() const { return first; } endRange277 int end() const { return 0; } 278 }; 279 AllPlugins()280 Range AllPlugins() { return { Iterator{ *this } }; } PluginsOfType(int type)281 Range PluginsOfType(int type) { return { Iterator{ *this, type } }; } EffectsOfType(EffectType type)282 Range EffectsOfType(EffectType type) { return { Iterator{ *this, type } }; } 283 //! @} 284 285 bool IsPluginEnabled(const PluginID & ID); 286 void EnablePlugin(const PluginID & ID, bool enable); 287 288 const ComponentInterfaceSymbol & GetSymbol(const PluginID & ID); 289 ComponentInterface *GetInstance(const PluginID & ID); 290 291 void CheckForUpdates(bool bFast = false); 292 293 //! Used only by Nyquist Workbench module 294 const PluginID & RegisterPlugin( 295 std::unique_ptr<EffectDefinitionInterface> effect, PluginType type ); 296 void UnregisterPlugin(const PluginID & ID); 297 298 //! Load from preferences 299 void Load(); 300 //! Save to preferences 301 void Save(); 302 303 private: 304 // private! Use Get() 305 PluginManager(); 306 ~PluginManager(); 307 308 void LoadGroup(FileConfig *pRegistry, PluginType type); 309 void SaveGroup(FileConfig *pRegistry, PluginType type); 310 311 PluginDescriptor & CreatePlugin(const PluginID & id, ComponentInterface *ident, PluginType type); 312 313 FileConfig *GetSettings(); 314 315 bool HasGroup(const RegistryPath & group); 316 bool GetSubgroups(const RegistryPath & group, RegistryPaths & subgroups); 317 318 bool GetConfig(const RegistryPath & key, wxString & value, const wxString & defval = L""); 319 bool GetConfig(const RegistryPath & key, int & value, int defval = 0); 320 bool GetConfig(const RegistryPath & key, bool & value, bool defval = false); 321 bool GetConfig(const RegistryPath & key, float & value, float defval = 0.0); 322 bool GetConfig(const RegistryPath & key, double & value, double defval = 0.0); 323 324 bool SetConfig(const RegistryPath & key, const wxString & value); 325 bool SetConfig(const RegistryPath & key, const int & value); 326 bool SetConfig(const RegistryPath & key, const bool & value); 327 bool SetConfig(const RegistryPath & key, const float & value); 328 bool SetConfig(const RegistryPath & key, const double & value); 329 330 /* Return values are keys for lookup in a config file */ 331 RegistryPath SettingsPath(const PluginID & ID, bool shared); 332 RegistryPath SharedGroup(const PluginID & ID, const RegistryPath & group); 333 RegistryPath SharedKey(const PluginID & ID, const RegistryPath & group, const RegistryPath & key); 334 RegistryPath PrivateGroup(const PluginID & ID, const RegistryPath & group); 335 RegistryPath PrivateKey(const PluginID & ID, const RegistryPath & group, const RegistryPath & key); 336 337 // The PluginID must be kept unique. Since the wxFileConfig class does not preserve 338 // case, we use base64 encoding. 339 wxString ConvertID(const PluginID & ID); 340 wxString b64encode(const void *in, int len); 341 int b64decode(const wxString &in, void *out); 342 343 private: 344 friend std::default_delete<PluginManager>; 345 static std::unique_ptr<PluginManager> mInstance; 346 347 bool IsDirty(); 348 void SetDirty(bool dirty = true); 349 std::unique_ptr<FileConfig> mSettings; 350 351 bool mDirty; 352 int mCurrentIndex; 353 354 PluginMap mPlugins; 355 }; 356 357 // Defining these special names in the low-level PluginManager.h 358 // is unfortunate 359 // Internal name should be stable across versions 360 #define NYQUIST_PROMPT_ID wxT("Nyquist Prompt") 361 // User-visible name might change in later versions 362 #define NYQUIST_PROMPT_NAME XO("Nyquist Prompt") 363 364 #endif /* __AUDACITY_PLUGINMANAGER_H__ */ 365