mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
AudioPluginHost: Allow out-of-process scanner to scan AUv3 plugins
This commit is contained in:
parent
53f8650ba3
commit
6c046ffc04
3 changed files with 61 additions and 32 deletions
|
|
@ -35,22 +35,23 @@ class PluginScannerSubprocess : private ChildProcessWorker,
|
|||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
PluginScannerSubprocess()
|
||||
{
|
||||
formatManager.addDefaultFormats();
|
||||
}
|
||||
|
||||
using ChildProcessWorker::initialiseFromCommandLine;
|
||||
|
||||
private:
|
||||
void handleMessageFromCoordinator (const MemoryBlock& mb) override
|
||||
{
|
||||
{
|
||||
const std::lock_guard<std::mutex> lock (mutex);
|
||||
pendingBlocks.emplace (mb);
|
||||
}
|
||||
if (mb.isEmpty())
|
||||
return;
|
||||
|
||||
triggerAsyncUpdate();
|
||||
if (! doScan (mb))
|
||||
{
|
||||
{
|
||||
const std::lock_guard<std::mutex> lock (mutex);
|
||||
pendingBlocks.emplace (mb);
|
||||
}
|
||||
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void handleConnectionLost() override
|
||||
|
|
@ -58,7 +59,6 @@ private:
|
|||
JUCEApplicationBase::quit();
|
||||
}
|
||||
|
||||
// It's important to run the plugin scan on the main thread!
|
||||
void handleAsyncUpdate() override
|
||||
{
|
||||
for (;;)
|
||||
|
|
@ -78,27 +78,55 @@ private:
|
|||
if (block.isEmpty())
|
||||
return;
|
||||
|
||||
MemoryInputStream stream { block, false };
|
||||
const auto formatName = stream.readString();
|
||||
const auto identifier = stream.readString();
|
||||
|
||||
OwnedArray<PluginDescription> results;
|
||||
|
||||
for (auto* format : formatManager.getFormats())
|
||||
if (format->getName() == formatName)
|
||||
format->findAllTypesForFile (results, identifier);
|
||||
|
||||
XmlElement xml ("LIST");
|
||||
|
||||
for (const auto& desc : results)
|
||||
xml.addChildElement (desc->createXml().release());
|
||||
|
||||
const auto str = xml.toString();
|
||||
sendMessageToCoordinator ({ str.toRawUTF8(), str.getNumBytesAsUTF8() });
|
||||
doScan (block);
|
||||
}
|
||||
}
|
||||
|
||||
AudioPluginFormatManager formatManager;
|
||||
bool doScan (const MemoryBlock& block)
|
||||
{
|
||||
AudioPluginFormatManager formatManager;
|
||||
formatManager.addDefaultFormats();
|
||||
|
||||
MemoryInputStream stream { block, false };
|
||||
const auto formatName = stream.readString();
|
||||
const auto identifier = stream.readString();
|
||||
|
||||
PluginDescription pd;
|
||||
pd.fileOrIdentifier = identifier;
|
||||
pd.uniqueId = pd.deprecatedUid = 0;
|
||||
|
||||
const auto matchingFormat = [&]() -> AudioPluginFormat*
|
||||
{
|
||||
for (auto* format : formatManager.getFormats())
|
||||
if (format->getName() == formatName)
|
||||
return format;
|
||||
|
||||
return nullptr;
|
||||
}();
|
||||
|
||||
if (matchingFormat == nullptr
|
||||
|| (! MessageManager::getInstance()->isThisTheMessageThread()
|
||||
&& ! matchingFormat->requiresUnblockedMessageThreadDuringCreation (pd)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
OwnedArray<PluginDescription> results;
|
||||
matchingFormat->findAllTypesForFile (results, identifier);
|
||||
sendPluginDescriptions (results);
|
||||
return true;
|
||||
}
|
||||
|
||||
void sendPluginDescriptions (const OwnedArray<PluginDescription>& results)
|
||||
{
|
||||
XmlElement xml ("LIST");
|
||||
|
||||
for (const auto& desc : results)
|
||||
xml.addChildElement (desc->createXml().release());
|
||||
|
||||
const auto str = xml.toString();
|
||||
sendMessageToCoordinator ({ str.toRawUTF8(), str.getNumBytesAsUTF8() });
|
||||
}
|
||||
|
||||
std::mutex mutex;
|
||||
std::queue<MemoryBlock> pendingBlocks;
|
||||
|
|
|
|||
|
|
@ -137,6 +137,9 @@ public:
|
|||
*/
|
||||
virtual FileSearchPath getDefaultLocationsToSearch() = 0;
|
||||
|
||||
/** Returns true if instantiation of this plugin type must be done from a non-message thread. */
|
||||
virtual bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const = 0;
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
friend class AudioPluginFormatManager;
|
||||
|
|
@ -149,9 +152,6 @@ protected:
|
|||
virtual void createPluginInstance (const PluginDescription&, double initialSampleRate,
|
||||
int initialBufferSize, PluginCreationCallback) = 0;
|
||||
|
||||
/** Returns true if instantiation of this plugin type must be done from a non-message thread. */
|
||||
virtual bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const = 0;
|
||||
|
||||
private:
|
||||
struct AsyncCreateMessage;
|
||||
void handleMessage (const Message&) override;
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ struct ChildProcessWorker::Connection : public InterprocessConnection,
|
|||
~Connection() override
|
||||
{
|
||||
stopThread (10000);
|
||||
disconnect();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue