mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Plugin scanning: added a custom scanner callback, and added an option to run the scan on a background thread.
This commit is contained in:
parent
c559b332d1
commit
6ce0c2e433
4 changed files with 112 additions and 27 deletions
|
|
@ -68,7 +68,7 @@ bool KnownPluginList::addType (const PluginDescription& type)
|
|||
}
|
||||
}
|
||||
|
||||
types.add (new PluginDescription (type));
|
||||
types.insert (0, new PluginDescription (type));
|
||||
sendChangeMessage();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -116,6 +116,11 @@ bool KnownPluginList::isListingUpToDate (const String& fileOrIdentifier) const
|
|||
return true;
|
||||
}
|
||||
|
||||
void KnownPluginList::setCustomScanner (CustomScanner* newScanner)
|
||||
{
|
||||
scanner = newScanner;
|
||||
}
|
||||
|
||||
bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier,
|
||||
const bool dontRescanIfAlreadyInList,
|
||||
OwnedArray <PluginDescription>& typesFound,
|
||||
|
|
@ -147,7 +152,11 @@ bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier,
|
|||
return false;
|
||||
|
||||
OwnedArray <PluginDescription> found;
|
||||
format.findAllTypesForFile (found, fileOrIdentifier);
|
||||
|
||||
if (scanner != nullptr)
|
||||
scanner->findPluginTypesFor (format, found, fileOrIdentifier);
|
||||
else
|
||||
format.findAllTypesForFile (found, fileOrIdentifier);
|
||||
|
||||
for (int i = 0; i < found.size(); ++i)
|
||||
{
|
||||
|
|
@ -167,29 +176,39 @@ void KnownPluginList::scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& f
|
|||
{
|
||||
for (int i = 0; i < files.size(); ++i)
|
||||
{
|
||||
const String filenameOrID (files[i]);
|
||||
bool found = false;
|
||||
|
||||
for (int j = 0; j < formatManager.getNumFormats(); ++j)
|
||||
{
|
||||
AudioPluginFormat* const format = formatManager.getFormat (j);
|
||||
|
||||
if (scanAndAddFile (files[i], true, typesFound, *format))
|
||||
return;
|
||||
if (format->fileMightContainThisPluginType (filenameOrID)
|
||||
&& scanAndAddFile (filenameOrID, true, typesFound, *format))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const File f (files[i]);
|
||||
|
||||
if (f.isDirectory())
|
||||
if (! found)
|
||||
{
|
||||
StringArray s;
|
||||
const File f (filenameOrID);
|
||||
|
||||
if (f.isDirectory())
|
||||
{
|
||||
Array<File> subFiles;
|
||||
f.findChildFiles (subFiles, File::findFilesAndDirectories, false);
|
||||
StringArray s;
|
||||
|
||||
for (int j = 0; j < subFiles.size(); ++j)
|
||||
s.add (subFiles.getReference(j).getFullPathName());
|
||||
{
|
||||
Array<File> subFiles;
|
||||
f.findChildFiles (subFiles, File::findFilesAndDirectories, false);
|
||||
|
||||
for (int j = 0; j < subFiles.size(); ++j)
|
||||
s.add (subFiles.getReference(j).getFullPathName());
|
||||
}
|
||||
|
||||
scanAndAddDragAndDroppedFiles (formatManager, s, typesFound);
|
||||
}
|
||||
|
||||
scanAndAddDragAndDroppedFiles (formatManager, s, typesFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -485,3 +504,7 @@ int KnownPluginList::getIndexChosenByMenu (const int menuResultCode) const
|
|||
const int i = menuResultCode - menuIdBase;
|
||||
return isPositiveAndBelow (i, types.size()) ? i : -1;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
KnownPluginList::CustomScanner::CustomScanner() {}
|
||||
KnownPluginList::CustomScanner::~CustomScanner() {}
|
||||
|
|
|
|||
|
|
@ -179,10 +179,25 @@ public:
|
|||
/** Creates a PluginTree object containing all the known plugins. */
|
||||
PluginTree* createTree (const SortMethod sortMethod) const;
|
||||
|
||||
//==============================================================================
|
||||
class CustomScanner
|
||||
{
|
||||
public:
|
||||
CustomScanner();
|
||||
virtual ~CustomScanner();
|
||||
|
||||
virtual void findPluginTypesFor (AudioPluginFormat& format,
|
||||
OwnedArray <PluginDescription>& result,
|
||||
const String& fileOrIdentifier) = 0;
|
||||
};
|
||||
|
||||
void setCustomScanner (CustomScanner* scanner);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
OwnedArray <PluginDescription> types;
|
||||
StringArray blacklist;
|
||||
ScopedPointer<CustomScanner> scanner;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (KnownPluginList)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ PluginListComponent::PluginListComponent (AudioPluginFormatManager& manager,
|
|||
list (listToEdit),
|
||||
deadMansPedalFile (deadMansPedal),
|
||||
optionsButton ("Options..."),
|
||||
propertiesToUse (properties)
|
||||
propertiesToUse (properties),
|
||||
scanOnBackgroundThread (false)
|
||||
{
|
||||
listBox.setModel (this);
|
||||
addAndMakeVisible (&listBox);
|
||||
|
|
@ -59,6 +60,11 @@ void PluginListComponent::setOptionsButtonText (const String& newText)
|
|||
resized();
|
||||
}
|
||||
|
||||
void PluginListComponent::setScansOnMessageThread (bool useMessageThread) noexcept
|
||||
{
|
||||
scanOnBackgroundThread = ! useMessageThread;
|
||||
}
|
||||
|
||||
void PluginListComponent::resized()
|
||||
{
|
||||
listBox.setBounds (0, 0, getWidth(), getHeight() - 30);
|
||||
|
|
@ -237,42 +243,79 @@ void PluginListComponent::filesDropped (const StringArray& files, int, int)
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
class PluginListComponent::Scanner : private Timer
|
||||
class PluginListComponent::Scanner : private Timer,
|
||||
private Thread
|
||||
{
|
||||
public:
|
||||
Scanner (PluginListComponent& plc, AudioPluginFormat& format, const FileSearchPath& path)
|
||||
: owner (plc),
|
||||
Scanner (PluginListComponent& plc,
|
||||
AudioPluginFormat& format,
|
||||
const FileSearchPath& path,
|
||||
bool useThread)
|
||||
: Thread ("plugin_scan"),
|
||||
owner (plc),
|
||||
aw (TRANS("Scanning for plug-ins..."),
|
||||
TRANS("Searching for all possible plug-in files..."), AlertWindow::NoIcon),
|
||||
progress (0.0),
|
||||
progress (0.0), finished (false),
|
||||
scanner (owner.list, format, path, true, owner.deadMansPedalFile)
|
||||
{
|
||||
aw.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey));
|
||||
aw.addProgressBarComponent (progress);
|
||||
aw.enterModalState();
|
||||
|
||||
if (useThread)
|
||||
startThread();
|
||||
|
||||
startTimer (20);
|
||||
}
|
||||
|
||||
~Scanner()
|
||||
{
|
||||
stopThread (10000);
|
||||
}
|
||||
|
||||
private:
|
||||
void timerCallback()
|
||||
{
|
||||
aw.setMessage (TRANS("Testing:\n\n") + scanner.getNextPluginFileThatWillBeScanned());
|
||||
if (! isThreadRunning())
|
||||
{
|
||||
if (doNextScan())
|
||||
startTimer (20);
|
||||
}
|
||||
|
||||
if (scanner.scanNextFile (true) && aw.isCurrentlyModal())
|
||||
if (! aw.isCurrentlyModal())
|
||||
finished = true;
|
||||
|
||||
if (finished)
|
||||
owner.scanFinished (scanner.getFailedFiles());
|
||||
else
|
||||
aw.setMessage (progressMessage);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
while (doNextScan() && ! threadShouldExit())
|
||||
{}
|
||||
}
|
||||
|
||||
bool doNextScan()
|
||||
{
|
||||
progressMessage = TRANS("Testing:\n\n") + scanner.getNextPluginFileThatWillBeScanned();
|
||||
|
||||
if (scanner.scanNextFile (true))
|
||||
{
|
||||
progress = scanner.getProgress();
|
||||
startTimer (20);
|
||||
}
|
||||
else
|
||||
{
|
||||
owner.scanFinished (scanner.getFailedFiles());
|
||||
return true;
|
||||
}
|
||||
|
||||
finished = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginListComponent& owner;
|
||||
AlertWindow aw;
|
||||
String progressMessage;
|
||||
double progress;
|
||||
bool finished;
|
||||
PluginDirectoryScanner scanner;
|
||||
};
|
||||
|
||||
|
|
@ -312,7 +355,7 @@ void PluginListComponent::scanFor (AudioPluginFormat* format)
|
|||
propertiesToUse->saveIfNeeded();
|
||||
}
|
||||
|
||||
currentScanner = new Scanner (*this, *format, path);
|
||||
currentScanner = new Scanner (*this, *format, path, scanOnBackgroundThread);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,9 @@ public:
|
|||
/** Changes the text in the panel's button. */
|
||||
void setOptionsButtonText (const String& newText);
|
||||
|
||||
/** Chooses whether to use the message thread or a background thread for scanning. */
|
||||
void setScansOnMessageThread (bool useMessageThread) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void resized();
|
||||
|
|
@ -83,6 +86,7 @@ private:
|
|||
ListBox listBox;
|
||||
TextButton optionsButton;
|
||||
PropertiesFile* propertiesToUse;
|
||||
bool scanOnBackgroundThread;
|
||||
|
||||
class Scanner;
|
||||
friend class Scanner;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue