Audacity 3.2.0
Public Member Functions | Static Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
ModuleManager Class Referencefinal

#include <ModuleManager.h>

Collaboration diagram for ModuleManager:
[legend]

Public Member Functions

void Initialize ()
 
int Dispatch (ModuleDispatchTypes type)
 
bool DiscoverProviders ()
 
auto Providers () const
 
auto Providers ()
 
bool RegisterEffectPlugin (const PluginID &provider, const PluginPath &path, TranslatableString &errMsg)
 
PluginProviderCreateProviderInstance (const PluginID &provider, const PluginPath &path)
 
std::unique_ptr< ComponentInterfaceLoadPlugin (const PluginID &provider, const PluginPath &path)
 
bool IsProviderValid (const PluginID &provider, const PluginPath &path)
 
bool CheckPluginExist (const PluginID &providerId, const PluginPath &path)
 

Static Public Member Functions

static ModuleManagerGet ()
 
static wxString GetPluginTypeString ()
 
static PluginID GetID (PluginProvider *provider)
 

Private Types

using DelayedErrors = std::vector< std::pair< std::unique_ptr< Module >, wxString > >
 

Private Member Functions

 ModuleManager ()
 
 ~ModuleManager ()
 
 ModuleManager (const ModuleManager &)=delete
 
ModuleManageroperator= (const ModuleManager &)=delete
 
void InitializeBuiltins ()
 

Static Private Member Functions

static void FindModules (FilePaths &files)
 
static void TryLoadModules (const FilePaths &files, FilePaths &decided, DelayedErrors &errors)
 

Private Attributes

PluginProviderHandlesMap mProviders
 
std::vector< std::unique_ptr< Module > > mModules
 

Static Private Attributes

static std::unique_ptr< ModuleManagermInstance {}
 

Friends

std::unique_ptr< ModuleManagerstd::make_unique ()
 

Detailed Description

Definition at line 85 of file ModuleManager.h.

Member Typedef Documentation

◆ DelayedErrors

using ModuleManager::DelayedErrors = std::vector< std::pair< std::unique_ptr<Module>, wxString > >
private

Definition at line 103 of file ModuleManager.h.

Constructor & Destructor Documentation

◆ ModuleManager() [1/2]

ModuleManager::ModuleManager ( )
private

Definition at line 204 of file ModuleManager.cpp.

205{
206}

◆ ~ModuleManager()

ModuleManager::~ModuleManager ( )
private

Definition at line 208 of file ModuleManager.cpp.

209{
210 mProviders.clear();
211 builtinProviderList().clear();
212}
PluginProviderHandlesMap mProviders
BuiltinProviderList & builtinProviderList()

References anonymous_namespace{ModuleManager.cpp}::builtinProviderList(), and mProviders.

Here is the call graph for this function:

◆ ModuleManager() [2/2]

ModuleManager::ModuleManager ( const ModuleManager )
privatedelete

Member Function Documentation

◆ CheckPluginExist()

bool ModuleManager::CheckPluginExist ( const PluginID providerId,
const PluginPath path 
)

Definition at line 527 of file ModuleManager.cpp.

528{
529 if(mProviders.find(providerId) == mProviders.end())
530 return false;
531
532 return mProviders[providerId]->CheckPluginExist(path);
533}

References mProviders.

Referenced by PluginManager::InitializePlugins().

Here is the caller graph for this function:

◆ CreateProviderInstance()

PluginProvider * ModuleManager::CreateProviderInstance ( const PluginID provider,
const PluginPath path 
)

Definition at line 506 of file ModuleManager.cpp.

508{
509 if (path.empty() && mProviders.find(providerID) != mProviders.end())
510 {
511 return mProviders[providerID].get();
512 }
513
514 return nullptr;
515}

References mProviders.

Referenced by PluginManager::IsPluginAvailable(), and PluginManager::Load().

Here is the caller graph for this function:

◆ DiscoverProviders()

bool ModuleManager::DiscoverProviders ( )

Definition at line 439 of file ModuleManager.cpp.

440{
442
443// The commented out code loads modules whether or not they are enabled.
444// none of our modules is a 'provider' of effects, so this code commented out.
445#if 0
446 FilePaths provList;
447 FilePaths pathList;
448
449 // Code from LoadLadspa that might be useful in load modules.
450 wxString pathVar = wxString::FromUTF8(getenv("AUDACITY_MODULES_PATH"));
451
452 if (!pathVar.empty())
453 {
454 FileNames::AddMultiPathsToPathList(pathVar, pathList);
455 }
456 else
457 {
459 }
460
461#if defined(__WXMSW__)
462 FileNames::FindFilesInPathList(wxT("*.dll"), pathList, provList);
463#elif defined(__WXMAC__)
464 FileNames::FindFilesInPathList(wxT("*.dylib"), pathList, provList);
465#else
466 FileNames::FindFilesInPathList(wxT("*.so"), pathList, provList);
467#endif
468
469 for ( const auto &path : provList )
470 LoadModule(path);
471#endif
472
473 return true;
474}
wxT("CloseDown"))
void InitializeBuiltins()
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
FILES_API void AddUniquePathToPathList(const FilePath &path, FilePaths &pathList)
FILES_API void FindFilesInPathList(const wxString &pattern, const FilePaths &pathList, FilePaths &results, int flags=wxDIR_FILES)
FILES_API void AddMultiPathsToPathList(const wxString &multiPathString, FilePaths &pathList)
FILES_API FilePath ModulesDir()

References FileNames::AddMultiPathsToPathList(), FileNames::AddUniquePathToPathList(), FileNames::FindFilesInPathList(), InitializeBuiltins(), FileNames::ModulesDir(), and wxT().

Here is the call graph for this function:

◆ Dispatch()

int ModuleManager::Dispatch ( ModuleDispatchTypes  type)

Definition at line 379 of file ModuleManager.cpp.

380{
381 for (const auto &module: mModules) {
382 module->Dispatch(type);
383 }
384 return 0;
385}
std::vector< std::unique_ptr< Module > > mModules

References mModules.

Referenced by AudacityApp::InitPart2(), ProjectManager::New(), ProjectManager::OnCloseWindow(), and QuitAudacity().

Here is the caller graph for this function:

◆ FindModules()

void ModuleManager::FindModules ( FilePaths files)
staticprivate

Definition at line 215 of file ModuleManager.cpp.

216{
217 const auto &audacityPathList = FileNames::AudacityPathList();
218 FilePaths pathList;
219 wxString pathVar;
220
221 // Code from LoadLadspa that might be useful in load modules.
222 pathVar = wxGetenv(wxT("AUDACITY_MODULES_PATH"));
223 if (!pathVar.empty())
224 FileNames::AddMultiPathsToPathList(pathVar, pathList);
225
226 for (const auto &path : audacityPathList) {
227 wxString prefix = path + wxFILE_SEP_PATH;
228 FileNames::AddUniquePathToPathList(prefix + wxT("modules"),
229 pathList);
230 if (files.size()) {
231 break;
232 }
233 }
234
235 #if defined(__WXMSW__)
236 FileNames::FindFilesInPathList(wxT("*.dll"), pathList, files);
237 #else
238 FileNames::FindFilesInPathList(wxT("*.so"), pathList, files);
239 #endif
240}
FILES_API const FilePaths & AudacityPathList()
A list of directories that should be searched for Audacity files (plug-ins, help files,...

References FileNames::AddMultiPathsToPathList(), FileNames::AddUniquePathToPathList(), FileNames::AudacityPathList(), FileNames::FindFilesInPathList(), and wxT().

Referenced by Initialize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Get()

ModuleManager & ModuleManager::Get ( )
static

Definition at line 416 of file ModuleManager.cpp.

417{
418 if (!mInstance)
419 mInstance = std::make_unique<ModuleManager>();
420
421 return *mInstance;
422}
static std::unique_ptr< ModuleManager > mInstance

References mInstance.

Referenced by PluginDataModel::ApplyChanges(), PluginManager::CheckPluginUpdates(), PluginManager::ClearEffectPlugins(), anonymous_namespace{PluginHost.cpp}::Discover(), PluginManager::DropFile(), PluginManager::Initialize(), PluginManager::InitializePlugins(), AudacityApp::InitPart2(), PluginManager::IsPluginAvailable(), PluginManager::Load(), ProjectManager::New(), ProjectManager::OnCloseWindow(), PluginHost::PluginHost(), PluginRegistrationDialog::PopulateOrExchange(), QuitAudacity(), and TryLoadModules().

Here is the caller graph for this function:

◆ GetID()

PluginID ModuleManager::GetID ( PluginProvider provider)
static

Definition at line 429 of file ModuleManager.cpp.

430{
431 return wxString::Format(wxT("%s_%s_%s_%s_%s"),
433 wxEmptyString,
434 provider->GetVendor().Internal(),
435 provider->GetSymbol().Internal(),
436 provider->GetPath());
437}
virtual PluginPath GetPath() const =0
virtual VendorSymbol GetVendor() const =0
virtual ComponentInterfaceSymbol GetSymbol() const =0
const wxString & Internal() const
static wxString GetPluginTypeString()

References ComponentInterface::GetPath(), GetPluginTypeString(), ComponentInterface::GetSymbol(), ComponentInterface::GetVendor(), ComponentInterfaceSymbol::Internal(), and wxT().

Referenced by PluginManager::GetID(), and InitializeBuiltins().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetPluginTypeString()

wxString ModuleManager::GetPluginTypeString ( )
static

Definition at line 424 of file ModuleManager.cpp.

425{
426 return L"Module";
427}

Referenced by GetID(), and PluginManager::GetPluginTypeString().

Here is the caller graph for this function:

◆ Initialize()

void ModuleManager::Initialize ( )

Definition at line 352 of file ModuleManager.cpp.

353{
354 FilePaths files;
355 FindModules(files);
356
357 FilePaths decided;
358 DelayedErrors errors;
359 size_t numDecided = 0;
360
361 // Multiple passes give modules multiple chances to load in case they
362 // depend on some other module not yet loaded
363 do {
364 numDecided = decided.size();
365 errors.clear();
366 TryLoadModules(files, decided, errors);
367 }
368 while ( errors.size() && numDecided < decided.size() );
369
370 // Only now show accumulated errors of modules that failed to load
371 for ( const auto &pair : errors ) {
372 auto &pModule = pair.first;
373 pModule->ShowLoadFailureError(pair.second);
374 ModuleSettings::SetModuleStatus( pModule->GetName(), kModuleFailed );
375 }
376}
@ kModuleFailed
std::vector< std::pair< std::unique_ptr< Module >, wxString > > DelayedErrors
static void FindModules(FilePaths &files)
static void TryLoadModules(const FilePaths &files, FilePaths &decided, DelayedErrors &errors)
MODULE_MANAGER_API void SetModuleStatus(const FilePath &fname, int iStatus)

References FindModules(), kModuleFailed, ModuleSettings::SetModuleStatus(), and TryLoadModules().

Referenced by AudacityApp::InitPart2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ InitializeBuiltins()

void ModuleManager::InitializeBuiltins ( )
private

Definition at line 476 of file ModuleManager.cpp.

477{
478 for (const auto& pluginProviderFactory : builtinProviderList())
479 {
480 auto pluginProvider = pluginProviderFactory();
481
482 if (pluginProvider && pluginProvider->Initialize()) {
483 PluginProviderUniqueHandle handle { std::move(pluginProvider) };
484
485 auto id = GetID(handle.get());
486
487 // Need to remember it
488 mProviders[id] = std::move(handle);
489 }
490 }
491}
int id
static PluginID GetID(PluginProvider *provider)

References anonymous_namespace{ModuleManager.cpp}::builtinProviderList(), GetID(), id, and mProviders.

Referenced by DiscoverProviders().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsProviderValid()

bool ModuleManager::IsProviderValid ( const PluginID provider,
const PluginPath path 
)

Definition at line 535 of file ModuleManager.cpp.

537{
538 // Builtin modules do not have a path
539 if (path.empty())
540 {
541 return true;
542 }
543
544 wxFileName lib(path);
545 if (lib.FileExists() || lib.DirExists())
546 {
547 return true;
548 }
549
550 return false;
551}

◆ LoadPlugin()

std::unique_ptr< ComponentInterface > ModuleManager::LoadPlugin ( const PluginID provider,
const PluginPath path 
)

Definition at line 517 of file ModuleManager.cpp.

519{
520 if (auto iter = mProviders.find(providerID);
521 iter == mProviders.end())
522 return nullptr;
523 else
524 return iter->second->LoadPlugin(path);
525}

References mProviders.

◆ operator=()

ModuleManager & ModuleManager::operator= ( const ModuleManager )
privatedelete

◆ Providers() [1/2]

auto ModuleManager::Providers ( )
inline

Definition at line 120 of file ModuleManager.h.

121 { return make_iterator_range(mProviders.begin(), mProviders.end()); }
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: IteratorX.h:210

References make_iterator_range().

Here is the call graph for this function:

◆ Providers() [2/2]

auto ModuleManager::Providers ( ) const
inline

Definition at line 117 of file ModuleManager.h.

118 { return make_iterator_range(mProviders.cbegin(), mProviders.cend()); }

References make_iterator_range().

Here is the call graph for this function:

◆ RegisterEffectPlugin()

bool ModuleManager::RegisterEffectPlugin ( const PluginID provider,
const PluginPath path,
TranslatableString errMsg 
)

Definition at line 493 of file ModuleManager.cpp.

494{
495 errMsg = {};
496 if (mProviders.find(providerID) == mProviders.end())
497 {
498 return false;
499 }
500
501 auto nFound = mProviders[providerID]->DiscoverPluginsAtPath(path, errMsg, PluginManagerInterface::DefaultRegistrationCallback);
502
503 return nFound > 0;
504}
static const PluginID & DefaultRegistrationCallback(PluginProvider *provider, ComponentInterface *ident)

References PluginManagerInterface::DefaultRegistrationCallback(), and mProviders.

Here is the call graph for this function:

◆ TryLoadModules()

void ModuleManager::TryLoadModules ( const FilePaths files,
FilePaths decided,
DelayedErrors errors 
)
staticprivate

Definition at line 242 of file ModuleManager.cpp.

244{
245 FilePaths checked;
246 wxString saveOldCWD = ::wxGetCwd();
247 auto cleanup = finally([&]{ ::wxSetWorkingDirectory(saveOldCWD); });
248 for (const auto &file : files) {
249 // As a courtesy to some modules that might be bridges to
250 // open other modules, we set the current working
251 // directory to be the module's directory.
252 auto prefix = ::wxPathOnly(file);
253 ::wxSetWorkingDirectory(prefix);
254
255 // Only process the first module encountered in the
256 // defined search sequence.
257 wxString ShortName = wxFileName( file ).GetName();
258 if( checked.Index( ShortName, false ) != wxNOT_FOUND )
259 continue;
260 checked.Add( ShortName );
261
262 // Skip if a previous pass through this function decided it already
263 if( decided.Index( ShortName, false ) != wxNOT_FOUND )
264 continue;
265
266#ifdef EXPERIMENTAL_MODULE_PREFS
267 int iModuleStatus = ModuleSettings::GetModuleStatus( file );
268 if( iModuleStatus == kModuleDisabled )
269 continue;
270 if( iModuleStatus == kModuleFailed )
271 continue;
272 // New module? You have to go and explicitly enable it.
273 if( iModuleStatus == kModuleNew ){
274 // To ensure it is noted in config file and so
275 // appears on modules page.
277 continue;
278 }
279
280 if( iModuleStatus == kModuleAsk )
281#endif
282 // JKC: I don't like prompting for the plug-ins individually
283 // I think it would be better to show the module prefs page,
284 // and let the user decide for each one.
285 {
286 auto msg = XO("Module \"%s\" found.").Format( ShortName );
287 msg += XO("\n\nOnly use modules from trusted sources");
288 const TranslatableStrings buttons{
289 XO("Yes"), XO("No"),
290 }; // could add a button here for 'yes and remember that', and put it into the cfg file. Needs more thought.
291 int action = BasicUI::ShowMultiDialog(msg,
292 XO("Audacity Module Loader"),
293 buttons,
294 "",
295 XO("Try and load this module?"),
296 false);
297#ifdef EXPERIMENTAL_MODULE_PREFS
298 // If we're not prompting always, accept the answer permanently
299 if( iModuleStatus == kModuleNew ){
300 iModuleStatus = (action==1)?kModuleDisabled : kModuleEnabled;
301 ModuleSettings::SetModuleStatus( file, iModuleStatus );
302 }
303#endif
304 if(action == 1){ // "No"
305 decided.Add( ShortName );
306 continue;
307 }
308 }
309#ifdef EXPERIMENTAL_MODULE_PREFS
310 // Before attempting to load, we set the state to bad.
311 // That way, if we crash, we won't try again.
313#endif
314
315 wxString Error;
316 auto umodule = std::make_unique<Module>(file);
317 if (umodule->Load(Error)) // it will get rejected if there are version problems
318 {
319 decided.Add( ShortName );
320 auto module = umodule.get();
321
322 if (!module->HasDispatch())
323 {
324 auto ShortName = wxFileName(file).GetName();
326 XO("The module \"%s\" does not provide any of the required functions.\n\nIt will not be loaded.")
327 .Format(ShortName));
328 wxLogMessage(wxT("The module \"%s\" does not provide any of the required functions. It will not be loaded."), file);
329 module->Unload();
330 }
331 else
332 {
333 Get().mModules.push_back(std::move(umodule));
334
335#ifdef EXPERIMENTAL_MODULE_PREFS
336 // Loaded successfully, restore the status.
337 ModuleSettings::SetModuleStatus(file, iModuleStatus);
338#endif
339 }
340 }
341 else if (!Error.empty()) {
342 // Module is not yet decided in this pass.
343 // Maybe it depends on another which has not yet been loaded.
344 // But don't take the kModuleAsk path again in a later pass.
346 errors.emplace_back( std::move( umodule ), Error );
347 }
348 }
349}
XO("Cut/Copy/Paste")
static BasicUI::MessageBoxResult DoMessageBox(const TranslatableString &msg)
@ kModuleDisabled
@ kModuleAsk
@ kModuleNew
@ kModuleEnabled
std::vector< TranslatableString > TranslatableStrings
Abstract base class used in importing a file.
static ModuleManager & Get()
int ShowMultiDialog(const TranslatableString &message, const TranslatableString &title, const TranslatableStrings &buttons, const ManualPageID &helpPage, const TranslatableString &boxMsg, bool log)
Display a dialog with radio buttons.
Definition: BasicUI.h:357
MODULE_MANAGER_API int GetModuleStatus(const FilePath &fname)

References DoMessageBox(), Error, Get(), ModuleSettings::GetModuleStatus(), kModuleAsk, kModuleDisabled, kModuleEnabled, kModuleFailed, kModuleNew, mModules, ModuleSettings::SetModuleStatus(), BasicUI::ShowMultiDialog(), wxT(), and XO().

Referenced by Initialize().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ std::make_unique

std::unique_ptr< ModuleManager > std::make_unique ( )
friend

Member Data Documentation

◆ mInstance

std::unique_ptr< ModuleManager > ModuleManager::mInstance {}
staticprivate

Definition at line 146 of file ModuleManager.h.

Referenced by Get().

◆ mModules

std::vector<std::unique_ptr<Module> > ModuleManager::mModules
private

Definition at line 155 of file ModuleManager.h.

Referenced by Dispatch(), and TryLoadModules().

◆ mProviders

PluginProviderHandlesMap ModuleManager::mProviders
private

The documentation for this class was generated from the following files: