From e2ecbde236c4a390bd23aab9ccb34004f06a3d37 Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 20 Nov 2023 13:35:26 +0000 Subject: [PATCH] LV2 Host: Allow fileAllTypesForFile to accept bundle paths as well as bundle URIs --- .../format_types/juce_LV2PluginFormat.cpp | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp index d0710fddf5..50008645c7 100644 --- a/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp @@ -1785,6 +1785,13 @@ private: SupportsTime time = SupportsTime::no; }; +struct FreeString { void operator() (void* ptr) const noexcept { lilv_free (ptr); } }; + +static File bundlePathFromUri (const char* uri) +{ + return File { std::unique_ptr { lilv_file_uri_parse (uri, nullptr) }.get() }; +} + class Plugins { public: @@ -1800,6 +1807,17 @@ public: return lilv_plugins_get_by_uri (plugins, uri.get()); } + const LilvPlugin* getByFile (const File& file) const + { + for (const auto* plugin : *this) + { + if (bundlePathFromUri (lilv_node_as_uri (lilv_plugin_get_bundle_uri (plugin))) == file) + return plugin; + } + + return nullptr; + } + private: const LilvPlugins* plugins = nullptr; }; @@ -2135,8 +2153,6 @@ private: JUCE_LEAK_DETECTOR (PortMap) }; -struct FreeString { void operator() (void* ptr) const noexcept { lilv_free (ptr); } }; - class PluginState { public: @@ -2584,11 +2600,6 @@ public: auto withPluginUri (URL v) const noexcept { return withMember (*this, &UiInstanceArgs::pluginUri, std::move (v)); } }; -static File bundlePathFromUri (const char* uri) -{ - return File { std::unique_ptr { lilv_file_uri_parse (uri, nullptr) }.get() }; -} - /* Creates and holds a UI instance for a plugin with a specific URI, using the provided descriptor. */ @@ -5213,10 +5224,17 @@ public: void findAllTypesForFile (OwnedArray& result, const String& identifier) { - auto desc = getDescription (findPluginByUri (identifier)); + if (File::isAbsolutePath (identifier)) + world->loadBundle (world->newFileUri (nullptr, File::addTrailingSeparator (identifier).toRawUTF8())); - if (desc.fileOrIdentifier.isNotEmpty()) - result.add (std::make_unique (desc)); + for (const auto& plugin : { findPluginByUri (identifier), findPluginByFile (identifier) }) + { + if (auto desc = getDescription (plugin); desc.fileOrIdentifier.isNotEmpty()) + { + result.add (std::make_unique (desc)); + break; + } + } } bool fileMightContainThisPluginType (const String& file) const @@ -5226,7 +5244,7 @@ public: const auto numBytes = file.getNumBytesAsUTF8(); std::vector vec (numBytes + 1, 0); std::copy (data, data + numBytes, vec.begin()); - return serd_uri_string_has_scheme (vec.data()); + return serd_uri_string_has_scheme (vec.data()) || file.endsWith (".lv2"); } String getNameOfPluginFromIdentifier (const String& identifier) @@ -5488,6 +5506,11 @@ private: return world->getAllPlugins().getByUri (world->newUri (s.toRawUTF8())); } + const LilvPlugin* findPluginByFile (const File& f) + { + return world->getAllPlugins().getByFile (f); + } + template void visitParentClasses (const LilvPluginClass* c, Fn&& fn) const {