1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-11-23 09:20:16 +01:00

Crude way to let modules depend on others: multiple load passes...

... Repeatedly pass through the list of modules that need to be opened, so
long as the list is not empty and at least one module loaded in the last pass.

This discovers dependencies of modules on other modules, avoiding the need to
describe the dependencies and make one pass in some topologically sorted order.

Which would be smarter, but would require much other work.
This commit is contained in:
Paul Licameli
2020-10-14 20:58:20 -04:00
parent 059f96173b
commit c7834257d8
2 changed files with 42 additions and 6 deletions

View File

@@ -85,8 +85,8 @@ wxWindow * MakeHijackPanel()
static tpRegScriptServerFunc scriptFn;
Module::Module(const FilePath & name)
: mName{ name }
{
mName = name;
mLib = std::make_unique<wxDynamicLibrary>();
mDispatch = NULL;
}
@@ -119,6 +119,9 @@ bool Module::Load(wxString &deferredErrorMessage)
auto ShortName = wxFileName(mName).GetName();
if (!mLib->Load(mName, wxDL_NOW | wxDL_QUIET | wxDL_GLOBAL)) {
// For this failure path, only, there is a possiblity of retrial
// after some other dependency of this module is loaded. So the
// error is not immediately reported.
deferredErrorMessage = wxString(wxSysErrorMsg());
return false;
}
@@ -265,7 +268,8 @@ void ModuleManager::FindModules(FilePaths &files)
#endif
}
void ModuleManager::TryLoadModules(const FilePaths &files)
void ModuleManager::TryLoadModules(
const FilePaths &files, FilePaths &decided, DelayedErrors &errors)
{
FilePaths checked;
wxString saveOldCWD = ::wxGetCwd();
@@ -284,6 +288,10 @@ void ModuleManager::TryLoadModules(const FilePaths &files)
continue;
checked.Add( ShortName );
// Skip if a previous pass through this function decided it already
if( decided.Index( ShortName, false ) != wxNOT_FOUND )
continue;
#ifdef EXPERIMENTAL_MODULE_PREFS
int iModuleStatus = ModulePrefs::GetModuleStatus( file );
if( iModuleStatus == kModuleDisabled )
@@ -323,6 +331,7 @@ void ModuleManager::TryLoadModules(const FilePaths &files)
}
#endif
if(action == 1){ // "No"
decided.Add( ShortName );
continue;
}
}
@@ -336,6 +345,7 @@ void ModuleManager::TryLoadModules(const FilePaths &files)
auto umodule = std::make_unique<Module>(file);
if (umodule->Load(Error)) // it will get rejected if there are version problems
{
decided.Add( ShortName );
auto module = umodule.get();
{
@@ -376,7 +386,11 @@ void ModuleManager::TryLoadModules(const FilePaths &files)
}
}
else if (!Error.empty()) {
umodule->ShowLoadFailureError(Error);
// Module is not yet decided in this pass.
// Maybe it depends on another which has not yet been loaded.
// But don't take the kModuleAsk path again in a later pass.
ModulePrefs::SetModuleStatus( file, kModuleEnabled );
errors.emplace_back( std::move( umodule ), Error );
}
}
}
@@ -387,7 +401,25 @@ void ModuleManager::Initialize()
FilePaths files;
FindModules(files);
TryLoadModules(files);
FilePaths decided;
DelayedErrors errors;
size_t numDecided = 0;
// Multiple passes give modules multiple chances to load in case they
// depend on some other module not yet loaded
do {
numDecided = decided.size();
errors.clear();
TryLoadModules(files, decided, errors);
}
while ( errors.size() && numDecided < decided.size() );
// Only now show accumulated errors of modules that failed to load
for ( const auto &pair : errors ) {
auto &pModule = pair.first;
pModule->ShowLoadFailureError(pair.second);
ModulePrefs::SetModuleStatus( pModule->GetName(), kModuleFailed );
}
// After loading all the modules, we may have a registered scripting function.
if(scriptFn)

View File

@@ -47,9 +47,10 @@ public:
bool HasDispatch() { return mDispatch != NULL; };
int Dispatch(ModuleDispatchTypes type);
void * GetSymbol(const wxString &name);
const FilePath &GetName() const { return mName; }
private:
FilePath mName;
const FilePath mName;
std::unique_ptr<wxDynamicLibrary> mLib;
fnModuleDispatch mDispatch;
};
@@ -78,7 +79,10 @@ public:
private:
static void FindModules(FilePaths &files);
static void TryLoadModules(const FilePaths &files);
using DelayedErrors =
std::vector< std::pair< std::unique_ptr<Module>, wxString > >;
static void TryLoadModules(
const FilePaths &files, FilePaths &decided, DelayedErrors &errors);
public:
void Initialize();