Audacity  3.0.3
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)
 
ModuleInterfaceCreateProviderInstance (const PluginID &provider, const PluginPath &path)
 
std::unique_ptr< ComponentInterfaceCreateInstance (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 (ModuleInterface *module)
 

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 ModuleInterfaceDeleter
 
ModuleMap mDynModules
 
std::vector< std::unique_ptr< Module > > mModules
 

Static Private Attributes

static std::unique_ptr< ModuleManagermInstance {}
 

Detailed Description

Definition at line 70 of file ModuleManager.h.

Member Typedef Documentation

◆ DelayedErrors

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

Definition at line 88 of file ModuleManager.h.

Constructor & Destructor Documentation

◆ ModuleManager() [1/2]

ModuleManager::ModuleManager ( )
private

Definition at line 206 of file ModuleManager.cpp.

207 {
208 }

◆ ~ModuleManager()

ModuleManager::~ModuleManager ( )
private

Definition at line 210 of file ModuleManager.cpp.

211 {
212  mDynModules.clear();
213  builtinModuleList().clear();
214 }

References anonymous_namespace{ModuleManager.cpp}::builtinModuleList(), and mDynModules.

Here is the call graph for this function:

◆ ModuleManager() [2/2]

ModuleManager::ModuleManager ( const ModuleManager )
private

Member Function Documentation

◆ CreateInstance()

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

Definition at line 514 of file ModuleManager.cpp.

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

References mDynModules.

Referenced by PluginDescriptor::GetInstance().

Here is the caller graph for this function:

◆ CreateProviderInstance()

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

Definition at line 503 of file ModuleManager.cpp.

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

References mDynModules.

Referenced by PluginManager::CheckForUpdates(), and PluginDescriptor::GetInstance().

Here is the caller graph for this function:

◆ DiscoverProviders()

bool ModuleManager::DiscoverProviders ( )

Definition at line 420 of file ModuleManager.cpp.

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

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

382 {
383  for (const auto &module: mModules) {
384  module->Dispatch(type);
385  }
386  return 0;
387 }

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

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

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

396 {
397  if (!mInstance)
398  {
400  }
401 
402  return *mInstance;
403 }

References mInstance, and safenew.

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

Here is the caller graph for this function:

◆ GetID()

PluginID ModuleManager::GetID ( ModuleInterface module)
static

Definition at line 410 of file ModuleManager.cpp.

411 {
412  return wxString::Format(wxT("%s_%s_%s_%s_%s"),
414  wxEmptyString,
415  module->GetVendor().Internal(),
416  module->GetSymbol().Internal(),
417  module->GetPath());
418 }

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

406 {
407  return L"Module";
408 }

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

Here is the caller graph for this function:

◆ Initialize()

void ModuleManager::Initialize ( )

Definition at line 354 of file ModuleManager.cpp.

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

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

458 {
459  for (auto moduleMain : builtinModuleList())
460  {
461  ModuleInterfaceHandle module {
462  moduleMain(), ModuleInterfaceDeleter{}
463  };
464 
465  if (module && module->Initialize())
466  {
467  // Register the provider
468  ModuleInterface *pInterface = module.get();
469  auto id = GetID(pInterface);
470 
471  // Need to remember it
472  mDynModules[id] = std::move(module);
473  }
474  else
475  {
476  // Don't leak! Destructor of module does that.
477  }
478  }
479 }

References anonymous_namespace{ModuleManager.cpp}::builtinModuleList(), GetID(), id, and mDynModules.

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

545 {
546  if (mDynModules.find(providerID) == mDynModules.end())
547  {
548  return false;
549  }
550 
551  return mDynModules[providerID]->IsPluginValid(path, bFast);
552 }

References mDynModules.

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

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

Referenced by PluginManager::CheckForUpdates().

Here is the caller graph for this function:

◆ operator=()

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

◆ Providers()

auto ModuleManager::Providers ( ) const
inline

Definition at line 102 of file ModuleManager.h.

103  { return make_iterator_range(mDynModules.cbegin(), mDynModules.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 490 of file ModuleManager.cpp.

491 {
492  errMsg = {};
493  if (mDynModules.find(providerID) == mDynModules.end())
494  {
495  return false;
496  }
497 
498  auto nFound = mDynModules[providerID]->DiscoverPluginsAtPath(path, errMsg, PluginManagerInterface::DefaultRegistrationCallback);
499 
500  return nFound > 0;
501 }

References PluginManagerInterface::DefaultRegistrationCallback(), and mDynModules.

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

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

References AudacityMessageBox(), Get(), ModuleSettings::GetModuleStatus(), kModuleAsk, kModuleDisabled, kModuleEnabled, kModuleFailed, kModuleNew, mModules, ModuleSettings::SetModuleStatus(), 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

◆ mDynModules

ModuleMap ModuleManager::mDynModules
private

◆ mInstance

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

Definition at line 128 of file ModuleManager.h.

Referenced by Get().

◆ mModules

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

Definition at line 137 of file ModuleManager.h.

Referenced by Dispatch(), and TryLoadModules().

◆ ModuleInterfaceDeleter

friend ModuleManager::ModuleInterfaceDeleter
private

Definition at line 126 of file ModuleManager.h.


The documentation for this class was generated from the following files:
ModuleManager::TryLoadModules
static void TryLoadModules(const FilePaths &files, FilePaths &decided, DelayedErrors &errors)
Definition: ModuleManager.cpp:244
ModuleManager::mDynModules
ModuleMap mDynModules
Definition: ModuleManager.h:133
make_iterator_range
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:551
ModuleSettings::GetModuleStatus
int GetModuleStatus(const FilePath &fname)
Definition: ModuleSettings.cpp:28
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
Definition: AudacityMessageBox.cpp:17
ModuleManager::mModules
std::vector< std::unique_ptr< Module > > mModules
Definition: ModuleManager.h:137
ComponentInterface::GetSymbol
virtual ComponentInterfaceSymbol GetSymbol()=0
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: TranslatableString.h:295
kModuleEnabled
@ kModuleEnabled
Definition: ModuleSettings.h:18
ModuleManager::GetID
static PluginID GetID(ModuleInterface *module)
Definition: ModuleManager.cpp:410
kModuleFailed
@ kModuleFailed
Definition: ModuleSettings.h:20
Format
Abstract base class used in importing a file.
ModuleManager::InitializeBuiltins
void InitializeBuiltins()
Definition: ModuleManager.cpp:457
anonymous_namespace{ModuleManager.cpp}::builtinModuleList
BuiltinModuleList & builtinModuleList()
Definition: ModuleManager.cpp:178
XO
#define XO(s)
Definition: Internat.h:31
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
FileNames::AddUniquePathToPathList
FILES_API void AddUniquePathToPathList(const FilePath &path, FilePaths &pathList)
ComponentInterface::GetVendor
virtual VendorSymbol GetVendor()=0
ModuleInterface
Definition: ModuleInterface.h:70
ModuleManager::GetPluginTypeString
static wxString GetPluginTypeString()
Definition: ModuleManager.cpp:405
ModuleManager::DelayedErrors
std::vector< std::pair< std::unique_ptr< Module >, wxString > > DelayedErrors
Definition: ModuleManager.h:89
ModuleManager
Definition: ModuleManager.h:71
ComponentInterface::GetPath
virtual PluginPath GetPath()=0
ModuleManager::Get
static ModuleManager & Get()
Definition: ModuleManager.cpp:395
kModuleNew
@ kModuleNew
Definition: ModuleSettings.h:21
FileNames::ModulesDir
FILES_API FilePath ModulesDir()
FileNames::FindFilesInPathList
FILES_API void FindFilesInPathList(const wxString &pattern, const FilePaths &pathList, FilePaths &results, int flags=wxDIR_FILES)
ShowMultiDialog
int ShowMultiDialog(const TranslatableString &message, const TranslatableString &title, const TranslatableStrings &buttons, const wxString &helpPage, const TranslatableString &boxMsg, bool log)
Definition: MultiDialog.cpp:180
FileNames::AddMultiPathsToPathList
FILES_API void AddMultiPathsToPathList(const wxString &multiPathString, FilePaths &pathList)
id
int id
Definition: WaveTrackControls.cpp:577
PluginManagerInterface::DefaultRegistrationCallback
static const PluginID & DefaultRegistrationCallback(ModuleInterface *provider, ComponentInterface *ident)
Definition: PluginManager.cpp:329
FileNames::AudacityPathList
FILES_API const FilePaths & AudacityPathList()
A list of directories that should be searched for Audacity files (plug-ins, help files,...
ModuleManager::FindModules
static void FindModules(FilePaths &files)
Definition: ModuleManager.cpp:217
ModuleSettings::SetModuleStatus
void SetModuleStatus(const FilePath &fname, int iStatus)
Definition: ModuleSettings.cpp:75
ModuleManager::mInstance
static std::unique_ptr< ModuleManager > mInstance
Definition: ModuleManager.h:128
ModuleInterfaceHandle
std::unique_ptr< ModuleInterface, ModuleInterfaceDeleter > ModuleInterfaceHandle
Definition: ModuleManager.h:65
ComponentInterfaceSymbol::Internal
const wxString & Internal() const
Definition: ComponentInterfaceSymbol.h:55
kModuleDisabled
@ kModuleDisabled
Definition: ModuleSettings.h:17
BasicUI::Icon::Error
@ Error
safenew
#define safenew
Definition: MemoryX.h:10
ModuleInterfaceDeleter
Definition: ModuleManager.h:59
kModuleAsk
@ kModuleAsk
Definition: ModuleSettings.h:19