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 84 of file ModuleManager.h.

Member Typedef Documentation

◆ DelayedErrors

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

Definition at line 102 of file ModuleManager.h.

Constructor & Destructor Documentation

◆ ModuleManager() [1/2]

ModuleManager::ModuleManager ( )
private

Definition at line 205 of file ModuleManager.cpp.

206{
207}

◆ ~ModuleManager()

ModuleManager::~ModuleManager ( )
private

Definition at line 209 of file ModuleManager.cpp.

210{
211 mProviders.clear();
212 builtinProviderList().clear();
213}
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 528 of file ModuleManager.cpp.

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

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 507 of file ModuleManager.cpp.

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

References mProviders.

Referenced by PluginManager::Load().

Here is the caller graph for this function:

◆ DiscoverProviders()

bool ModuleManager::DiscoverProviders ( )

Definition at line 440 of file ModuleManager.cpp.

441{
443
444// The commented out code loads modules whether or not they are enabled.
445// none of our modules is a 'provider' of effects, so this code commented out.
446#if 0
447 FilePaths provList;
448 FilePaths pathList;
449
450 // Code from LoadLadspa that might be useful in load modules.
451 wxString pathVar = wxString::FromUTF8(getenv("AUDACITY_MODULES_PATH"));
452
453 if (!pathVar.empty())
454 {
455 FileNames::AddMultiPathsToPathList(pathVar, pathList);
456 }
457 else
458 {
460 }
461
462#if defined(__WXMSW__)
463 FileNames::FindFilesInPathList(wxT("*.dll"), pathList, provList);
464#elif defined(__WXMAC__)
465 FileNames::FindFilesInPathList(wxT("*.dylib"), pathList, provList);
466#else
467 FileNames::FindFilesInPathList(wxT("*.so"), pathList, provList);
468#endif
469
470 for ( const auto &path : provList )
471 LoadModule(path);
472#endif
473
474 return true;
475}
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 380 of file ModuleManager.cpp.

381{
382 for (const auto &module: mModules) {
383 module->Dispatch(type);
384 }
385 return 0;
386}
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 216 of file ModuleManager.cpp.

217{
218 const auto &audacityPathList = FileNames::AudacityPathList();
219 FilePaths pathList;
220 wxString pathVar;
221
222 // Code from LoadLadspa that might be useful in load modules.
223 pathVar = wxGetenv(wxT("AUDACITY_MODULES_PATH"));
224 if (!pathVar.empty())
225 FileNames::AddMultiPathsToPathList(pathVar, pathList);
226
227 for (const auto &path : audacityPathList) {
228 wxString prefix = path + wxFILE_SEP_PATH;
229 FileNames::AddUniquePathToPathList(prefix + wxT("modules"),
230 pathList);
231 if (files.size()) {
232 break;
233 }
234 }
235
236 #if defined(__WXMSW__)
237 FileNames::FindFilesInPathList(wxT("*.dll"), pathList, files);
238 #else
239 FileNames::FindFilesInPathList(wxT("*.so"), pathList, files);
240 #endif
241}
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 417 of file ModuleManager.cpp.

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

References mInstance.

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

Here is the caller graph for this function:

◆ GetID()

PluginID ModuleManager::GetID ( PluginProvider provider)
static

Definition at line 430 of file ModuleManager.cpp.

431{
432 return wxString::Format(wxT("%s_%s_%s_%s_%s"),
434 wxEmptyString,
435 provider->GetVendor().Internal(),
436 provider->GetSymbol().Internal(),
437 provider->GetPath());
438}
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 425 of file ModuleManager.cpp.

426{
427 return L"Module";
428}

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

Here is the caller graph for this function:

◆ Initialize()

void ModuleManager::Initialize ( )

Definition at line 353 of file ModuleManager.cpp.

354{
355 FilePaths files;
356 FindModules(files);
357
358 FilePaths decided;
359 DelayedErrors errors;
360 size_t numDecided = 0;
361
362 // Multiple passes give modules multiple chances to load in case they
363 // depend on some other module not yet loaded
364 do {
365 numDecided = decided.size();
366 errors.clear();
367 TryLoadModules(files, decided, errors);
368 }
369 while ( errors.size() && numDecided < decided.size() );
370
371 // Only now show accumulated errors of modules that failed to load
372 for ( const auto &pair : errors ) {
373 auto &pModule = pair.first;
374 pModule->ShowLoadFailureError(pair.second);
375 ModuleSettings::SetModuleStatus( pModule->GetName(), kModuleFailed );
376 }
377}
@ 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 477 of file ModuleManager.cpp.

478{
479 for (const auto& pluginProviderFactory : builtinProviderList())
480 {
481 auto pluginProvider = pluginProviderFactory();
482
483 if (pluginProvider && pluginProvider->Initialize()) {
484 PluginProviderUniqueHandle handle { std::move(pluginProvider) };
485
486 auto id = GetID(handle.get());
487
488 // Need to remember it
489 mProviders[id] = std::move(handle);
490 }
491 }
492}
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 536 of file ModuleManager.cpp.

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

◆ LoadPlugin()

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

Definition at line 518 of file ModuleManager.cpp.

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

References mProviders.

◆ operator=()

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

◆ Providers() [1/2]

auto ModuleManager::Providers ( )
inline

Definition at line 119 of file ModuleManager.h.

120 { return make_iterator_range(mProviders.begin(), mProviders.end()); }
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:431

References make_iterator_range().

Here is the call graph for this function:

◆ Providers() [2/2]

auto ModuleManager::Providers ( ) const
inline

Definition at line 116 of file ModuleManager.h.

117 { 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 494 of file ModuleManager.cpp.

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

References PluginManagerInterface::DefaultRegistrationCallback(), and mProviders.

Referenced by PluginRegistrationDialog::OnOK().

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

◆ TryLoadModules()

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

Definition at line 243 of file ModuleManager.cpp.

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

References DoMessageBox(), BasicUI::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 145 of file ModuleManager.h.

Referenced by Get().

◆ mModules

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

Definition at line 154 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: