From cc3359a6bea22c3d4584a5d57403e7d568e16fe7 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 31 Jan 2014 23:58:48 +0000 Subject: Subscribe to ports before instantiating plugin UIs (fix #954). Respond to put/set/patch with the same type of event (not set=>delta). Don't feed back changes to originating client. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5326 a436a847-0d15-0410-975c-d299462d15a1 --- src/client/ClientStore.cpp | 9 ++++++-- src/client/PluginUI.cpp | 51 +++++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 23 deletions(-) (limited to 'src/client') diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index d3438f46..a3fc60aa 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -215,7 +215,7 @@ ClientStore::put(const Raul::URI& uri, { typedef Resource::Properties::const_iterator Iterator; #ifdef INGEN_CLIENT_STORE_DUMP - std::cerr << "Put " << uri << " {" << endl; + std::cerr << "Client put " << uri << " {" << endl; for (auto p : properties) std::cerr << '\t' << p.first << " = " << _uris.forge.str(p.second) << " :: " << p.second.type() << endl; @@ -312,7 +312,7 @@ ClientStore::delta(const Raul::URI& uri, const Resource::Properties& add) { #ifdef INGEN_CLIENT_STORE_DUMP - std::cerr << "Delta " << uri << " {" << endl; + std::cerr << "Client delta " << uri << " {" << endl; for (auto r : remove) std::cerr << " - " << r.first << " = " << _uris.forge.str(r.second) @@ -352,6 +352,11 @@ ClientStore::set_property(const Raul::URI& subject_uri, const Raul::URI& predicate, const Atom& value) { +#ifdef INGEN_CLIENT_STORE_DUMP + std::cerr << "Client set " << subject_uri << " : " + << predicate << " = " << _uris.forge.str(value) << std::endl; +#endif + if (subject_uri == Raul::URI("ingen:/engine")) { _log.info(fmt("Engine property <%1%> = %2%\n") % predicate.c_str() % _uris.forge.str(value)); diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp index 227f6000..0e308abd 100644 --- a/src/client/PluginUI.cpp +++ b/src/client/PluginUI.cpp @@ -80,7 +80,7 @@ lv2_ui_write(SuilController controller, Atom val = ui->world()->forge().alloc( atom->size, atom->type, LV2_ATOM_BODY_CONST(atom)); ui->world()->interface()->set_property(port->uri(), - uris.ingen_value, + uris.ingen_activity, val); } else { @@ -199,30 +199,14 @@ PluginUI::create(Ingen::World* world, return SPtr(); } + // Create the PluginUI, but don't instantiate yet SPtr ret(new PluginUI(world, block, lilv_ui_get_uri(ui))); ret->_features = world->lv2_features().lv2_features( world, const_cast(block.get())); - SuilInstance* instance = suil_instance_new( - PluginUI::ui_host, - ret.get(), - lilv_node_as_uri(gtk_ui), - lilv_node_as_uri(lilv_plugin_get_uri(plugin)), - lilv_node_as_uri(lilv_ui_get_uri(ui)), - lilv_node_as_uri(ui_type), - lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_bundle_uri(ui))), - lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_binary_uri(ui))), - ret->_features->array()); - - lilv_node_free(gtk_ui); - - if (!instance) { - world->log().error("Failed to instantiate LV2 UI\n"); - return SPtr(); - } - - ret->_instance = instance; - + /* Subscribe (enable broadcast) for any requested port notifications. This + must be done before instantiation so responses to any events sent by the + UI's init() will be sent back to this client. */ LilvWorld* lworld = world->lilv_world(); LilvNode* ui_portNotification = lilv_new_uri(lworld, LV2_UI__portNotification); LilvNode* lv2_symbol = lilv_new_uri(lworld, LV2_CORE__symbol); @@ -243,6 +227,31 @@ PluginUI::create(Ingen::World* world, lilv_node_free(lv2_symbol); lilv_node_free(ui_portNotification); + // Instantiate the actual plugin UI via Suil + SuilInstance* instance = suil_instance_new( + PluginUI::ui_host, + ret.get(), + lilv_node_as_uri(gtk_ui), + lilv_node_as_uri(lilv_plugin_get_uri(plugin)), + lilv_node_as_uri(lilv_ui_get_uri(ui)), + lilv_node_as_uri(ui_type), + lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_bundle_uri(ui))), + lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_binary_uri(ui))), + ret->_features->array()); + + lilv_node_free(gtk_ui); + + if (!instance) { + world->log().error("Failed to instantiate LV2 UI\n"); + // Cancel any subscriptions + for (uint32_t i : ret->_subscribed_ports) { + lv2_ui_unsubscribe(ret.get(), i, 0, NULL); + } + return SPtr(); + } + + ret->_instance = instance; + return ret; } -- cgit v1.2.1