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 | 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
 
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 IsPluginValid (const PluginID &provider, const PluginPath &path, bool bFast)
 

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 &) PROHIBITED
 
ModuleManageroperator= (const ModuleManager &) PROHIBITED
 
void InitializeBuiltins ()
 

Static Private Member Functions

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

Private Attributes

friend PluginProviderDeleter
 
PluginProviderMap mProviders
 
std::vector< std::unique_ptr< Module > > mModules
 

Static Private Attributes

static std::unique_ptr< ModuleManagermInstance {}
 

Detailed Description

Definition at line 71 of file ModuleManager.h.

Member Typedef Documentation

◆ DelayedErrors

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

Definition at line 89 of file ModuleManager.h.

Constructor & Destructor Documentation

◆ ModuleManager() [1/2]

ModuleManager::ModuleManager ( )
private

Definition at line 207 of file ModuleManager.cpp.

208{
209}

◆ ~ModuleManager()

ModuleManager::~ModuleManager ( )
private

Definition at line 211 of file ModuleManager.cpp.

212{
213 mProviders.clear();
214 builtinProviderList().clear();
215}
PluginProviderMap 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 )
private

Member Function Documentation

◆ CreateProviderInstance()

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

Definition at line 500 of file ModuleManager.cpp.

502{
503 if (path.empty() && mProviders.find(providerID) != mProviders.end())
504 {
505 return mProviders[providerID].get();
506 }
507
508 return nullptr;
509}

References mProviders.

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

Here is the caller graph for this function:

◆ DiscoverProviders()

bool ModuleManager::DiscoverProviders ( )

Definition at line 421 of file ModuleManager.cpp.

422{
424
425// The commented out code loads modules whether or not they are enabled.
426// none of our modules is a 'provider' of effects, so this code commented out.
427#if 0
428 FilePaths provList;
429 FilePaths pathList;
430
431 // Code from LoadLadspa that might be useful in load modules.
432 wxString pathVar = wxString::FromUTF8(getenv("AUDACITY_MODULES_PATH"));
433
434 if (!pathVar.empty())
435 {
436 FileNames::AddMultiPathsToPathList(pathVar, pathList);
437 }
438 else
439 {
441 }
442
443#if defined(__WXMSW__)
444 FileNames::FindFilesInPathList(wxT("*.dll"), pathList, provList);
445#elif defined(__WXMAC__)
446 FileNames::FindFilesInPathList(wxT("*.dylib"), pathList, provList);
447#else
448 FileNames::FindFilesInPathList(wxT("*.so"), pathList, provList);
449#endif
450
451 for ( const auto &path : provList )
452 LoadModule(path);
453#endif
454
455 return true;
456}
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(), and FileNames::ModulesDir().

Here is the call graph for this function:

◆ Dispatch()

int ModuleManager::Dispatch ( ModuleDispatchTypes  type)

Definition at line 382 of file ModuleManager.cpp.

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

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

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

397{
398 if (!mInstance)
399 {
401 }
402
403 return *mInstance;
404}
#define safenew
Definition: MemoryX.h:10
static std::unique_ptr< ModuleManager > mInstance

References mInstance, and safenew.

Referenced by PluginManager::CheckForUpdates(), PluginManager::DropFile(), PluginManager::Initialize(), AudacityApp::InitPart2(), PluginManager::Load(), ProjectManager::New(), ProjectManager::OnCloseWindow(), PluginRegistrationDialog::OnOK(), QuitAudacity(), and TryLoadModules().

Here is the caller graph for this function:

◆ GetID()

PluginID ModuleManager::GetID ( PluginProvider provider)
static

Definition at line 411 of file ModuleManager.cpp.

412{
413 return wxString::Format(wxT("%s_%s_%s_%s_%s"),
415 wxEmptyString,
416 provider->GetVendor().Internal(),
417 provider->GetSymbol().Internal(),
418 provider->GetPath());
419}
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(), and ComponentInterfaceSymbol::Internal().

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

407{
408 return L"Module";
409}

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

Here is the caller graph for this function:

◆ Initialize()

void ModuleManager::Initialize ( )

Definition at line 355 of file ModuleManager.cpp.

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

459{
460 for (auto pluginProviderMain : builtinProviderList())
461 {
462 PluginProviderHandle provider{ pluginProviderMain(), PluginProviderDeleter{} };
463 if (provider && provider->Initialize()) {
464 // Register the provider
465 auto pInterface = provider.get();
466 auto id = GetID(pInterface);
467
468 // Need to remember it
469 mProviders[id] = std::move(provider);
470 }
471 else
472 {
473 // Don't leak! Destructor of module does that.
474 }
475 }
476}
std::unique_ptr< PluginProvider, PluginProviderDeleter > PluginProviderHandle
Definition: ModuleManager.h:67
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:

◆ IsPluginValid()

bool ModuleManager::IsPluginValid ( const PluginID provider,
const PluginPath path,
bool  bFast 
)

Definition at line 539 of file ModuleManager.cpp.

542{
543 if (mProviders.find(providerID) == mProviders.end())
544 {
545 return false;
546 }
547
548 return mProviders[providerID]->IsPluginValid(path, bFast);
549}

References mProviders.

Referenced by PluginManager::CheckForUpdates().

Here is the caller graph for this function:

◆ IsProviderValid()

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

Definition at line 521 of file ModuleManager.cpp.

523{
524 // Builtin modules do not have a path
525 if (path.empty())
526 {
527 return true;
528 }
529
530 wxFileName lib(path);
531 if (lib.FileExists() || lib.DirExists())
532 {
533 return true;
534 }
535
536 return false;
537}

Referenced by PluginManager::CheckForUpdates().

Here is the caller graph for this function:

◆ LoadPlugin()

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

Definition at line 511 of file ModuleManager.cpp.

513{
514 if (auto iter = mProviders.find(providerID);
515 iter == mProviders.end())
516 return nullptr;
517 else
518 return iter->second->LoadPlugin(path);
519}

References mProviders.

◆ operator=()

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

◆ Providers()

auto ModuleManager::Providers ( ) const
inline

Definition at line 103 of file ModuleManager.h.

104 { return make_iterator_range(mProviders.cbegin(), mProviders.cend()); }
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:423

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

488{
489 errMsg = {};
490 if (mProviders.find(providerID) == mProviders.end())
491 {
492 return false;
493 }
494
495 auto nFound = mProviders[providerID]->DiscoverPluginsAtPath(path, errMsg, PluginManagerInterface::DefaultRegistrationCallback);
496
497 return nFound > 0;
498}
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 245 of file ModuleManager.cpp.

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

Referenced by Initialize().

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

Member Data Documentation

◆ mInstance

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

Definition at line 129 of file ModuleManager.h.

Referenced by Get().

◆ mModules

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

Definition at line 138 of file ModuleManager.h.

Referenced by Dispatch(), and TryLoadModules().

◆ mProviders

PluginProviderMap ModuleManager::mProviders
private

◆ PluginProviderDeleter

friend ModuleManager::PluginProviderDeleter
private

Definition at line 127 of file ModuleManager.h.


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