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;
}
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;
void getAllTypes (OwnedArray<PluginDescription>&);
void getAllTypes (Array<PluginDescription>&);
//==============================================================================
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 ({},
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);
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)


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

@@ -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)];
}
//==============================================================================


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

@@ -87,7 +87,7 @@ public:
void createPlugin (const PluginDescription&, Point<int> 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<PluginDescription> internalTypes;
Array<PluginDescription> internalTypes;
KnownPluginList knownPluginList;
KnownPluginList::SortMethod pluginSortMethod;


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

@@ -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


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

@@ -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.


+ 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);
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);
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)
@@ -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<CustomScanner> 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<PluginDescription*> oldOrder, newOrder;
Array<PluginDescription> 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<XmlElement> 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<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) == ":")
path = path.substring (2);
@@ -400,16 +425,16 @@ struct PluginTreeUtils
}
static void buildTreeByCategory (KnownPluginList::PluginTree& tree,
const Array<PluginDescription*>& sorted,
const Array<PluginDescription>& sorted,
const KnownPluginList::SortMethod sortMethod)
{
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())
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<KnownPluginList::PluginTree>();
}
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<const PluginDescription*>& plugins, const String& name)
static bool containsDuplicateNames (const Array<PluginDescription>& 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<PluginDescription>& allPlugins,
const Array<PluginDescription>& 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::PluginTree> KnownPluginList::createTree (const SortMethod sortMethod) const
{
Array<PluginDescription*> sorted;
Array<PluginDescription> 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<PluginTree>();
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<PluginTree> tree (createTree (sortMethod));
auto tree = createTree (sortMethod);
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. */
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. */
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.
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<PluginDescription> 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<PluginTree> subFolders;
Array<const PluginDescription*> plugins;
Array<PluginDescription> 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 */
@@ -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<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:
//==============================================================================
OwnedArray<PluginDescription> types;
Array<PluginDescription> types;
StringArray blacklist;
std::unique_ptr<CustomScanner> scanner;
CriticalSection scanLock, typesArrayLock;


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

@@ -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()]);
}


Loading…
Cancel
Save