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();
EffectManager & em = EffectManager::Get();
{
const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect|PluginTypeAudacityCommand);
while (plug)
{
auto command = em.GetCommandIdentifier(plug->GetID());
for (auto &plug
: pm.PluginsOfType(PluginTypeEffect|PluginTypeAudacityCommand)) {
auto command = em.GetCommandIdentifier(plug.GetID());
if (!command.empty())
commands.push_back( {
{ command, plug->GetSymbol().Msgid() },
plug->GetPluginType() == PluginTypeEffect ?
{ command, plug.GetSymbol().Msgid() },
plug.GetPluginType() == PluginTypeEffect ?
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.
// We could/should try all the list-style commands.
// instead we only try the effects.
PluginManager & pm = PluginManager::Get();
EffectManager & em = EffectManager::Get();
const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect);
while (plug)
{
if (em.GetCommandIdentifier(plug->GetID()) == Str)
{
for (auto &plug : PluginManager::Get().PluginsOfType(PluginTypeEffect))
if (em.GetCommandIdentifier(plug.GetID()) == Str)
return EffectUI::DoEffect(
plug->GetID(), context,
plug.GetID(), context,
EffectManager::kConfigured);
}
plug = pm.GetNextPlugin(PluginTypeEffect);
}
return false;
}

View File

@ -627,15 +627,10 @@ void PluginRegistrationDialog::PopulateOrExchange(ShuttleGui &S)
}
PluginManager & pm = PluginManager::Get();
for (PluginMap::iterator iter = pm.mPlugins.begin(); iter != pm.mPlugins.end(); ++iter)
{
PluginDescriptor & plug = iter->second;
for (auto &plug : pm.AllPlugins()) {
PluginType plugType = plug.GetPluginType();
if (plugType != PluginTypeEffect && plugType != PluginTypeStub)
{
continue;
}
const auto &path = plug.GetPath();
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,
errMsg))
{
for (size_t k = 0, cntk = item.plugs.size(); k < cntk; k++)
{
pm.mPlugins.erase(item.plugs[k]->GetProviderID() + wxT("_") + path);
}
for (auto plug : item.plugs)
pm.UnregisterPlugin(
plug->GetProviderID() + wxT("_") + path);
// Bug 1893. We've found a provider that works.
// Error messages from any that failed are no longer useful.
errMsgs = {};
@ -1047,19 +1041,14 @@ void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
XO("Effect or Command at %s failed to register:\n%s")
.Format( path, errMsgs ) );
}
else if (item.state == STATE_New)
{
for (size_t j = 0, cnt = item.plugs.size(); j < cnt; j++)
{
item.plugs[j]->SetValid(false);
}
else if (item.state == STATE_New) {
for (auto plug : item.plugs)
plug->SetValid(false);
}
else if (item.state != STATE_New)
{
for (size_t j = 0, cnt = item.plugs.size(); j < cnt; j++)
{
item.plugs[j]->SetEnabled(item.state == STATE_Enabled);
item.plugs[j]->SetValid(item.valid);
else if (item.state != STATE_New) {
for (auto plug : item.plugs) {
plug->SetEnabled(item.state == STATE_Enabled);
plug->SetValid(item.valid);
}
}
}
@ -1388,7 +1377,7 @@ const PluginID &PluginManagerInterface::AudacityCommandRegistrationCallback(
return empty;
}
RegistryPath PluginManager::GetPluginEnabledSetting( const PluginID &ID )
RegistryPath PluginManager::GetPluginEnabledSetting( const PluginID &ID ) const
{
auto pPlugin = GetPlugin( ID );
if ( pPlugin )
@ -1397,7 +1386,7 @@ RegistryPath PluginManager::GetPluginEnabledSetting( const PluginID &ID )
}
RegistryPath PluginManager::GetPluginEnabledSetting(
const PluginDescriptor &desc )
const PluginDescriptor &desc ) const
{
switch ( desc.GetPluginType() ) {
case PluginTypeModule: {
@ -1802,12 +1791,9 @@ bool PluginManager::DropFile(const wxString &fileName)
auto &mm = ModuleManager::Get();
const wxFileName src{ fileName };
for (const PluginDescriptor *plug = GetFirstPlugin(PluginTypeModule);
plug;
plug = GetNextPlugin(PluginTypeModule))
{
for (auto &plug : PluginsOfType(PluginTypeModule)) {
auto module = static_cast<ModuleInterface *>
(mm.CreateProviderInstance(plug->GetID(), plug->GetPath()));
(mm.CreateProviderInstance(plug.GetID(), plug.GetPath()));
if (! module)
continue;
@ -2483,8 +2469,6 @@ const PluginID & PluginManager::RegisterPlugin(
return plug.GetID();
}
// Here solely for the purpose of Nyquist Workbench until
// a better solution is devised.
void PluginManager::UnregisterPlugin(const PluginID & ID)
{
mPlugins.erase(ID);
@ -2496,7 +2480,7 @@ int PluginManager::GetPluginCount(PluginType 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())
return nullptr;
@ -2504,93 +2488,57 @@ const PluginDescriptor *PluginManager::GetPlugin(const PluginID & ID)
return &iter->second;
}
const PluginDescriptor *PluginManager::GetFirstPlugin(int type)
void PluginManager::Iterator::Advance(bool incrementing)
{
for (mPluginsIter = mPlugins.begin(); mPluginsIter != mPlugins.end(); ++mPluginsIter)
{
PluginDescriptor & plug = mPluginsIter->second;
PluginType plugType = plug.GetPluginType();
if( plug.IsValid() && plug.IsEnabled() && ((plugType & type) != 0))
{
bool familyEnabled = true;
if( (plugType & PluginTypeEffect) != 0) {
const auto end = mPm.mPlugins.end();
if (incrementing && mIterator != end)
++mIterator;
bool all = mPluginType == PluginTypeNone && mEffectType == EffectTypeNone;
for (; mIterator != end; ++mIterator) {
auto &plug = mIterator->second;
if (!all && !(plug.IsValid() && plug.IsEnabled()))
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
auto setting = GetPluginEnabledSetting( plug );
familyEnabled = setting.empty()
? true
: gPrefs->Read( setting, true );
auto setting = mPm.GetPluginEnabledSetting( plug );
if (!(setting.empty() || gPrefs->Read( setting, true )))
continue;
}
if (familyEnabled)
return &mPluginsIter->second;
// Pause iteration at this match
break;
}
}
return NULL;
}
const PluginDescriptor *PluginManager::GetNextPlugin(int type)
{
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;
PluginManager::Iterator::Iterator(PluginManager &manager)
: mPm{ manager }
, mIterator{ manager.mPlugins.begin() }
{
}
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)
{
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;
Advance(false);
}
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())
{
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;
}
}
Advance(false);
}
return NULL;
auto PluginManager::Iterator::operator ++() -> Iterator &
{
Advance(true);
return *this;
}
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
PluginTypeStub =1, // Used for plugins that have not yet been registered
PluginTypeEffect =1<<1,
@ -173,8 +172,8 @@ class AUDACITY_DLL_API PluginManager final : public PluginManagerInterface
{
public:
RegistryPath GetPluginEnabledSetting( const PluginID &ID );
RegistryPath GetPluginEnabledSetting( const PluginDescriptor &desc );
RegistryPath GetPluginEnabledSetting( const PluginID &ID ) const;
RegistryPath GetPluginEnabledSetting( const PluginDescriptor &desc ) const;
// PluginManagerInterface implementation
@ -246,13 +245,42 @@ public:
static wxString GetPluginTypeString(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.
const PluginDescriptor *GetNextPlugin( int type);
//! @name iteration over plugins of certain types, supporting range-for syntax
//! @{
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);
const PluginDescriptor *GetNextPluginForEffectType(EffectType type);
Range AllPlugins() { return { Iterator{ *this } }; }
Range PluginsOfType(int type) { return { Iterator{ *this, type } }; }
Range EffectsOfType(EffectType type) { return { Iterator{ *this, type } }; }
//! @}
bool IsPluginEnabled(const PluginID & ID);
void EnablePlugin(const PluginID & ID, bool enable);
@ -267,17 +295,19 @@ public:
//! Used only by Nyquist Workbench module
const PluginID & RegisterPlugin(
std::unique_ptr<EffectDefinitionInterface> effect, PluginType type );
//! Used only by Nyquist Workbench module
void UnregisterPlugin(const PluginID & ID);
//! Load from preferences
void Load();
//! Save to preferences
void Save();
private:
// private! Use Get()
PluginManager();
~PluginManager();
void Load();
void LoadGroup(FileConfig *pRegistry, PluginType type);
void Save();
void SaveGroup(FileConfig *pRegistry, PluginType type);
PluginDescriptor & CreatePlugin(const PluginID & id, ComponentInterface *ident, PluginType type);
@ -324,9 +354,6 @@ private:
int mCurrentIndex;
PluginMap mPlugins;
PluginMap::iterator mPluginsIter;
friend class PluginRegistrationDialog;
};
// 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();
EffectManager & em = EffectManager::Get();
{
const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect | PluginTypeAudacityCommand);
while (plug)
{
auto command = em.GetCommandIdentifier(plug->GetID());
for (auto &plug
: pm.PluginsOfType(PluginTypeEffect | PluginTypeAudacityCommand)) {
auto command = em.GetCommandIdentifier(plug.GetID());
if (!command.empty()){
em.GetCommandDefinition( plug->GetID(), context, flags );
em.GetCommandDefinition( plug.GetID(), context, flags );
}
plug = pm.GetNextPlugin(PluginTypeEffect | PluginTypeAudacityCommand );
}
}
context.EndArray();

View File

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

View File

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

View File

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