28#include <wx/filename.h>
35#ifdef EXPERIMENTAL_MODULE_PREFS
40#define initFnName "ExtensionModuleInit"
41#define versionFnName "GetVersionString"
44typedef wxChar * (*tVersionFn)();
49 mLib = std::make_unique<wxDynamicLibrary>();
66 auto ShortName = wxFileName(
mName).GetName();
68 XO(
"Unable to load the \"%s\" module.\n\nError: %s")
70 wxLogMessage(
wxT(
"Unable to load the module \"%s\". Error: %s"),
mName,
Error);
75 deferredErrorMessage.clear();
77 if (
mLib->IsLoaded()) {
86 auto ShortName = wxFileName(
mName).GetName();
88 if (!
mLib->Load(
mName, wxDL_NOW | wxDL_QUIET | wxDL_GLOBAL)) {
92 deferredErrorMessage = wxString(wxSysErrorMsg());
98 if (versionFn == NULL){
100 XO(
"The module \"%s\" does not provide a version string.\n\nIt will not be loaded.")
102 wxLogMessage(
wxT(
"The module \"%s\" does not provide a version string. It will not be loaded."),
mName);
107 wxString moduleVersion = versionFn();
108 if( moduleVersion != AUDACITY_VERSION_STRING) {
110 XO(
"The module \"%s\" is matched with Audacity version \"%s\".\n\nIt will not be loaded.")
111 .
Format(ShortName, moduleVersion));
112 wxLogMessage(
wxT(
"The module \"%s\" is matched with Audacity version \"%s\". It will not be loaded."),
mName, moduleVersion);
133 XO(
"The module \"%s\" failed to initialize.\n\nIt will not be loaded.")
135 wxLogMessage(
wxT(
"The module \"%s\" failed to initialize.\nIt will not be loaded."),
mName);
144 if (
mLib->IsLoaded()) {
154 if (
mLib->IsLoaded())
188 if(pluginProviderFactory)
189 list.push_back(std::move(pluginProviderFactory));
195 auto end = list.end(), iter = std::find(list.begin(),
end, pluginProviderFactory);
222 pathVar = wxGetenv(
wxT(
"AUDACITY_MODULES_PATH"));
223 if (!pathVar.empty())
226 for (
const auto &path : audacityPathList) {
227 wxString prefix = path + wxFILE_SEP_PATH;
235 #if defined(__WXMSW__)
246 wxString saveOldCWD = ::wxGetCwd();
247 auto cleanup =
finally([&]{ ::wxSetWorkingDirectory(saveOldCWD); });
248 for (
const auto &file : files) {
252 auto prefix = ::wxPathOnly(file);
253 ::wxSetWorkingDirectory(prefix);
257 wxString ShortName = wxFileName( file ).GetName();
258 if( checked.Index( ShortName,
false ) != wxNOT_FOUND )
260 checked.Add( ShortName );
263 if( decided.Index( ShortName,
false ) != wxNOT_FOUND )
266#ifdef EXPERIMENTAL_MODULE_PREFS
286 auto msg =
XO(
"Module \"%s\" found.").Format( ShortName );
287 msg +=
XO(
"\n\nOnly use modules from trusted sources");
292 XO(
"Audacity Module Loader"),
295 XO(
"Try and load this module?"),
297#ifdef EXPERIMENTAL_MODULE_PREFS
305 decided.Add( ShortName );
309#ifdef EXPERIMENTAL_MODULE_PREFS
316 auto umodule = std::make_unique<Module>(file);
317 if (umodule->Load(
Error))
319 decided.Add( ShortName );
320 auto module = umodule.get();
322 if (!module->HasDispatch())
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.")
328 wxLogMessage(
wxT(
"The module \"%s\" does not provide any of the required functions. It will not be loaded."), file);
335#ifdef EXPERIMENTAL_MODULE_PREFS
341 else if (!
Error.empty()) {
346 errors.emplace_back( std::move( umodule ),
Error );
359 size_t numDecided = 0;
364 numDecided = decided.size();
368 while ( errors.size() && numDecided < decided.size() );
371 for (
const auto &pair : errors ) {
372 auto &pModule = pair.first;
373 pModule->ShowLoadFailureError(pair.second);
381 for (
const auto &module:
mModules) {
382 module->Dispatch(type);
419 mInstance = std::make_unique<ModuleManager>();
431 return wxString::Format(
wxT(
"%s_%s_%s_%s_%s"),
450 wxString pathVar = wxString::FromUTF8(getenv(
"AUDACITY_MODULES_PATH"));
452 if (!pathVar.empty())
461#if defined(__WXMSW__)
463#elif defined(__WXMAC__)
469 for (
const auto &path : provList )
480 auto pluginProvider = pluginProviderFactory();
482 if (pluginProvider && pluginProvider->Initialize()) {
485 auto id =
GetID(handle.get());
524 return iter->second->LoadPlugin(path);
532 return mProviders[providerId]->CheckPluginExist(path);
544 wxFileName lib(path);
545 if (lib.FileExists() || lib.DirExists())
Toolkit-neutral facade for basic user interface services.
const TranslatableString name
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
#define ModuleDispatchName
void RegisterProviderFactory(PluginProviderFactory pluginProviderFactory)
static BasicUI::MessageBoxResult DoMessageBox(const TranslatableString &msg)
void UnregisterProviderFactory(PluginProviderFactory pluginProviderFactory)
std::vector< PluginProviderFactory > BuiltinProviderList
std::unique_ptr< PluginProvider >(*)() PluginProviderFactory
int(* fnModuleDispatch)(ModuleDispatchTypes type)
Generalized interface for discovery of plug-ins for one protocol.
std::vector< TranslatableString > TranslatableStrings
virtual PluginPath GetPath() const =0
virtual VendorSymbol GetVendor() const =0
virtual ComponentInterfaceSymbol GetSymbol() const =0
const wxString & Internal() const
void ShowLoadFailureError(const wxString &Error)
fnModuleDispatch mDispatch
std::unique_ptr< wxDynamicLibrary > mLib
Module(const FilePath &name)
void * GetSymbol(const wxString &name)
bool Load(wxString &deferredErrorMessage)
int Dispatch(ModuleDispatchTypes type)
std::vector< std::pair< std::unique_ptr< Module >, wxString > > DelayedErrors
static void FindModules(FilePaths &files)
static std::unique_ptr< ModuleManager > mInstance
PluginProviderHandlesMap mProviders
static ModuleManager & Get()
static PluginID GetID(PluginProvider *provider)
static wxString GetPluginTypeString()
void InitializeBuiltins()
std::unique_ptr< ComponentInterface > LoadPlugin(const PluginID &provider, const PluginPath &path)
int Dispatch(ModuleDispatchTypes type)
PluginProvider * CreateProviderInstance(const PluginID &provider, const PluginPath &path)
bool IsProviderValid(const PluginID &provider, const PluginPath &path)
bool RegisterEffectPlugin(const PluginID &provider, const PluginPath &path, TranslatableString &errMsg)
bool CheckPluginExist(const PluginID &providerId, const PluginPath &path)
std::vector< std::unique_ptr< Module > > mModules
static void TryLoadModules(const FilePaths &files, FilePaths &decided, DelayedErrors &errors)
static const PluginID & DefaultRegistrationCallback(PluginProvider *provider, ComponentInterface *ident)
std::unique_ptr< PluginProvider > mPtr
~PluginProviderUniqueHandle()
Holds a msgid for the translation catalog; may also bind format arguments.
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
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.
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
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()
FILES_API const FilePaths & AudacityPathList()
A list of directories that should be searched for Audacity files (plug-ins, help files,...
MODULE_MANAGER_API void SetModuleStatus(const FilePath &fname, int iStatus)
MODULE_MANAGER_API int GetModuleStatus(const FilePath &fname)
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
BuiltinProviderList & builtinProviderList()
MessageBoxOptions && Caption(TranslatableString caption_) &&