From 26d7e8e9399ef49a37463188cd2f841537c9bb4d Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 21 Dec 2012 22:41:43 +0000 Subject: Gracefully ignore plugins which require unsupported features or have unknown port types. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4882 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/BlockFactory.cpp | 61 +++++++++++++++++++++++++++++++++++++---- src/server/LV2Options.hpp | 4 ++- src/server/LV2ResizeFeature.hpp | 2 ++ src/server/Worker.hpp | 2 ++ 4 files changed, 62 insertions(+), 7 deletions(-) (limited to 'src/server') diff --git a/src/server/BlockFactory.cpp b/src/server/BlockFactory.cpp index 484e0c63..6d961047 100644 --- a/src/server/BlockFactory.cpp +++ b/src/server/BlockFactory.cpp @@ -18,6 +18,7 @@ #include "lilv/lilv.h" +#include "ingen/LV2Features.hpp" #include "ingen/Log.hpp" #include "ingen/World.hpp" #include "internals/Controller.hpp" @@ -118,24 +119,72 @@ BlockFactory::load_plugin(const Raul::URI& uri) void BlockFactory::load_lv2_plugins() { + // Build an array of port type nodes for checking compatibility + typedef std::vector< SharedPtr > Types; + Types types; + for (unsigned t = PortType::AUDIO; t <= PortType::ATOM; ++t) { + const Raul::URI& uri(PortType((PortType::Symbol)t).uri()); + types.push_back(SharedPtr( + lilv_new_uri(_world->lilv_world(), uri.c_str()), + lilv_node_free)); + } + const LilvPlugins* plugins = lilv_world_get_all_plugins(_world->lilv_world()); LILV_FOREACH(plugins, i, plugins) { const LilvPlugin* lv2_plug = lilv_plugins_get(plugins, i); const Raul::URI uri(lilv_node_as_uri(lilv_plugin_get_uri(lv2_plug))); + + // Ignore plugins that require features Ingen doesn't support + LilvNodes* features = lilv_plugin_get_required_features(lv2_plug); + bool supported = true; + LILV_FOREACH(nodes, f, features) { + const char* feature = lilv_node_as_uri(lilv_nodes_get(features, f)); + if (!_world->lv2_features().is_supported(feature)) { + supported = false; + _world->log().warn( + Raul::fmt("Ignoring <%1%>; required feature <%2%>\n") + % uri % feature); + break; + } + } + if (!supported) { + continue; + } + + // Ignore plugins that are missing ports if (!lilv_plugin_get_port_by_index(lv2_plug, 0)) { _world->log().warn( - Raul::fmt("Ignoring plugin <%1%> with invalid ports\n") % uri); + Raul::fmt("Ignoring <%1%>; missing or corrupt ports\n") % uri); continue; } - if (_plugins.find(uri) != _plugins.end()) { + const uint32_t n_ports = lilv_plugin_get_num_ports(lv2_plug); + for (uint32_t p = 0; p < n_ports; ++p) { + const LilvPort* port = lilv_plugin_get_port_by_index(lv2_plug, p); + supported = false; + for (Types::const_iterator t = types.begin(); t != types.end(); ++t) { + if (lilv_port_is_a(lv2_plug, port, t->get())) { + supported = true; + break; + } + } + if (!supported) { + _world->log().warn( + Raul::fmt("Ignoring <%1%>; unsupported port <%2%>\n") + % uri % lilv_node_as_string( + lilv_port_get_symbol(lv2_plug, port))); + break; + } + } + if (!supported) { continue; } - LV2Plugin* const plugin = new LV2Plugin(_lv2_info, uri); - - plugin->lilv_plugin(lv2_plug); - _plugins.insert(make_pair(uri, plugin)); + if (_plugins.find(uri) == _plugins.end()) { + LV2Plugin* const plugin = new LV2Plugin(_lv2_info, uri); + plugin->lilv_plugin(lv2_plug); + _plugins.insert(make_pair(uri, plugin)); + } } } diff --git a/src/server/LV2Options.hpp b/src/server/LV2Options.hpp index ee8e3ee6..5f100f2a 100644 --- a/src/server/LV2Options.hpp +++ b/src/server/LV2Options.hpp @@ -48,7 +48,9 @@ struct LV2Options : public Ingen::LV2Features::Feature { engine.world()->uris().atom_Sequence); } } - + + const char* uri() const { return LV2_OPTIONS__options; } + SharedPtr feature(World* w, Node* n) { BlockImpl* block = dynamic_cast(n); if (!block) { diff --git a/src/server/LV2ResizeFeature.hpp b/src/server/LV2ResizeFeature.hpp index 47f30e41..8edd7868 100644 --- a/src/server/LV2ResizeFeature.hpp +++ b/src/server/LV2ResizeFeature.hpp @@ -47,6 +47,8 @@ struct ResizeFeature : public Ingen::LV2Features::Feature { free(feature); } + const char* uri() const { return LV2_RESIZE_PORT_URI; } + SharedPtr feature(World* w, Node* n) { BlockImpl* block = dynamic_cast(n); if (!block) diff --git a/src/server/Worker.hpp b/src/server/Worker.hpp index 9b69edb2..69597439 100644 --- a/src/server/Worker.hpp +++ b/src/server/Worker.hpp @@ -38,6 +38,8 @@ public: ~Worker(); struct Schedule : public LV2Features::Feature { + const char* uri() const { return LV2_WORKER__schedule; } + SharedPtr feature(World* world, Node* n); }; -- cgit v1.2.1