diff --git a/modules/juce_audio_processors/format_types/juce_ARACommon.cpp b/modules/juce_audio_processors/format_types/juce_ARACommon.cpp index d118366fae..35454d5d86 100644 --- a/modules/juce_audio_processors/format_types/juce_ARACommon.cpp +++ b/modules/juce_audio_processors/format_types/juce_ARACommon.cpp @@ -48,8 +48,21 @@ static ARA::ARAInterfaceConfiguration createInterfaceConfig (const ARA::ARAFacto &assertFunction); } +/* If the provided ARAFactory is not yet in use it constructs a new shared_ptr that will call the + provided onDelete function inside the custom deleter of this new shared_ptr instance. + + The onDelete function is responsible for releasing the resources that guarantee the validity of + the wrapped ARAFactory*. + + If however the ARAFactory is already in use the function will just return a copy of the already + existing shared_ptr and call the onDelete function immediately. This is to ensure that the + ARAFactory is only uninitialised when no plugin instance can be using it. + + On both platforms the onDelete function is used to release resources that ensure that the module + providing the ARAFactory* remains loaded. +*/ static std::shared_ptr getOrCreateARAFactory (const ARA::ARAFactory* ptr, - std::function onDelete) + std::function onDelete) { JUCE_ASSERT_MESSAGE_THREAD @@ -58,14 +71,17 @@ static std::shared_ptr getOrCreateARAFactory (const ARA:: auto& cachePtr = cache[ptr]; if (const auto obj = cachePtr.lock()) + { + onDelete(); return obj; + } const auto interfaceConfig = createInterfaceConfig (ptr); ptr->initializeARAWithConfiguration (&interfaceConfig); const auto obj = std::shared_ptr (ptr, [deleter = std::move (onDelete)] (const ARA::ARAFactory* factory) { factory->uninitializeARA(); - deleter (factory); + deleter(); }); cachePtr = obj; return obj; diff --git a/modules/juce_audio_processors/format_types/juce_ARAHosting.cpp b/modules/juce_audio_processors/format_types/juce_ARAHosting.cpp index d406ffd240..af7923a97d 100644 --- a/modules/juce_audio_processors/format_types/juce_ARAHosting.cpp +++ b/modules/juce_audio_processors/format_types/juce_ARAHosting.cpp @@ -278,8 +278,18 @@ class ARAHostDocumentController::Impl public: Impl (ARAFactoryWrapper araFactoryIn, std::unique_ptr&& dcHostInstanceIn, - const ARA::ARADocumentControllerInstance* documentControllerInstance) + const ARA::ARADocumentControllerInstance* documentControllerInstance, + std::unique_ptr&& audioAccessControllerIn, + std::unique_ptr&& archivingControllerIn, + std::unique_ptr&& contentAccessControllerIn, + std::unique_ptr&& modelUpdateControllerIn, + std::unique_ptr&& playbackControllerIn) : araFactory (std::move (araFactoryIn)), + audioAccessController (std::move (audioAccessControllerIn)), + archivingController (std::move (archivingControllerIn)), + contentAccessController (std::move (contentAccessControllerIn)), + modelUpdateController (std::move (modelUpdateControllerIn)), + playbackController (std::move (playbackControllerIn)), dcHostInstance (std::move (dcHostInstanceIn)), documentController (documentControllerInstance) { @@ -300,16 +310,23 @@ public: std::unique_ptr&& playbackController) { std::unique_ptr dcHostInstance = - std::make_unique (audioAccessController.release(), - archivingController.release(), - contentAccessController.release(), - modelUpdateController.release(), - playbackController.release()); + std::make_unique (audioAccessController.get(), + archivingController.get(), + contentAccessController.get(), + modelUpdateController.get(), + playbackController.get()); const auto documentProperties = makeARASizedStruct (&ARA::ARADocumentProperties::name, documentName.toRawUTF8()); if (auto* dci = araFactory.get()->createDocumentControllerWithDocument (dcHostInstance.get(), &documentProperties)) - return std::make_unique (std::move (araFactory), std::move (dcHostInstance), dci); + return std::make_unique (std::move (araFactory), + std::move (dcHostInstance), + dci, + std::move (audioAccessController), + std::move (archivingController), + std::move (contentAccessController), + std::move (modelUpdateController), + std::move (playbackController)); return {}; } @@ -386,6 +403,13 @@ public: private: ARAFactoryWrapper araFactory; + + std::unique_ptr audioAccessController; + std::unique_ptr archivingController; + std::unique_ptr contentAccessController; + std::unique_ptr modelUpdateController; + std::unique_ptr playbackController; + std::unique_ptr dcHostInstance; ARA::Host::DocumentController documentController; }; diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index ec695c4f81..e5d40290fc 100644 --- a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -488,7 +488,7 @@ static std::shared_ptr getARAFactory (AudioUnitSharedPtr { jassert (audioUnitFactory.outFactory != nullptr); return getOrCreateARAFactory (audioUnitFactory.outFactory, - [owningAuPtr = std::move (audioUnit)] (const ARA::ARAFactory*) {}); + [owningAuPtr = std::move (audioUnit)]() {}); } } #else diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index 31bf6ff482..0122c211b4 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -1424,7 +1424,7 @@ static std::shared_ptr getARAFactory (Steinberg::IPluginF == Steinberg::kResultOk) { factory = getOrCreateARAFactory (source->getFactory(), - [source] (const ARA::ARAFactory*) { source->release(); }); + [source]() { source->release(); }); return false; } jassert (source == nullptr);