Browse Source

Deprecated some thread unsafe methods in KnownPluginList and modernised the interface a bit

tags/2021-05-28
ed 6 years ago
parent
commit
92a9c37bac
10 changed files with 178 additions and 197 deletions
  1. +2
    -6
      extras/AudioPluginHost/Source/Filters/InternalFilters.cpp
  2. +1
    -2
      extras/AudioPluginHost/Source/Filters/InternalFilters.h
  3. +5
    -8
      extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp
  4. +10
    -11
      extras/AudioPluginHost/Source/UI/MainHostWindow.cpp
  5. +2
    -2
      extras/AudioPluginHost/Source/UI/MainHostWindow.h
  6. +0
    -51
      modules/juce_audio_processors/processors/juce_PluginDescription.cpp
  7. +9
    -9
      modules/juce_audio_processors/processors/juce_PluginDescription.h
  8. +106
    -67
      modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp
  9. +23
    -25
      modules/juce_audio_processors/scanning/juce_KnownPluginList.h
  10. +20
    -16
      modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp

+ 2
- 6
extras/AudioPluginHost/Source/Filters/InternalFilters.cpp View File

@@ -389,11 +389,7 @@ bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const P
return false; return false;
} }
void InternalPluginFormat::getAllTypes (OwnedArray<PluginDescription>& results)
void InternalPluginFormat::getAllTypes (Array<PluginDescription>& results)
{ {
results.add (new PluginDescription (audioInDesc));
results.add (new PluginDescription (audioOutDesc));
results.add (new PluginDescription (midiInDesc));
results.add (new PluginDescription (SineWaveSynth::getPluginDescription()));
results.add (new PluginDescription (ReverbFilter::getPluginDescription()));
results.add (audioInDesc, audioOutDesc, midiInDesc, SineWaveSynth::getPluginDescription(), ReverbFilter::getPluginDescription());
} }

+ 1
- 2
extras/AudioPluginHost/Source/Filters/InternalFilters.h View File

@@ -42,8 +42,7 @@ public:
//============================================================================== //==============================================================================
PluginDescription audioInDesc, audioOutDesc, midiInDesc; PluginDescription audioInDesc, audioOutDesc, midiInDesc;
void getAllTypes (OwnedArray<PluginDescription>&);
void getAllTypes (Array<PluginDescription>&);
//============================================================================== //==============================================================================
String getName() const override { return "Internal"; } String getName() const override { return "Internal"; }


+ 5
- 8
extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp View File

@@ -844,9 +844,9 @@ void GraphEditorPanel::showPopupMenu (Point<int> mousePos)
menu->showMenuAsync ({}, menu->showMenuAsync ({},
ModalCallbackFunction::create ([this, mousePos] (int r) ModalCallbackFunction::create ([this, mousePos] (int r)
{ {
if (auto* mainWin = findParentComponentOfClass<MainHostWindow>())
if (auto* desc = mainWin->getChosenType (r))
createNewPlugin (*desc, mousePos);
if (r > 0)
if (auto* mainWin = findParentComponentOfClass<MainHostWindow>())
createNewPlugin (mainWin->getChosenType (r), mousePos);
})); }));
} }
} }
@@ -1114,10 +1114,7 @@ struct GraphDocumentComponent::PluginListBoxModel : public ListBoxModel,
g.setColour (rowIsSelected ? Colours::black : Colours::white); g.setColour (rowIsSelected ? Colours::black : Colours::white);
if (rowNumber < knownPlugins.getNumTypes()) if (rowNumber < knownPlugins.getNumTypes())
g.drawFittedText (knownPlugins.getType (rowNumber)->name,
{ 0, 0, width, height - 2 },
Justification::centred,
1);
g.drawFittedText (knownPlugins.getTypes()[rowNumber].name, { 0, 0, width, height - 2 }, Justification::centred, 1);
g.setColour (Colours::black.withAlpha (0.4f)); g.setColour (Colours::black.withAlpha (0.4f));
g.drawRect (0, height - 1, width, 1); g.drawRect (0, height - 1, width, 1);
@@ -1283,7 +1280,7 @@ void GraphDocumentComponent::itemDropped (const SourceDetails& details)
// must be a valid index! // must be a valid index!
jassert (isPositiveAndBelow (pluginTypeIndex, pluginList.getNumTypes())); jassert (isPositiveAndBelow (pluginTypeIndex, pluginList.getNumTypes()));
createNewPlugin (*pluginList.getType (pluginTypeIndex), details.localPosition);
createNewPlugin (pluginList.getTypes()[pluginTypeIndex], details.localPosition);
} }
void GraphDocumentComponent::showSidePanel (bool showSettingsPanel) void GraphDocumentComponent::showSidePanel (bool showSettingsPanel)


+ 10
- 11
extras/AudioPluginHost/Source/UI/MainHostWindow.cpp View File

@@ -111,8 +111,8 @@ MainHostWindow::MainHostWindow()
if (auto savedPluginList = getAppProperties().getUserSettings()->getXmlValue ("pluginList")) if (auto savedPluginList = getAppProperties().getUserSettings()->getXmlValue ("pluginList"))
knownPluginList.recreateFromXml (*savedPluginList); knownPluginList.recreateFromXml (*savedPluginList);
for (auto* t : internalTypes)
knownPluginList.addType (*t);
for (auto& t : internalTypes)
knownPluginList.addType (t);
pluginSortMethod = (KnownPluginList::SortMethod) getAppProperties().getUserSettings() pluginSortMethod = (KnownPluginList::SortMethod) getAppProperties().getUserSettings()
->getIntValue ("pluginSortMethod", KnownPluginList::sortByManufacturer); ->getIntValue ("pluginSortMethod", KnownPluginList::sortByManufacturer);
@@ -346,10 +346,9 @@ void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/
} }
else else
{ {
if (auto* desc = getChosenType (menuItemID))
createPlugin (*desc,
{ proportionOfWidth (0.3f + Random::getSystemRandom().nextFloat() * 0.6f),
proportionOfHeight (0.3f + Random::getSystemRandom().nextFloat() * 0.6f) });
if (knownPluginList.getIndexChosenByMenu (menuItemID) >= 0)
createPlugin (getChosenType (menuItemID), { proportionOfWidth (0.3f + Random::getSystemRandom().nextFloat() * 0.6f),
proportionOfHeight (0.3f + Random::getSystemRandom().nextFloat() * 0.6f) });
} }
} }
@@ -371,9 +370,9 @@ void MainHostWindow::addPluginsToMenu (PopupMenu& m) const
{ {
int i = 0; int i = 0;
for (auto* t : internalTypes)
m.addItem (++i, t->name + " (" + t->pluginFormatName + ")",
graphHolder->graph->getNodeForName (t->name) == nullptr);
for (auto& t : internalTypes)
m.addItem (++i, t.name + " (" + t.pluginFormatName + ")",
graphHolder->graph->getNodeForName (t.name) == nullptr);
} }
m.addSeparator(); m.addSeparator();
@@ -381,12 +380,12 @@ void MainHostWindow::addPluginsToMenu (PopupMenu& m) const
knownPluginList.addToMenu (m, pluginSortMethod); knownPluginList.addToMenu (m, pluginSortMethod);
} }
const PluginDescription* MainHostWindow::getChosenType (const int menuID) const
PluginDescription MainHostWindow::getChosenType (const int menuID) const
{ {
if (menuID >= 1 && menuID < 1 + internalTypes.size()) if (menuID >= 1 && menuID < 1 + internalTypes.size())
return internalTypes [menuID - 1]; return internalTypes [menuID - 1];
return knownPluginList.getType (knownPluginList.getIndexChosenByMenu (menuID));
return knownPluginList.getTypes()[knownPluginList.getIndexChosenByMenu (menuID)];
} }
//============================================================================== //==============================================================================


+ 2
- 2
extras/AudioPluginHost/Source/UI/MainHostWindow.h View File

@@ -87,7 +87,7 @@ public:
void createPlugin (const PluginDescription&, Point<int> pos); void createPlugin (const PluginDescription&, Point<int> pos);
void addPluginsToMenu (PopupMenu&) const; void addPluginsToMenu (PopupMenu&) const;
const PluginDescription* getChosenType (int menuID) const;
PluginDescription getChosenType (int menuID) const;
bool isDoublePrecisionProcessing(); bool isDoublePrecisionProcessing();
void updatePrecisionMenuItem (ApplicationCommandInfo& info); void updatePrecisionMenuItem (ApplicationCommandInfo& info);
@@ -99,7 +99,7 @@ private:
AudioDeviceManager deviceManager; AudioDeviceManager deviceManager;
AudioPluginFormatManager formatManager; AudioPluginFormatManager formatManager;
OwnedArray<PluginDescription> internalTypes;
Array<PluginDescription> internalTypes;
KnownPluginList knownPluginList; KnownPluginList knownPluginList;
KnownPluginList::SortMethod pluginSortMethod; KnownPluginList::SortMethod pluginSortMethod;


+ 0
- 51
modules/juce_audio_processors/processors/juce_PluginDescription.cpp View File

@@ -27,57 +27,6 @@
namespace juce namespace juce
{ {
PluginDescription::PluginDescription()
: uid (0),
isInstrument (false),
numInputChannels (0),
numOutputChannels (0),
hasSharedContainer (false)
{
}
PluginDescription::~PluginDescription()
{
}
PluginDescription::PluginDescription (const PluginDescription& other)
: name (other.name),
descriptiveName (other.descriptiveName),
pluginFormatName (other.pluginFormatName),
category (other.category),
manufacturerName (other.manufacturerName),
version (other.version),
fileOrIdentifier (other.fileOrIdentifier),
lastFileModTime (other.lastFileModTime),
lastInfoUpdateTime (other.lastInfoUpdateTime),
uid (other.uid),
isInstrument (other.isInstrument),
numInputChannels (other.numInputChannels),
numOutputChannels (other.numOutputChannels),
hasSharedContainer (other.hasSharedContainer)
{
}
PluginDescription& PluginDescription::operator= (const PluginDescription& other)
{
name = other.name;
descriptiveName = other.descriptiveName;
pluginFormatName = other.pluginFormatName;
category = other.category;
manufacturerName = other.manufacturerName;
version = other.version;
fileOrIdentifier = other.fileOrIdentifier;
uid = other.uid;
isInstrument = other.isInstrument;
lastFileModTime = other.lastFileModTime;
lastInfoUpdateTime = other.lastInfoUpdateTime;
numInputChannels = other.numInputChannels;
numOutputChannels = other.numOutputChannels;
hasSharedContainer = other.hasSharedContainer;
return *this;
}
bool PluginDescription::isDuplicateOf (const PluginDescription& other) const noexcept bool PluginDescription::isDuplicateOf (const PluginDescription& other) const noexcept
{ {
return fileOrIdentifier == other.fileOrIdentifier return fileOrIdentifier == other.fileOrIdentifier


+ 9
- 9
modules/juce_audio_processors/processors/juce_PluginDescription.h View File

@@ -44,10 +44,10 @@ class JUCE_API PluginDescription
{ {
public: public:
//============================================================================== //==============================================================================
PluginDescription();
PluginDescription (const PluginDescription& other);
PluginDescription& operator= (const PluginDescription& other);
~PluginDescription();
PluginDescription() = default;
PluginDescription (const PluginDescription& other) = default;
PluginDescription& operator= (const PluginDescription& other) = default;
//============================================================================== //==============================================================================
/** The name of the plug-in. */ /** The name of the plug-in. */
@@ -96,19 +96,19 @@ public:
@see createIdentifierString @see createIdentifierString
*/ */
int uid;
int uid = 0;
/** True if the plug-in identifies itself as a synthesiser. */ /** True if the plug-in identifies itself as a synthesiser. */
bool isInstrument;
bool isInstrument = false;
/** The number of inputs. */ /** The number of inputs. */
int numInputChannels;
int numInputChannels = 0;
/** The number of outputs. */ /** The number of outputs. */
int numOutputChannels;
int numOutputChannels = 0;
/** True if the plug-in is part of a multi-type container, e.g. a VST Shell. */ /** True if the plug-in is part of a multi-type container, e.g. a VST Shell. */
bool hasSharedContainer;
bool hasSharedContainer = false;
/** Returns true if the two descriptions refer to the same plug-in. /** Returns true if the two descriptions refer to the same plug-in.


+ 106
- 67
modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp View File

@@ -41,26 +41,38 @@ void KnownPluginList::clear()
} }
} }
PluginDescription* KnownPluginList::getTypeForFile (const String& fileOrIdentifier) const
int KnownPluginList::getNumTypes() const noexcept
{ {
ScopedLock lock (typesArrayLock); ScopedLock lock (typesArrayLock);
return types.size();
}
Array<PluginDescription> KnownPluginList::getTypes() const
{
ScopedLock lock (typesArrayLock);
return types;
}
for (auto* desc : types)
if (desc->fileOrIdentifier == fileOrIdentifier)
return desc;
std::unique_ptr<PluginDescription> KnownPluginList::getTypeForFile (const String& fileOrIdentifier) const
{
ScopedLock lock (typesArrayLock);
for (auto& desc : types)
if (desc.fileOrIdentifier == fileOrIdentifier)
return std::make_unique<PluginDescription> (desc);
return nullptr;
return {};
} }
PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& identifierString) const
std::unique_ptr<PluginDescription> KnownPluginList::getTypeForIdentifierString (const String& identifierString) const
{ {
ScopedLock lock (typesArrayLock); ScopedLock lock (typesArrayLock);
for (auto* desc : types)
if (desc->matchesIdentifierString (identifierString))
return desc;
for (auto& desc : types)
if (desc.matchesIdentifierString (identifierString))
return std::make_unique<PluginDescription> (desc);
return nullptr;
return {};
} }
bool KnownPluginList::addType (const PluginDescription& type) bool KnownPluginList::addType (const PluginDescription& type)
@@ -68,31 +80,34 @@ bool KnownPluginList::addType (const PluginDescription& type)
{ {
ScopedLock lock (typesArrayLock); ScopedLock lock (typesArrayLock);
for (auto* desc : types)
for (auto& desc : types)
{ {
if (desc->isDuplicateOf (type))
if (desc.isDuplicateOf (type))
{ {
// strange - found a duplicate plugin with different info.. // strange - found a duplicate plugin with different info..
jassert (desc->name == type.name);
jassert (desc->isInstrument == type.isInstrument);
jassert (desc.name == type.name);
jassert (desc.isInstrument == type.isInstrument);
*desc = type;
desc = type;
return false; return false;
} }
} }
types.insert (0, new PluginDescription (type));
types.insert (0, type);
} }
sendChangeMessage(); sendChangeMessage();
return true; return true;
} }
void KnownPluginList::removeType (const int index)
void KnownPluginList::removeType (const PluginDescription& type)
{ {
{ {
ScopedLock lock (typesArrayLock); ScopedLock lock (typesArrayLock);
types.remove (index);
for (auto& desc : types)
if (desc.isDuplicateOf (type))
types.remove (&desc);
} }
sendChangeMessage(); sendChangeMessage();
@@ -106,16 +121,17 @@ bool KnownPluginList::isListingUpToDate (const String& fileOrIdentifier,
ScopedLock lock (typesArrayLock); ScopedLock lock (typesArrayLock);
for (auto* d : types)
if (d->fileOrIdentifier == fileOrIdentifier && formatToUse.pluginNeedsRescanning (*d))
for (auto& d : types)
if (d.fileOrIdentifier == fileOrIdentifier && formatToUse.pluginNeedsRescanning (d))
return false; return false;
return true; return true;
} }
void KnownPluginList::setCustomScanner (CustomScanner* newScanner)
void KnownPluginList::setCustomScanner (std::unique_ptr<CustomScanner> newScanner)
{ {
scanner.reset (newScanner);
if (scanner != newScanner)
scanner = std::move (newScanner);
} }
bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier, bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier,
@@ -132,14 +148,14 @@ bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier,
ScopedLock lock (typesArrayLock); ScopedLock lock (typesArrayLock);
for (auto* d : types)
for (auto& d : types)
{ {
if (d->fileOrIdentifier == fileOrIdentifier && d->pluginFormatName == format.getName())
if (d.fileOrIdentifier == fileOrIdentifier && d.pluginFormatName == format.getName())
{ {
if (format.pluginNeedsRescanning (*d))
if (format.pluginNeedsRescanning (d))
needsRescanning = true; needsRescanning = true;
else else
typesFound.add (new PluginDescription (*d));
typesFound.add (new PluginDescription (d));
} }
} }
@@ -198,7 +214,7 @@ void KnownPluginList::scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& f
if (! found) if (! found)
{ {
const File f (filenameOrID);
File f (filenameOrID);
if (f.isDirectory()) if (f.isDirectory())
{ {
@@ -261,22 +277,22 @@ struct PluginSorter
PluginSorter (KnownPluginList::SortMethod sortMethod, bool forwards) noexcept PluginSorter (KnownPluginList::SortMethod sortMethod, bool forwards) noexcept
: method (sortMethod), direction (forwards ? 1 : -1) {} : method (sortMethod), direction (forwards ? 1 : -1) {}
bool operator() (const PluginDescription* first, const PluginDescription* second) const
bool operator() (const PluginDescription& first, const PluginDescription& second) const
{ {
int diff = 0; int diff = 0;
switch (method) switch (method)
{ {
case KnownPluginList::sortByCategory: diff = first->category.compareNatural (second->category, false); break;
case KnownPluginList::sortByManufacturer: diff = first->manufacturerName.compareNatural (second->manufacturerName, false); break;
case KnownPluginList::sortByFormat: diff = first->pluginFormatName.compare (second->pluginFormatName); break;
case KnownPluginList::sortByFileSystemLocation: diff = lastPathPart (first->fileOrIdentifier).compare (lastPathPart (second->fileOrIdentifier)); break;
case KnownPluginList::sortByInfoUpdateTime: diff = compare (first->lastInfoUpdateTime, second->lastInfoUpdateTime); break;
case KnownPluginList::sortByCategory: diff = first.category.compareNatural (second.category, false); break;
case KnownPluginList::sortByManufacturer: diff = first.manufacturerName.compareNatural (second.manufacturerName, false); break;
case KnownPluginList::sortByFormat: diff = first.pluginFormatName.compare (second.pluginFormatName); break;
case KnownPluginList::sortByFileSystemLocation: diff = lastPathPart (first.fileOrIdentifier).compare (lastPathPart (second.fileOrIdentifier)); break;
case KnownPluginList::sortByInfoUpdateTime: diff = compare (first.lastInfoUpdateTime, second.lastInfoUpdateTime); break;
default: break; default: break;
} }
if (diff == 0) if (diff == 0)
diff = first->name.compareNatural (second->name, false);
diff = first.name.compareNatural (second.name, false);
return diff * direction < 0; return diff * direction < 0;
} }
@@ -303,7 +319,7 @@ void KnownPluginList::sort (const SortMethod method, bool forwards)
{ {
if (method != defaultOrder) if (method != defaultOrder)
{ {
Array<PluginDescription*> oldOrder, newOrder;
Array<PluginDescription> oldOrder, newOrder;
{ {
ScopedLock lock (typesArrayLock); ScopedLock lock (typesArrayLock);
@@ -313,7 +329,16 @@ void KnownPluginList::sort (const SortMethod method, bool forwards)
newOrder.addArray (types); newOrder.addArray (types);
} }
if (oldOrder != newOrder)
auto hasOrderChanged = [&]
{
for (int i = 0; i < oldOrder.size(); ++i)
if (! oldOrder[i].isDuplicateOf (newOrder[i]))
return true;
return false;
}();
if (hasOrderChanged)
sendChangeMessage(); sendChangeMessage();
} }
} }
@@ -327,7 +352,7 @@ std::unique_ptr<XmlElement> KnownPluginList::createXml() const
ScopedLock lock (typesArrayLock); ScopedLock lock (typesArrayLock);
for (int i = types.size(); --i >= 0;) for (int i = types.size(); --i >= 0;)
e->prependChildElement (types.getUnchecked(i)->createXml().release());
e->prependChildElement (types.getUnchecked (i).createXml().release());
} }
for (auto& b : blacklist) for (auto& b : blacklist)
@@ -360,12 +385,12 @@ struct PluginTreeUtils
{ {
enum { menuIdBase = 0x324503f4 }; enum { menuIdBase = 0x324503f4 };
static void buildTreeByFolder (KnownPluginList::PluginTree& tree, const Array<PluginDescription*>& allPlugins)
static void buildTreeByFolder (KnownPluginList::PluginTree& tree, const Array<PluginDescription>& allPlugins)
{ {
for (auto* pd : allPlugins)
for (auto& pd : allPlugins)
{ {
auto path = pd->fileOrIdentifier.replaceCharacter ('\\', '/')
.upToLastOccurrenceOf ("/", false, false);
auto path = pd.fileOrIdentifier.replaceCharacter ('\\', '/')
.upToLastOccurrenceOf ("/", false, false);
if (path.substring (1, 2) == ":") if (path.substring (1, 2) == ":")
path = path.substring (2); path = path.substring (2);
@@ -400,16 +425,16 @@ struct PluginTreeUtils
} }
static void buildTreeByCategory (KnownPluginList::PluginTree& tree, static void buildTreeByCategory (KnownPluginList::PluginTree& tree,
const Array<PluginDescription*>& sorted,
const Array<PluginDescription>& sorted,
const KnownPluginList::SortMethod sortMethod) const KnownPluginList::SortMethod sortMethod)
{ {
String lastType; String lastType;
std::unique_ptr<KnownPluginList::PluginTree> current (new KnownPluginList::PluginTree());
auto current = std::make_unique<KnownPluginList::PluginTree>();
for (auto* pd : sorted)
for (auto& pd : sorted)
{ {
auto thisType = (sortMethod == KnownPluginList::sortByCategory ? pd->category
: pd->manufacturerName);
auto thisType = (sortMethod == KnownPluginList::sortByCategory ? pd.category
: pd.manufacturerName);
if (! thisType.containsNonWhitespaceChars()) if (! thisType.containsNonWhitespaceChars())
thisType = "Other"; thisType = "Other";
@@ -420,7 +445,7 @@ struct PluginTreeUtils
{ {
current->folder = lastType; current->folder = lastType;
tree.subFolders.add (std::move (current)); tree.subFolders.add (std::move (current));
current.reset (new KnownPluginList::PluginTree());
current = std::make_unique<KnownPluginList::PluginTree>();
} }
lastType = thisType; lastType = thisType;
@@ -436,7 +461,7 @@ struct PluginTreeUtils
} }
} }
static void addPlugin (KnownPluginList::PluginTree& tree, PluginDescription* const pd, String path)
static void addPlugin (KnownPluginList::PluginTree& tree, PluginDescription pd, String path)
{ {
if (path.isEmpty()) if (path.isEmpty())
{ {
@@ -454,7 +479,7 @@ struct PluginTreeUtils
for (int i = tree.subFolders.size(); --i >= 0;) for (int i = tree.subFolders.size(); --i >= 0;)
{ {
KnownPluginList::PluginTree& subFolder = *tree.subFolders.getUnchecked(i);
auto& subFolder = *tree.subFolders.getUnchecked (i);
if (subFolder.folder.equalsIgnoreCase (firstSubFolder)) if (subFolder.folder.equalsIgnoreCase (firstSubFolder))
{ {
@@ -463,27 +488,26 @@ struct PluginTreeUtils
} }
} }
auto newFolder = new KnownPluginList::PluginTree();
auto* newFolder = new KnownPluginList::PluginTree();
newFolder->folder = firstSubFolder; newFolder->folder = firstSubFolder;
tree.subFolders.add (newFolder); tree.subFolders.add (newFolder);
addPlugin (*newFolder, pd, remainingPath); addPlugin (*newFolder, pd, remainingPath);
} }
} }
static bool containsDuplicateNames (const Array<const PluginDescription*>& plugins, const String& name)
static bool containsDuplicateNames (const Array<PluginDescription>& plugins, const String& name)
{ {
int matches = 0; int matches = 0;
for (int i = 0; i < plugins.size(); ++i)
if (plugins.getUnchecked(i)->name == name)
if (++matches > 1)
return true;
for (auto& p : plugins)
if (p.name == name && ++matches > 1)
return true;
return false; return false;
} }
static bool addToMenu (const KnownPluginList::PluginTree& tree, PopupMenu& m, static bool addToMenu (const KnownPluginList::PluginTree& tree, PopupMenu& m,
const OwnedArray<PluginDescription>& allPlugins,
const Array<PluginDescription>& allPlugins,
const String& currentlyTickedPluginID) const String& currentlyTickedPluginID)
{ {
bool isTicked = false; bool isTicked = false;
@@ -491,32 +515,47 @@ struct PluginTreeUtils
for (auto* sub : tree.subFolders) for (auto* sub : tree.subFolders)
{ {
PopupMenu subMenu; PopupMenu subMenu;
const bool isItemTicked = addToMenu (*sub, subMenu, allPlugins, currentlyTickedPluginID);
auto isItemTicked = addToMenu (*sub, subMenu, allPlugins, currentlyTickedPluginID);
isTicked = isTicked || isItemTicked; isTicked = isTicked || isItemTicked;
m.addSubMenu (sub->folder, subMenu, true, nullptr, isItemTicked, 0); m.addSubMenu (sub->folder, subMenu, true, nullptr, isItemTicked, 0);
} }
for (auto* plugin : tree.plugins)
auto getPluginMenuIndex = [&] (const PluginDescription& d)
{
int i = 0;
for (auto& p : allPlugins)
{
if (p.isDuplicateOf (d))
return i + menuIdBase;
++i;
}
return 0;
};
for (auto& plugin : tree.plugins)
{ {
auto name = plugin->name;
auto name = plugin.name;
if (containsDuplicateNames (tree.plugins, name)) if (containsDuplicateNames (tree.plugins, name))
name << " (" << plugin->pluginFormatName << ')';
name << " (" << plugin.pluginFormatName << ')';
const bool isItemTicked = plugin->matchesIdentifierString (currentlyTickedPluginID);
auto isItemTicked = plugin.matchesIdentifierString (currentlyTickedPluginID);
isTicked = isTicked || isItemTicked; isTicked = isTicked || isItemTicked;
m.addItem (allPlugins.indexOf (plugin) + menuIdBase, name, true, isItemTicked);
m.addItem (getPluginMenuIndex (plugin), name, true, isItemTicked);
} }
return isTicked; return isTicked;
} }
}; };
KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortMethod) const
std::unique_ptr<KnownPluginList::PluginTree> KnownPluginList::createTree (const SortMethod sortMethod) const
{ {
Array<PluginDescription*> sorted;
Array<PluginDescription> sorted;
{ {
ScopedLock lock (typesArrayLock); ScopedLock lock (typesArrayLock);
@@ -525,7 +564,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM
std::stable_sort (sorted.begin(), sorted.end(), PluginSorter (sortMethod, true)); std::stable_sort (sorted.begin(), sorted.end(), PluginSorter (sortMethod, true));
auto* tree = new PluginTree();
auto tree = std::make_unique<PluginTree>();
if (sortMethod == sortByCategory || sortMethod == sortByManufacturer || sortMethod == sortByFormat) if (sortMethod == sortByCategory || sortMethod == sortByManufacturer || sortMethod == sortByFormat)
{ {
@@ -537,7 +576,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM
} }
else else
{ {
for (auto* p : sorted)
for (auto& p : sorted)
tree->plugins.add (p); tree->plugins.add (p);
} }
@@ -548,7 +587,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM
void KnownPluginList::addToMenu (PopupMenu& menu, const SortMethod sortMethod, void KnownPluginList::addToMenu (PopupMenu& menu, const SortMethod sortMethod,
const String& currentlyTickedPluginID) const const String& currentlyTickedPluginID) const
{ {
std::unique_ptr<PluginTree> tree (createTree (sortMethod));
auto tree = createTree (sortMethod);
PluginTreeUtils::addToMenu (*tree, menu, types, currentlyTickedPluginID); PluginTreeUtils::addToMenu (*tree, menu, types, currentlyTickedPluginID);
} }


+ 23
- 25
modules/juce_audio_processors/scanning/juce_KnownPluginList.h View File

@@ -52,37 +52,27 @@ public:
/** Clears the list. */ /** Clears the list. */
void clear(); void clear();
/** Returns the number of types currently in the list.
@see getType
*/
int getNumTypes() const noexcept { return types.size(); }
/** Adds a type manually from its description. */
bool addType (const PluginDescription& type);
/** Returns one of the types.
@see getNumTypes
*/
PluginDescription* getType (int index) const noexcept { return types [index]; }
/** Removes a type. */
void removeType (const PluginDescription& type);
/** Type iteration. */
PluginDescription** begin() const noexcept { return types.begin(); }
/** Returns the number of types currently in the list. */
int getNumTypes() const noexcept;
/** Type iteration. */
PluginDescription** end() const noexcept { return types.end(); }
/** Returns a copy of the current list. */
Array<PluginDescription> getTypes() const;
/** Looks for a type in the list which comes from this file. */ /** Looks for a type in the list which comes from this file. */
PluginDescription* getTypeForFile (const String& fileOrIdentifier) const;
std::unique_ptr<PluginDescription> getTypeForFile (const String& fileOrIdentifier) const;
/** Looks for a type in the list which matches a plugin type ID. /** Looks for a type in the list which matches a plugin type ID.
The identifierString parameter must have been created by The identifierString parameter must have been created by
PluginDescription::createIdentifierString(). PluginDescription::createIdentifierString().
*/ */
PluginDescription* getTypeForIdentifierString (const String& identifierString) const;
/** Adds a type manually from its description. */
bool addType (const PluginDescription& type);
/** Removes a type. */
void removeType (int index);
std::unique_ptr<PluginDescription> getTypeForIdentifierString (const String& identifierString) const;
/** Looks for all types that can be loaded from a given file, and adds them /** Looks for all types that can be loaded from a given file, and adds them
to the list. to the list.
@@ -153,7 +143,7 @@ public:
Use getIndexChosenByMenu() to find out the type that was chosen. Use getIndexChosenByMenu() to find out the type that was chosen.
*/ */
void addToMenu (PopupMenu& menu, SortMethod sortMethod, void addToMenu (PopupMenu& menu, SortMethod sortMethod,
const String& currentlyTickedPluginID = String()) const;
const String& currentlyTickedPluginID = {}) const;
/** Converts a menu item index that has been chosen into its index in this list. /** Converts a menu item index that has been chosen into its index in this list.
Returns -1 if it's not an ID that was used. Returns -1 if it's not an ID that was used.
@@ -180,11 +170,11 @@ public:
{ {
String folder; /**< The name of this folder in the tree */ String folder; /**< The name of this folder in the tree */
OwnedArray<PluginTree> subFolders; OwnedArray<PluginTree> subFolders;
Array<const PluginDescription*> plugins;
Array<PluginDescription> plugins;
}; };
/** Creates a PluginTree object containing all the known plugins. */ /** Creates a PluginTree object containing all the known plugins. */
PluginTree* createTree (const SortMethod sortMethod) const;
std::unique_ptr<PluginTree> createTree (const SortMethod sortMethod) const;
//============================================================================== //==============================================================================
/** Class to define a custom plugin scanner */ /** Class to define a custom plugin scanner */
@@ -214,11 +204,19 @@ public:
/** Supplies a custom scanner to be used in future scans. /** Supplies a custom scanner to be used in future scans.
The KnownPluginList will take ownership of the object passed in. The KnownPluginList will take ownership of the object passed in.
*/ */
void setCustomScanner (CustomScanner*);
void setCustomScanner (std::unique_ptr<CustomScanner> newScanner);
//==============================================================================
// These methods have been deprecated! When getting the list of plugin types you should instead use
// the getTypes() method which returns a copy of the internal PluginDescription array and can be accessed
// in a thread-safe way.
JUCE_DEPRECATED_WITH_BODY (PluginDescription* getType (int index) const noexcept, { return &types.getReference (index); })
JUCE_DEPRECATED_WITH_BODY (PluginDescription** begin() const noexcept, { jassertfalse; return nullptr; })
JUCE_DEPRECATED_WITH_BODY (PluginDescription** end() const noexcept, { jassertfalse; return nullptr; })
private: private:
//============================================================================== //==============================================================================
OwnedArray<PluginDescription> types;
Array<PluginDescription> types;
StringArray blacklist; StringArray blacklist;
std::unique_ptr<CustomScanner> scanner; std::unique_ptr<CustomScanner> scanner;
CriticalSection scanLock, typesArrayLock; CriticalSection scanLock, typesArrayLock;


+ 20
- 16
modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp View File

@@ -67,15 +67,17 @@ public:
else if (columnId == descCol) else if (columnId == descCol)
text = TRANS("Deactivated after failing to initialise correctly"); text = TRANS("Deactivated after failing to initialise correctly");
} }
else if (const PluginDescription* const desc = list.getType (row))
else
{ {
auto desc = list.getTypes()[row];
switch (columnId) switch (columnId)
{ {
case nameCol: text = desc->name; break;
case typeCol: text = desc->pluginFormatName; break;
case categoryCol: text = desc->category.isNotEmpty() ? desc->category : "-"; break;
case manufacturerCol: text = desc->manufacturerName; break;
case descCol: text = getPluginDescription (*desc); break;
case nameCol: text = desc.name; break;
case typeCol: text = desc.pluginFormatName; break;
case categoryCol: text = desc.category.isNotEmpty() ? desc.category : "-"; break;
case manufacturerCol: text = desc.manufacturerName; break;
case descCol: text = getPluginDescription (desc); break;
default: jassertfalse; break; default: jassertfalse; break;
} }
@@ -238,30 +240,32 @@ void PluginListComponent::setTableModel (TableListBoxModel* model)
bool PluginListComponent::canShowSelectedFolder() const bool PluginListComponent::canShowSelectedFolder() const
{ {
if (const PluginDescription* const desc = list.getType (table.getSelectedRow()))
return File::createFileWithoutCheckingPath (desc->fileOrIdentifier).exists();
return false;
return File::createFileWithoutCheckingPath (list.getTypes()[table.getSelectedRow()].fileOrIdentifier).exists();
} }
void PluginListComponent::showSelectedFolder() void PluginListComponent::showSelectedFolder()
{ {
if (canShowSelectedFolder()) if (canShowSelectedFolder())
if (const PluginDescription* const desc = list.getType (table.getSelectedRow()))
File (desc->fileOrIdentifier).getParentDirectory().startAsProcess();
File (list.getTypes()[table.getSelectedRow()].fileOrIdentifier).getParentDirectory().startAsProcess();
} }
void PluginListComponent::removeMissingPlugins() void PluginListComponent::removeMissingPlugins()
{ {
for (int i = list.getNumTypes(); --i >= 0;)
if (! formatManager.doesPluginStillExist (*list.getType (i)))
list.removeType (i);
auto types = list.getTypes();
for (int i = types.size(); --i >= 0;)
{
auto type = types.getUnchecked (i);
if (! formatManager.doesPluginStillExist (type))
list.removeType (type);
}
} }
void PluginListComponent::removePluginItem (int index) void PluginListComponent::removePluginItem (int index)
{ {
if (index < list.getNumTypes()) if (index < list.getNumTypes())
list.removeType (index);
list.removeType (list.getTypes()[index]);
else else
list.removeFromBlacklist (list.getBlacklistedFiles() [index - list.getNumTypes()]); list.removeFromBlacklist (list.getBlacklistedFiles() [index - list.getNumTypes()]);
} }


Loading…
Cancel
Save