mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Deprecated some thread unsafe methods in KnownPluginList and modernised the interface a bit
This commit is contained in:
parent
ab9656f6fb
commit
92a9c37bac
10 changed files with 180 additions and 199 deletions
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
PluginDescription audioInDesc, audioOutDesc, midiInDesc;
|
||||
|
||||
void getAllTypes (OwnedArray<PluginDescription>&);
|
||||
void getAllTypes (Array<PluginDescription>&);
|
||||
|
||||
//==============================================================================
|
||||
String getName() const override { return "Internal"; }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)];
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -41,26 +41,38 @@ void KnownPluginList::clear()
|
|||
}
|
||||
}
|
||||
|
||||
PluginDescription* KnownPluginList::getTypeForFile (const String& fileOrIdentifier) const
|
||||
int KnownPluginList::getNumTypes() const noexcept
|
||||
{
|
||||
ScopedLock lock (typesArrayLock);
|
||||
|
||||
for (auto* desc : types)
|
||||
if (desc->fileOrIdentifier == fileOrIdentifier)
|
||||
return desc;
|
||||
|
||||
return nullptr;
|
||||
return types.size();
|
||||
}
|
||||
|
||||
PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& identifierString) const
|
||||
Array<PluginDescription> KnownPluginList::getTypes() const
|
||||
{
|
||||
ScopedLock lock (typesArrayLock);
|
||||
return types;
|
||||
}
|
||||
|
||||
std::unique_ptr<PluginDescription> KnownPluginList::getTypeForFile (const String& fileOrIdentifier) const
|
||||
{
|
||||
ScopedLock lock (typesArrayLock);
|
||||
|
||||
for (auto* desc : types)
|
||||
if (desc->matchesIdentifierString (identifierString))
|
||||
return desc;
|
||||
for (auto& desc : types)
|
||||
if (desc.fileOrIdentifier == fileOrIdentifier)
|
||||
return std::make_unique<PluginDescription> (desc);
|
||||
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<PluginDescription> KnownPluginList::getTypeForIdentifierString (const String& identifierString) const
|
||||
{
|
||||
ScopedLock lock (typesArrayLock);
|
||||
|
||||
for (auto& desc : types)
|
||||
if (desc.matchesIdentifierString (identifierString))
|
||||
return std::make_unique<PluginDescription> (desc);
|
||||
|
||||
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)
|
||||
{
|
||||
auto name = plugin->name;
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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…
Add table
Add a link
Reference in a new issue