From 92a9c37bac9b19d653f8a434c0257ccc7275edd4 Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 23 May 2019 14:01:01 +0100 Subject: [PATCH] Deprecated some thread unsafe methods in KnownPluginList and modernised the interface a bit --- .../Source/Filters/InternalFilters.cpp | 8 +- .../Source/Filters/InternalFilters.h | 3 +- .../Source/UI/GraphEditorPanel.cpp | 13 +- .../Source/UI/MainHostWindow.cpp | 21 +-- .../Source/UI/MainHostWindow.h | 4 +- .../processors/juce_PluginDescription.cpp | 51 ------ .../processors/juce_PluginDescription.h | 18 +- .../scanning/juce_KnownPluginList.cpp | 173 +++++++++++------- .../scanning/juce_KnownPluginList.h | 48 +++-- .../scanning/juce_PluginListComponent.cpp | 36 ++-- 10 files changed, 178 insertions(+), 197 deletions(-) diff --git a/extras/AudioPluginHost/Source/Filters/InternalFilters.cpp b/extras/AudioPluginHost/Source/Filters/InternalFilters.cpp index e2f9632872..d2a785bcf9 100644 --- a/extras/AudioPluginHost/Source/Filters/InternalFilters.cpp +++ b/extras/AudioPluginHost/Source/Filters/InternalFilters.cpp @@ -389,11 +389,7 @@ bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const P return false; } -void InternalPluginFormat::getAllTypes (OwnedArray& results) +void InternalPluginFormat::getAllTypes (Array& 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()); } diff --git a/extras/AudioPluginHost/Source/Filters/InternalFilters.h b/extras/AudioPluginHost/Source/Filters/InternalFilters.h index e0b26a2a8d..2838de4a57 100644 --- a/extras/AudioPluginHost/Source/Filters/InternalFilters.h +++ b/extras/AudioPluginHost/Source/Filters/InternalFilters.h @@ -42,8 +42,7 @@ public: //============================================================================== PluginDescription audioInDesc, audioOutDesc, midiInDesc; - - void getAllTypes (OwnedArray&); + void getAllTypes (Array&); //============================================================================== String getName() const override { return "Internal"; } diff --git a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp index e8d7d47378..418582c4a3 100644 --- a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp +++ b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp @@ -844,9 +844,9 @@ void GraphEditorPanel::showPopupMenu (Point mousePos) menu->showMenuAsync ({}, ModalCallbackFunction::create ([this, mousePos] (int r) { - if (auto* mainWin = findParentComponentOfClass()) - if (auto* desc = mainWin->getChosenType (r)) - createNewPlugin (*desc, mousePos); + if (r > 0) + if (auto* mainWin = findParentComponentOfClass()) + createNewPlugin (mainWin->getChosenType (r), mousePos); })); } } @@ -1114,10 +1114,7 @@ struct GraphDocumentComponent::PluginListBoxModel : public ListBoxModel, g.setColour (rowIsSelected ? Colours::black : Colours::white); 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.drawRect (0, height - 1, width, 1); @@ -1283,7 +1280,7 @@ void GraphDocumentComponent::itemDropped (const SourceDetails& details) // must be a valid index! jassert (isPositiveAndBelow (pluginTypeIndex, pluginList.getNumTypes())); - createNewPlugin (*pluginList.getType (pluginTypeIndex), details.localPosition); + createNewPlugin (pluginList.getTypes()[pluginTypeIndex], details.localPosition); } void GraphDocumentComponent::showSidePanel (bool showSettingsPanel) diff --git a/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp b/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp index 3d60c104bf..dfd99c2fd8 100644 --- a/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp +++ b/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp @@ -111,8 +111,8 @@ MainHostWindow::MainHostWindow() if (auto savedPluginList = getAppProperties().getUserSettings()->getXmlValue ("pluginList")) knownPluginList.recreateFromXml (*savedPluginList); - for (auto* t : internalTypes) - knownPluginList.addType (*t); + for (auto& t : internalTypes) + knownPluginList.addType (t); pluginSortMethod = (KnownPluginList::SortMethod) getAppProperties().getUserSettings() ->getIntValue ("pluginSortMethod", KnownPluginList::sortByManufacturer); @@ -346,10 +346,9 @@ void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/ } 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; - 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(); @@ -381,12 +380,12 @@ void MainHostWindow::addPluginsToMenu (PopupMenu& m) const 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()) return internalTypes [menuID - 1]; - return knownPluginList.getType (knownPluginList.getIndexChosenByMenu (menuID)); + return knownPluginList.getTypes()[knownPluginList.getIndexChosenByMenu (menuID)]; } //============================================================================== diff --git a/extras/AudioPluginHost/Source/UI/MainHostWindow.h b/extras/AudioPluginHost/Source/UI/MainHostWindow.h index 8ca9e21517..a0711a67e0 100644 --- a/extras/AudioPluginHost/Source/UI/MainHostWindow.h +++ b/extras/AudioPluginHost/Source/UI/MainHostWindow.h @@ -87,7 +87,7 @@ public: void createPlugin (const PluginDescription&, Point pos); void addPluginsToMenu (PopupMenu&) const; - const PluginDescription* getChosenType (int menuID) const; + PluginDescription getChosenType (int menuID) const; bool isDoublePrecisionProcessing(); void updatePrecisionMenuItem (ApplicationCommandInfo& info); @@ -99,7 +99,7 @@ private: AudioDeviceManager deviceManager; AudioPluginFormatManager formatManager; - OwnedArray internalTypes; + Array internalTypes; KnownPluginList knownPluginList; KnownPluginList::SortMethod pluginSortMethod; diff --git a/modules/juce_audio_processors/processors/juce_PluginDescription.cpp b/modules/juce_audio_processors/processors/juce_PluginDescription.cpp index 7acab70fc6..b023b80420 100644 --- a/modules/juce_audio_processors/processors/juce_PluginDescription.cpp +++ b/modules/juce_audio_processors/processors/juce_PluginDescription.cpp @@ -27,57 +27,6 @@ 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 { return fileOrIdentifier == other.fileOrIdentifier diff --git a/modules/juce_audio_processors/processors/juce_PluginDescription.h b/modules/juce_audio_processors/processors/juce_PluginDescription.h index 219c28c80a..5129a8b7c6 100644 --- a/modules/juce_audio_processors/processors/juce_PluginDescription.h +++ b/modules/juce_audio_processors/processors/juce_PluginDescription.h @@ -44,10 +44,10 @@ class JUCE_API PluginDescription { 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. */ @@ -96,19 +96,19 @@ public: @see createIdentifierString */ - int uid; + int uid = 0; /** True if the plug-in identifies itself as a synthesiser. */ - bool isInstrument; + bool isInstrument = false; /** The number of inputs. */ - int numInputChannels; + int numInputChannels = 0; /** 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. */ - bool hasSharedContainer; + bool hasSharedContainer = false; /** Returns true if the two descriptions refer to the same plug-in. diff --git a/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp b/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp index 15b70213f1..7b0adf4739 100644 --- a/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp +++ b/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp @@ -41,26 +41,38 @@ void KnownPluginList::clear() } } -PluginDescription* KnownPluginList::getTypeForFile (const String& fileOrIdentifier) const +int KnownPluginList::getNumTypes() const noexcept { ScopedLock lock (typesArrayLock); + return types.size(); +} + +Array KnownPluginList::getTypes() const +{ + ScopedLock lock (typesArrayLock); + return types; +} - for (auto* desc : types) - if (desc->fileOrIdentifier == fileOrIdentifier) - return desc; +std::unique_ptr KnownPluginList::getTypeForFile (const String& fileOrIdentifier) const +{ + ScopedLock lock (typesArrayLock); + + for (auto& desc : types) + if (desc.fileOrIdentifier == fileOrIdentifier) + return std::make_unique (desc); - return nullptr; + return {}; } -PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& identifierString) const +std::unique_ptr KnownPluginList::getTypeForIdentifierString (const String& identifierString) const { 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 (desc); - return nullptr; + return {}; } bool KnownPluginList::addType (const PluginDescription& type) @@ -68,31 +80,34 @@ bool KnownPluginList::addType (const PluginDescription& type) { 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.. - 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; } } - types.insert (0, new PluginDescription (type)); + types.insert (0, type); } sendChangeMessage(); return true; } -void KnownPluginList::removeType (const int index) +void KnownPluginList::removeType (const PluginDescription& type) { { ScopedLock lock (typesArrayLock); - types.remove (index); + + for (auto& desc : types) + if (desc.isDuplicateOf (type)) + types.remove (&desc); } sendChangeMessage(); @@ -106,16 +121,17 @@ bool KnownPluginList::isListingUpToDate (const String& fileOrIdentifier, 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 true; } -void KnownPluginList::setCustomScanner (CustomScanner* newScanner) +void KnownPluginList::setCustomScanner (std::unique_ptr newScanner) { - scanner.reset (newScanner); + if (scanner != newScanner) + scanner = std::move (newScanner); } bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier, @@ -132,14 +148,14 @@ bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier, 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; else - typesFound.add (new PluginDescription (*d)); + typesFound.add (new PluginDescription (d)); } } @@ -198,7 +214,7 @@ void KnownPluginList::scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& f if (! found) { - const File f (filenameOrID); + File f (filenameOrID); if (f.isDirectory()) { @@ -261,22 +277,22 @@ struct PluginSorter PluginSorter (KnownPluginList::SortMethod sortMethod, bool forwards) noexcept : 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; 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; } if (diff == 0) - diff = first->name.compareNatural (second->name, false); + diff = first.name.compareNatural (second.name, false); return diff * direction < 0; } @@ -303,7 +319,7 @@ void KnownPluginList::sort (const SortMethod method, bool forwards) { if (method != defaultOrder) { - Array oldOrder, newOrder; + Array oldOrder, newOrder; { ScopedLock lock (typesArrayLock); @@ -313,7 +329,16 @@ void KnownPluginList::sort (const SortMethod method, bool forwards) 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(); } } @@ -327,7 +352,7 @@ std::unique_ptr KnownPluginList::createXml() const ScopedLock lock (typesArrayLock); 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) @@ -360,12 +385,12 @@ struct PluginTreeUtils { enum { menuIdBase = 0x324503f4 }; - static void buildTreeByFolder (KnownPluginList::PluginTree& tree, const Array& allPlugins) + static void buildTreeByFolder (KnownPluginList::PluginTree& tree, const Array& 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) == ":") path = path.substring (2); @@ -400,16 +425,16 @@ struct PluginTreeUtils } static void buildTreeByCategory (KnownPluginList::PluginTree& tree, - const Array& sorted, + const Array& sorted, const KnownPluginList::SortMethod sortMethod) { String lastType; - std::unique_ptr current (new KnownPluginList::PluginTree()); + auto current = std::make_unique(); - 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()) thisType = "Other"; @@ -420,7 +445,7 @@ struct PluginTreeUtils { current->folder = lastType; tree.subFolders.add (std::move (current)); - current.reset (new KnownPluginList::PluginTree()); + current = std::make_unique(); } 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()) { @@ -454,7 +479,7 @@ struct PluginTreeUtils 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)) { @@ -463,27 +488,26 @@ struct PluginTreeUtils } } - auto newFolder = new KnownPluginList::PluginTree(); + auto* newFolder = new KnownPluginList::PluginTree(); newFolder->folder = firstSubFolder; tree.subFolders.add (newFolder); addPlugin (*newFolder, pd, remainingPath); } } - static bool containsDuplicateNames (const Array& plugins, const String& name) + static bool containsDuplicateNames (const Array& plugins, const String& name) { 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; } static bool addToMenu (const KnownPluginList::PluginTree& tree, PopupMenu& m, - const OwnedArray& allPlugins, + const Array& allPlugins, const String& currentlyTickedPluginID) { bool isTicked = false; @@ -491,32 +515,47 @@ struct PluginTreeUtils for (auto* sub : tree.subFolders) { PopupMenu subMenu; - const bool isItemTicked = addToMenu (*sub, subMenu, allPlugins, currentlyTickedPluginID); + auto isItemTicked = addToMenu (*sub, subMenu, allPlugins, currentlyTickedPluginID); isTicked = isTicked || isItemTicked; 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)) - name << " (" << plugin->pluginFormatName << ')'; + name << " (" << plugin.pluginFormatName << ')'; - const bool isItemTicked = plugin->matchesIdentifierString (currentlyTickedPluginID); + auto isItemTicked = plugin.matchesIdentifierString (currentlyTickedPluginID); isTicked = isTicked || isItemTicked; - m.addItem (allPlugins.indexOf (plugin) + menuIdBase, name, true, isItemTicked); + m.addItem (getPluginMenuIndex (plugin), name, true, isItemTicked); } return isTicked; } }; -KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortMethod) const +std::unique_ptr KnownPluginList::createTree (const SortMethod sortMethod) const { - Array sorted; + Array sorted; { ScopedLock lock (typesArrayLock); @@ -525,7 +564,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM std::stable_sort (sorted.begin(), sorted.end(), PluginSorter (sortMethod, true)); - auto* tree = new PluginTree(); + auto tree = std::make_unique(); if (sortMethod == sortByCategory || sortMethod == sortByManufacturer || sortMethod == sortByFormat) { @@ -537,7 +576,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM } else { - for (auto* p : sorted) + for (auto& p : sorted) tree->plugins.add (p); } @@ -548,7 +587,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM void KnownPluginList::addToMenu (PopupMenu& menu, const SortMethod sortMethod, const String& currentlyTickedPluginID) const { - std::unique_ptr tree (createTree (sortMethod)); + auto tree = createTree (sortMethod); PluginTreeUtils::addToMenu (*tree, menu, types, currentlyTickedPluginID); } diff --git a/modules/juce_audio_processors/scanning/juce_KnownPluginList.h b/modules/juce_audio_processors/scanning/juce_KnownPluginList.h index 7adf88162c..aa0eea9b29 100644 --- a/modules/juce_audio_processors/scanning/juce_KnownPluginList.h +++ b/modules/juce_audio_processors/scanning/juce_KnownPluginList.h @@ -52,37 +52,27 @@ public: /** Clears the list. */ 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 getTypes() const; /** Looks for a type in the list which comes from this file. */ - PluginDescription* getTypeForFile (const String& fileOrIdentifier) const; + std::unique_ptr getTypeForFile (const String& fileOrIdentifier) const; /** Looks for a type in the list which matches a plugin type ID. The identifierString parameter must have been created by 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 getTypeForIdentifierString (const String& identifierString) const; /** Looks for all types that can be loaded from a given file, and adds them to the list. @@ -153,7 +143,7 @@ public: Use getIndexChosenByMenu() to find out the type that was chosen. */ 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. 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 */ OwnedArray subFolders; - Array plugins; + Array plugins; }; /** Creates a PluginTree object containing all the known plugins. */ - PluginTree* createTree (const SortMethod sortMethod) const; + std::unique_ptr createTree (const SortMethod sortMethod) const; //============================================================================== /** Class to define a custom plugin scanner */ @@ -214,11 +204,19 @@ public: /** Supplies a custom scanner to be used in future scans. The KnownPluginList will take ownership of the object passed in. */ - void setCustomScanner (CustomScanner*); + void setCustomScanner (std::unique_ptr 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: //============================================================================== - OwnedArray types; + Array types; StringArray blacklist; std::unique_ptr scanner; CriticalSection scanLock, typesArrayLock; diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index f6f9894ad9..2b68ea5330 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -67,15 +67,17 @@ public: else if (columnId == descCol) 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) { - 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; } @@ -238,30 +240,32 @@ void PluginListComponent::setTableModel (TableListBoxModel* model) 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() { 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() { - 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) { if (index < list.getNumTypes()) - list.removeType (index); + list.removeType (list.getTypes()[index]); else list.removeFromBlacklist (list.getBlacklistedFiles() [index - list.getNumTypes()]); }