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

211{
212}

◆ ~ModuleManager()

ModuleManager::~ModuleManager ( )
private

Definition at line 214 of file ModuleManager.cpp.

215{
216 mProviders.clear();
217 builtinProviderList().clear();
218}
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 525 of file ModuleManager.cpp.

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

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

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

References mProviders.

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

Here is the caller graph for this function:

◆ DiscoverProviders()

bool ModuleManager::DiscoverProviders ( )

Definition at line 437 of file ModuleManager.cpp.

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

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

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

415{
416 if (!mInstance)
417 mInstance = std::make_unique<ModuleManager>();
418
419 return *mInstance;
420}
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 427 of file ModuleManager.cpp.

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

423{
424 return L"Module";
425}

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

Here is the caller graph for this function:

◆ Initialize()

void ModuleManager::Initialize ( )

Definition at line 350 of file ModuleManager.cpp.

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

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

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

◆ LoadPlugin()

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

Definition at line 515 of file ModuleManager.cpp.

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

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

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

250{
251 FilePaths checked;
252 wxString saveOldCWD = ::wxGetCwd();
253 auto cleanup = finally([&]{ ::wxSetWorkingDirectory(saveOldCWD); });
254 for (const auto &file : files) {
255 // As a courtesy to some modules that might be bridges to
256 // open other modules, we set the current working
257 // directory to be the module's directory.
258 auto prefix = ::wxPathOnly(file);
259 ::wxSetWorkingDirectory(prefix);
260
261 // Only process the first module encountered in the
262 // defined search sequence.
263 wxString ShortName = wxFileName( file ).GetName();
264 if( checked.Index( ShortName, false ) != wxNOT_FOUND )
265 continue;
266 checked.Add( ShortName );
267
268 // Skip if a previous pass through this function decided it already
269 if( decided.Index( ShortName, false ) != wxNOT_FOUND )
270 continue;
271
272 int iModuleStatus = ModuleSettings::GetModuleStatus( file );
273 if( iModuleStatus == kModuleDisabled )
274 continue;
275 if( iModuleStatus == kModuleFailed )
276 continue;
277 // New module? You have to go and explicitly enable it.
278 if( iModuleStatus == kModuleNew ){
279 // To ensure it is noted in config file and so
280 // appears on modules page.
282 continue;
283 }
284
285 if( iModuleStatus == kModuleAsk )
286 // JKC: I don't like prompting for the plug-ins individually
287 // I think it would be better to show the module prefs page,
288 // and let the user decide for each one.
289 {
290 auto msg = XO("Module \"%s\" found.").Format( ShortName );
291 msg += XO("\n\nOnly use modules from trusted sources");
292 const TranslatableStrings buttons{
293 XO("Yes"), XO("No"),
294 }; // could add a button here for 'yes and remember that', and put it into the cfg file. Needs more thought.
295 int action = BasicUI::ShowMultiDialog(msg,
296 XO("Audacity Module Loader"),
297 buttons,
298 "",
299 XO("Try and load this module?"),
300 false);
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 if(action == 1){ // "No"
307 decided.Add( ShortName );
308 continue;
309 }
310 }
311 // Before attempting to load, we set the state to bad.
312 // That way, if we crash, we won't try again.
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 // Loaded successfully, restore the status.
336 ModuleSettings::SetModuleStatus(file, iModuleStatus);
337 }
338 }
339 else if (!Error.empty()) {
340 // Module is not yet decided in this pass.
341 // Maybe it depends on another which has not yet been loaded.
342 // But don't take the kModuleAsk path again in a later pass.
344 errors.emplace_back( std::move( umodule ), Error );
345 }
346 }
347}
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:359
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: