1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-02 17:09:26 +02:00

Simplify iterations over PluginManager; remove a friend

This commit is contained in:
Paul Licameli 2021-06-19 08:58:07 -04:00
parent 731ab8d554
commit 04a0292d1d
7 changed files with 119 additions and 162 deletions

View File

@ -308,17 +308,15 @@ MacroCommandsCatalog::MacroCommandsCatalog( const AudacityProject *project )
PluginManager & pm = PluginManager::Get(); PluginManager & pm = PluginManager::Get();
EffectManager & em = EffectManager::Get(); EffectManager & em = EffectManager::Get();
{ {
const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect|PluginTypeAudacityCommand); for (auto &plug
while (plug) : pm.PluginsOfType(PluginTypeEffect|PluginTypeAudacityCommand)) {
{ auto command = em.GetCommandIdentifier(plug.GetID());
auto command = em.GetCommandIdentifier(plug->GetID());
if (!command.empty()) if (!command.empty())
commands.push_back( { commands.push_back( {
{ command, plug->GetSymbol().Msgid() }, { command, plug.GetSymbol().Msgid() },
plug->GetPluginType() == PluginTypeEffect ? plug.GetPluginType() == PluginTypeEffect ?
XO("Effect") : XO("Menu Command (With Parameters)") XO("Effect") : XO("Menu Command (With Parameters)")
} ); } );
plug = pm.GetNextPlugin(PluginTypeEffect|PluginTypeAudacityCommand);
} }
} }
@ -608,19 +606,12 @@ bool MacroCommands::HandleTextualCommand( CommandManager &commandManager,
// Not one of the singleton commands. // Not one of the singleton commands.
// We could/should try all the list-style commands. // We could/should try all the list-style commands.
// instead we only try the effects. // instead we only try the effects.
PluginManager & pm = PluginManager::Get();
EffectManager & em = EffectManager::Get(); EffectManager & em = EffectManager::Get();
const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect); for (auto &plug : PluginManager::Get().PluginsOfType(PluginTypeEffect))
while (plug) if (em.GetCommandIdentifier(plug.GetID()) == Str)
{
if (em.GetCommandIdentifier(plug->GetID()) == Str)
{
return EffectUI::DoEffect( return EffectUI::DoEffect(
plug->GetID(), context, plug.GetID(), context,
EffectManager::kConfigured); EffectManager::kConfigured);
}
plug = pm.GetNextPlugin(PluginTypeEffect);
}
return false; return false;
} }

View File

@ -627,15 +627,10 @@ void PluginRegistrationDialog::PopulateOrExchange(ShuttleGui &S)
} }
PluginManager & pm = PluginManager::Get(); PluginManager & pm = PluginManager::Get();
for (PluginMap::iterator iter = pm.mPlugins.begin(); iter != pm.mPlugins.end(); ++iter) for (auto &plug : pm.AllPlugins()) {
{
PluginDescriptor & plug = iter->second;
PluginType plugType = plug.GetPluginType(); PluginType plugType = plug.GetPluginType();
if (plugType != PluginTypeEffect && plugType != PluginTypeStub) if (plugType != PluginTypeEffect && plugType != PluginTypeStub)
{
continue; continue;
}
const auto &path = plug.GetPath(); const auto &path = plug.GetPath();
ItemData & item = mItems[path]; // will create NEW entry ItemData & item = mItems[path]; // will create NEW entry
@ -1025,10 +1020,9 @@ void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
if (mm.RegisterEffectPlugin(item.plugs[j]->GetProviderID(), path, if (mm.RegisterEffectPlugin(item.plugs[j]->GetProviderID(), path,
errMsg)) errMsg))
{ {
for (size_t k = 0, cntk = item.plugs.size(); k < cntk; k++) for (auto plug : item.plugs)
{ pm.UnregisterPlugin(
pm.mPlugins.erase(item.plugs[k]->GetProviderID() + wxT("_") + path); plug->GetProviderID() + wxT("_") + path);
}
// Bug 1893. We've found a provider that works. // Bug 1893. We've found a provider that works.
// Error messages from any that failed are no longer useful. // Error messages from any that failed are no longer useful.
errMsgs = {}; errMsgs = {};
@ -1047,19 +1041,14 @@ void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
XO("Effect or Command at %s failed to register:\n%s") XO("Effect or Command at %s failed to register:\n%s")
.Format( path, errMsgs ) ); .Format( path, errMsgs ) );
} }
else if (item.state == STATE_New) else if (item.state == STATE_New) {
{ for (auto plug : item.plugs)
for (size_t j = 0, cnt = item.plugs.size(); j < cnt; j++) plug->SetValid(false);
{
item.plugs[j]->SetValid(false);
}
} }
else if (item.state != STATE_New) else if (item.state != STATE_New) {
{ for (auto plug : item.plugs) {
for (size_t j = 0, cnt = item.plugs.size(); j < cnt; j++) plug->SetEnabled(item.state == STATE_Enabled);
{ plug->SetValid(item.valid);
item.plugs[j]->SetEnabled(item.state == STATE_Enabled);
item.plugs[j]->SetValid(item.valid);
} }
} }
} }
@ -1388,7 +1377,7 @@ const PluginID &PluginManagerInterface::AudacityCommandRegistrationCallback(
return empty; return empty;
} }
RegistryPath PluginManager::GetPluginEnabledSetting( const PluginID &ID ) RegistryPath PluginManager::GetPluginEnabledSetting( const PluginID &ID ) const
{ {
auto pPlugin = GetPlugin( ID ); auto pPlugin = GetPlugin( ID );
if ( pPlugin ) if ( pPlugin )
@ -1397,7 +1386,7 @@ RegistryPath PluginManager::GetPluginEnabledSetting( const PluginID &ID )
} }
RegistryPath PluginManager::GetPluginEnabledSetting( RegistryPath PluginManager::GetPluginEnabledSetting(
const PluginDescriptor &desc ) const PluginDescriptor &desc ) const
{ {
switch ( desc.GetPluginType() ) { switch ( desc.GetPluginType() ) {
case PluginTypeModule: { case PluginTypeModule: {
@ -1802,12 +1791,9 @@ bool PluginManager::DropFile(const wxString &fileName)
auto &mm = ModuleManager::Get(); auto &mm = ModuleManager::Get();
const wxFileName src{ fileName }; const wxFileName src{ fileName };
for (const PluginDescriptor *plug = GetFirstPlugin(PluginTypeModule); for (auto &plug : PluginsOfType(PluginTypeModule)) {
plug;
plug = GetNextPlugin(PluginTypeModule))
{
auto module = static_cast<ModuleInterface *> auto module = static_cast<ModuleInterface *>
(mm.CreateProviderInstance(plug->GetID(), plug->GetPath())); (mm.CreateProviderInstance(plug.GetID(), plug.GetPath()));
if (! module) if (! module)
continue; continue;
@ -2483,8 +2469,6 @@ const PluginID & PluginManager::RegisterPlugin(
return plug.GetID(); return plug.GetID();
} }
// Here solely for the purpose of Nyquist Workbench until
// a better solution is devised.
void PluginManager::UnregisterPlugin(const PluginID & ID) void PluginManager::UnregisterPlugin(const PluginID & ID)
{ {
mPlugins.erase(ID); mPlugins.erase(ID);
@ -2496,7 +2480,7 @@ int PluginManager::GetPluginCount(PluginType type)
return pair.second.GetPluginType() == type; }); return pair.second.GetPluginType() == type; });
} }
const PluginDescriptor *PluginManager::GetPlugin(const PluginID & ID) const PluginDescriptor *PluginManager::GetPlugin(const PluginID & ID) const
{ {
if (auto iter = mPlugins.find(ID); iter == mPlugins.end()) if (auto iter = mPlugins.find(ID); iter == mPlugins.end())
return nullptr; return nullptr;
@ -2504,93 +2488,57 @@ const PluginDescriptor *PluginManager::GetPlugin(const PluginID & ID)
return &iter->second; return &iter->second;
} }
const PluginDescriptor *PluginManager::GetFirstPlugin(int type) void PluginManager::Iterator::Advance(bool incrementing)
{ {
for (mPluginsIter = mPlugins.begin(); mPluginsIter != mPlugins.end(); ++mPluginsIter) const auto end = mPm.mPlugins.end();
{ if (incrementing && mIterator != end)
PluginDescriptor & plug = mPluginsIter->second; ++mIterator;
PluginType plugType = plug.GetPluginType(); bool all = mPluginType == PluginTypeNone && mEffectType == EffectTypeNone;
if( plug.IsValid() && plug.IsEnabled() && ((plugType & type) != 0)) for (; mIterator != end; ++mIterator) {
{ auto &plug = mIterator->second;
bool familyEnabled = true; if (!all && !(plug.IsValid() && plug.IsEnabled()))
if( (plugType & PluginTypeEffect) != 0) { continue;
auto plugType = plug.GetPluginType();
if ((mPluginType == PluginTypeNone || (plugType & mPluginType)) &&
(mEffectType == EffectTypeNone || plug.GetEffectType() == mEffectType)) {
if (!all && (plugType & PluginTypeEffect)) {
// This preference may be written by EffectsPrefs // This preference may be written by EffectsPrefs
auto setting = GetPluginEnabledSetting( plug ); auto setting = mPm.GetPluginEnabledSetting( plug );
familyEnabled = setting.empty() if (!(setting.empty() || gPrefs->Read( setting, true )))
? true continue;
: gPrefs->Read( setting, true );
} }
if (familyEnabled) // Pause iteration at this match
return &mPluginsIter->second; break;
} }
} }
return NULL;
} }
const PluginDescriptor *PluginManager::GetNextPlugin(int type) PluginManager::Iterator::Iterator(PluginManager &manager)
: mPm{ manager }
, mIterator{ manager.mPlugins.begin() }
{ {
while (++mPluginsIter != mPlugins.end())
{
PluginDescriptor & plug = mPluginsIter->second;
PluginType plugType = plug.GetPluginType();
if( plug.IsValid() && plug.IsEnabled() && ((plugType & type) != 0))
{
bool familyEnabled = true;
if( (plugType & PluginTypeEffect) != 0) {
// This preference may be written by EffectsPrefs
auto setting = GetPluginEnabledSetting( plug );
familyEnabled = setting.empty()
? true
: gPrefs->Read( setting, true );
}
if (familyEnabled)
return &mPluginsIter->second;
}
}
return NULL;
} }
const PluginDescriptor *PluginManager::GetFirstPluginForEffectType(EffectType type) PluginManager::Iterator::Iterator(PluginManager &manager, int type)
: mPm{ manager }
, mIterator{ manager.mPlugins.begin() }
, mPluginType{ type }
{ {
for (mPluginsIter = mPlugins.begin(); mPluginsIter != mPlugins.end(); ++mPluginsIter) Advance(false);
{
PluginDescriptor & plug = mPluginsIter->second;
bool familyEnabled;
// This preference may be written by EffectsPrefs
auto setting = GetPluginEnabledSetting( plug );
familyEnabled = setting.empty()
? true
: gPrefs->Read( setting, true );
if (plug.IsValid() && plug.IsEnabled() && plug.GetEffectType() == type && familyEnabled)
{
return &plug;
}
}
return NULL;
} }
const PluginDescriptor *PluginManager::GetNextPluginForEffectType(EffectType type) PluginManager::Iterator::Iterator(PluginManager &manager, EffectType type)
: mPm{ manager }
, mIterator{ manager.mPlugins.begin() }
, mEffectType{ type }
{ {
while (++mPluginsIter != mPlugins.end()) Advance(false);
{ }
PluginDescriptor & plug = mPluginsIter->second;
bool familyEnabled;
// This preference may be written by EffectsPrefs
auto setting = GetPluginEnabledSetting( plug );
familyEnabled = setting.empty()
? true
: gPrefs->Read( setting, true );
if (plug.IsValid() && plug.IsEnabled() && plug.GetEffectType() == type && familyEnabled)
{
return &plug;
}
}
return NULL; auto PluginManager::Iterator::operator ++() -> Iterator &
{
Advance(true);
return *this;
} }
bool PluginManager::IsPluginEnabled(const PluginID & ID) bool PluginManager::IsPluginEnabled(const PluginID & ID)

View File

@ -30,8 +30,7 @@ class FileConfig;
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
typedef enum typedef enum : unsigned {
{
PluginTypeNone = 0, // 2.1.0 placeholder entries...not used by 2.1.1 or greater PluginTypeNone = 0, // 2.1.0 placeholder entries...not used by 2.1.1 or greater
PluginTypeStub =1, // Used for plugins that have not yet been registered PluginTypeStub =1, // Used for plugins that have not yet been registered
PluginTypeEffect =1<<1, PluginTypeEffect =1<<1,
@ -173,8 +172,8 @@ class AUDACITY_DLL_API PluginManager final : public PluginManagerInterface
{ {
public: public:
RegistryPath GetPluginEnabledSetting( const PluginID &ID ); RegistryPath GetPluginEnabledSetting( const PluginID &ID ) const;
RegistryPath GetPluginEnabledSetting( const PluginDescriptor &desc ); RegistryPath GetPluginEnabledSetting( const PluginDescriptor &desc ) const;
// PluginManagerInterface implementation // PluginManagerInterface implementation
@ -246,13 +245,42 @@ public:
static wxString GetPluginTypeString(PluginType type); static wxString GetPluginTypeString(PluginType type);
int GetPluginCount(PluginType type); int GetPluginCount(PluginType type);
const PluginDescriptor *GetPlugin(const PluginID & ID); const PluginDescriptor *GetPlugin(const PluginID & ID) const;
const PluginDescriptor *GetFirstPlugin(int type); // possible or of several PlugInTypes. //! @name iteration over plugins of certain types, supporting range-for syntax
const PluginDescriptor *GetNextPlugin( int type); //! @{
class Iterator {
public:
//! Iterates all, even disabled
explicit Iterator(PluginManager &manager);
//! Iterates only enabled and matching plugins, with family enabled too if an effect
Iterator(PluginManager &manager,
int pluginType //!< bitwise or of values in PluginType
);
//! Iterates only enabled and matching effects, with family enabled too
Iterator(PluginManager &manager, EffectType type);
bool operator != (int) const {
return mIterator != mPm.mPlugins.end();
}
Iterator &operator ++ ();
auto &operator *() const { return mIterator->second; }
private:
void Advance(bool incrementing);
const PluginManager &mPm;
PluginMap::iterator mIterator;
EffectType mEffectType{ EffectTypeNone };
int mPluginType{ PluginTypeNone };
};
struct Range {
Iterator first;
Iterator begin() const { return first; }
int end() const { return 0; }
};
const PluginDescriptor *GetFirstPluginForEffectType(EffectType type); Range AllPlugins() { return { Iterator{ *this } }; }
const PluginDescriptor *GetNextPluginForEffectType(EffectType type); Range PluginsOfType(int type) { return { Iterator{ *this, type } }; }
Range EffectsOfType(EffectType type) { return { Iterator{ *this, type } }; }
//! @}
bool IsPluginEnabled(const PluginID & ID); bool IsPluginEnabled(const PluginID & ID);
void EnablePlugin(const PluginID & ID, bool enable); void EnablePlugin(const PluginID & ID, bool enable);
@ -267,17 +295,19 @@ public:
//! Used only by Nyquist Workbench module //! Used only by Nyquist Workbench module
const PluginID & RegisterPlugin( const PluginID & RegisterPlugin(
std::unique_ptr<EffectDefinitionInterface> effect, PluginType type ); std::unique_ptr<EffectDefinitionInterface> effect, PluginType type );
//! Used only by Nyquist Workbench module
void UnregisterPlugin(const PluginID & ID); void UnregisterPlugin(const PluginID & ID);
//! Load from preferences
void Load();
//! Save to preferences
void Save();
private: private:
// private! Use Get() // private! Use Get()
PluginManager(); PluginManager();
~PluginManager(); ~PluginManager();
void Load();
void LoadGroup(FileConfig *pRegistry, PluginType type); void LoadGroup(FileConfig *pRegistry, PluginType type);
void Save();
void SaveGroup(FileConfig *pRegistry, PluginType type); void SaveGroup(FileConfig *pRegistry, PluginType type);
PluginDescriptor & CreatePlugin(const PluginID & id, ComponentInterface *ident, PluginType type); PluginDescriptor & CreatePlugin(const PluginID & id, ComponentInterface *ident, PluginType type);
@ -324,9 +354,6 @@ private:
int mCurrentIndex; int mCurrentIndex;
PluginMap mPlugins; PluginMap mPlugins;
PluginMap::iterator mPluginsIter;
friend class PluginRegistrationDialog;
}; };
// Defining these special names in the low-level PluginManager.h // Defining these special names in the low-level PluginManager.h

View File

@ -416,14 +416,12 @@ bool GetInfoCommand::SendCommands(const CommandContext &context, int flags )
PluginManager & pm = PluginManager::Get(); PluginManager & pm = PluginManager::Get();
EffectManager & em = EffectManager::Get(); EffectManager & em = EffectManager::Get();
{ {
const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect | PluginTypeAudacityCommand); for (auto &plug
while (plug) : pm.PluginsOfType(PluginTypeEffect | PluginTypeAudacityCommand)) {
{ auto command = em.GetCommandIdentifier(plug.GetID());
auto command = em.GetCommandIdentifier(plug->GetID());
if (!command.empty()){ if (!command.empty()){
em.GetCommandDefinition( plug->GetID(), context, flags ); em.GetCommandDefinition( plug.GetID(), context, flags );
} }
plug = pm.GetNextPlugin(PluginTypeEffect | PluginTypeAudacityCommand );
} }
} }
context.EndArray(); context.EndArray();

View File

@ -826,15 +826,12 @@ const PluginID & EffectManager::GetEffectByIdentifier(const CommandID & strTarge
PluginManager & pm = PluginManager::Get(); PluginManager & pm = PluginManager::Get();
// Effects OR Generic commands... // Effects OR Generic commands...
const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect | PluginTypeAudacityCommand); for (auto &plug
while (plug) : pm.PluginsOfType(PluginTypeEffect | PluginTypeAudacityCommand)) {
{ auto &ID = plug.GetID();
if (GetCommandIdentifier(plug->GetID()) == strTarget) if (GetCommandIdentifier(ID) == strTarget)
{ return ID;
return plug->GetID();
}
plug = pm.GetNextPlugin(PluginTypeEffect | PluginTypeAudacityCommand);
} }
return empty;; return empty;
} }

View File

@ -302,9 +302,8 @@ MenuTable::BaseItemPtrs PopulateEffectsMenu(
std::vector<const PluginDescriptor*> optplugs; std::vector<const PluginDescriptor*> optplugs;
EffectManager & em = EffectManager::Get(); EffectManager & em = EffectManager::Get();
const PluginDescriptor *plug = pm.GetFirstPluginForEffectType(type); for (auto &plugin : pm.EffectsOfType(type)) {
while (plug) auto plug = &plugin;
{
if( plug->IsInstantiated() && em.IsHidden(plug->GetID()) ) if( plug->IsInstantiated() && em.IsHidden(plug->GetID()) )
continue; continue;
if ( !plug->IsEnabled() ){ if ( !plug->IsEnabled() ){
@ -322,7 +321,6 @@ MenuTable::BaseItemPtrs PopulateEffectsMenu(
defplugs.push_back(plug); defplugs.push_back(plug);
else else
optplugs.push_back(plug); optplugs.push_back(plug);
plug = pm.GetNextPluginForEffectType(type);
} }
wxString groupby = EffectsGroupBy.Read(); wxString groupby = EffectsGroupBy.Read();

View File

@ -137,10 +137,8 @@ static const std::vector< Entry > &GetModuleData()
struct ModuleData : public std::vector< Entry > { struct ModuleData : public std::vector< Entry > {
ModuleData() { ModuleData() {
auto &pm = PluginManager::Get(); auto &pm = PluginManager::Get();
for (auto plug = pm.GetFirstPlugin(PluginTypeModule); for (auto &plug : pm.PluginsOfType(PluginTypeModule)) {
plug; auto internal = plug.GetEffectFamily();
plug = pm.GetNextPlugin(PluginTypeModule)) {
auto internal = plug->GetEffectFamily();
if ( internal.empty() ) if ( internal.empty() )
continue; continue;
@ -153,11 +151,11 @@ static const std::vector< Entry > &GetModuleData()
// If there should be new modules, it is not important for them // If there should be new modules, it is not important for them
// to follow the " Effects" convention, but instead they can // to follow the " Effects" convention, but instead they can
// have shorter msgids. // have shorter msgids.
prompt = plug->GetSymbol().Msgid(); prompt = plug.GetSymbol().Msgid();
else else
prompt = iter->second; prompt = iter->second;
auto setting = pm.GetPluginEnabledSetting( *plug ); auto setting = pm.GetPluginEnabledSetting( plug );
push_back( { prompt, setting } ); push_back( { prompt, setting } );
} }