From ad07c414d557629251b2f4ea4078c22f241cc865 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 13 Feb 2010 22:07:26 +0000 Subject: Learn and remove bindings exclusively through property interface. Note this commit breaks some aspects of OSC and HTTP control for now. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2442 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/ClientBroadcaster.hpp | 6 ++ src/engine/ControlBindings.cpp | 23 ++++++ src/engine/ControlBindings.hpp | 6 ++ src/engine/HTTPClientSender.cpp | 8 +++ src/engine/HTTPClientSender.hpp | 4 ++ src/engine/LV2Node.cpp | 1 - src/engine/OSCClientSender.cpp | 53 ++++++++------ src/engine/OSCClientSender.hpp | 4 ++ src/engine/OSCEngineReceiver.cpp | 116 +++++++++++++------------------ src/engine/QueuedEngineInterface.cpp | 33 ++++----- src/engine/QueuedEngineInterface.hpp | 6 +- src/engine/events.hpp | 1 - src/engine/events/Learn.cpp | 99 -------------------------- src/engine/events/Learn.hpp | 61 ---------------- src/engine/events/SetMetadata.cpp | 131 +++++++++++++++++++++++------------ src/engine/events/SetMetadata.hpp | 11 ++- src/engine/internals/Controller.cpp | 1 - src/engine/wscript | 1 - 18 files changed, 248 insertions(+), 317 deletions(-) delete mode 100644 src/engine/events/Learn.cpp delete mode 100644 src/engine/events/Learn.hpp (limited to 'src/engine') diff --git a/src/engine/ClientBroadcaster.hpp b/src/engine/ClientBroadcaster.hpp index 37593730..38073dc1 100644 --- a/src/engine/ClientBroadcaster.hpp +++ b/src/engine/ClientBroadcaster.hpp @@ -74,6 +74,12 @@ public: BROADCAST(put, uri, properties); } + void delta(const Raul::URI& uri, + const Shared::Resource::Properties& remove, + const Shared::Resource::Properties& add) { + BROADCAST(delta, uri, remove, add); + } + void move(const Raul::Path& old_path, const Raul::Path& new_path) { BROADCAST(move, old_path, new_path); diff --git a/src/engine/ControlBindings.cpp b/src/engine/ControlBindings.cpp index 91d425a4..e183404a 100644 --- a/src/engine/ControlBindings.cpp +++ b/src/engine/ControlBindings.cpp @@ -301,6 +301,29 @@ ControlBindings::remove(const Raul::Path& path) } +SharedPtr +ControlBindings::remove(PortImpl* port) +{ + ThreadManager::assert_thread(THREAD_PRE_PROCESS); + + SharedPtr old_bindings(_bindings); + SharedPtr copy(new Bindings(*_bindings.get())); + + for (Bindings::iterator i = copy->begin(); i != copy->end();) { + Bindings::iterator next = i; + ++next; + + if (i->second == port) + copy->erase(i); + + i = next; + } + + _bindings = copy; + return old_bindings; +} + + void ControlBindings::pre_process(ProcessContext& context, EventBuffer* buffer) { diff --git a/src/engine/ControlBindings.hpp b/src/engine/ControlBindings.hpp index 458d153a..1b684b9a 100644 --- a/src/engine/ControlBindings.hpp +++ b/src/engine/ControlBindings.hpp @@ -72,6 +72,12 @@ public: */ SharedPtr remove(const Raul::Path& path); + /** Remove binding for a particular port. + * The caller must safely drop the returned reference in the + * post-processing thread after at least one process thread has run. + */ + SharedPtr remove(PortImpl* port); + private: Key port_binding(PortImpl* port); Key midi_event_key(uint16_t size, uint8_t* buf, uint16_t& value); diff --git a/src/engine/HTTPClientSender.cpp b/src/engine/HTTPClientSender.cpp index dcea6288..996aa7cd 100644 --- a/src/engine/HTTPClientSender.cpp +++ b/src/engine/HTTPClientSender.cpp @@ -71,6 +71,14 @@ HTTPClientSender::put(const URI& uri, } +void +HTTPClientSender::delta(const URI& uri, + const Resource::Properties& remove, + const Resource::Properties& add) +{ +} + + void HTTPClientSender::del(const Path& path) { diff --git a/src/engine/HTTPClientSender.hpp b/src/engine/HTTPClientSender.hpp index cbfd17f0..dc4b9edf 100644 --- a/src/engine/HTTPClientSender.hpp +++ b/src/engine/HTTPClientSender.hpp @@ -69,6 +69,10 @@ public: virtual void put(const Raul::URI& path, const Shared::Resource::Properties& properties); + virtual void delta(const Raul::URI& path, + const Shared::Resource::Properties& remove, + const Shared::Resource::Properties& add); + virtual void del(const Raul::Path& path); virtual void move(const Raul::Path& old_path, diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp index cdc29b15..956bf3af 100644 --- a/src/engine/LV2Node.cpp +++ b/src/engine/LV2Node.cpp @@ -301,7 +301,6 @@ LV2Node::instantiate(BufferFactory& bufs) for (uint32_t i = 0; i < slv2_values_size(properties); ++i) { SLV2Value p = slv2_values_get_at(properties, i); if (slv2_value_is_uri(p)) { - Raul::info << "SET PORT PROPERTY " << slv2_value_as_uri(p) << endl; port->set_property(uris.lv2_portProperty, Raul::URI(slv2_value_as_uri(p))); } } diff --git a/src/engine/OSCClientSender.cpp b/src/engine/OSCClientSender.cpp index 115b22de..c0f8e039 100644 --- a/src/engine/OSCClientSender.cpp +++ b/src/engine/OSCClientSender.cpp @@ -42,7 +42,7 @@ namespace Ingen { /** \page client_osc_namespace - *

/ingen/ok

+ *

/ok

* \arg \b response-id (int) - Request ID this is a response to * * Successful response to some command. @@ -53,7 +53,7 @@ OSCClientSender::response_ok(int32_t id) if (!_enabled) return; - if (lo_send(_address, "/ingen/ok", "i", id) < 0) { + if (lo_send(_address, "/ok", "i", id) < 0) { Raul::error << "Unable to send OK " << id << "! (" << lo_address_errstr(_address) << ")" << endl; } @@ -61,7 +61,7 @@ OSCClientSender::response_ok(int32_t id) /** \page client_osc_namespace - *

/ingen/error

+ *

/error

* \arg \b response-id (int) - Request ID this is a response to * \arg \b message (string) - Error message (natural language text) * @@ -73,7 +73,7 @@ OSCClientSender::response_error(int32_t id, const std::string& msg) if (!_enabled) return; - if (lo_send(_address, "/ingen/error", "is", id, msg.c_str()) < 0) { + if (lo_send(_address, "/error", "is", id, msg.c_str()) < 0) { Raul::error << "Unable to send error " << id << "! (" << lo_address_errstr(_address) << ")" << endl; } @@ -81,7 +81,7 @@ OSCClientSender::response_error(int32_t id, const std::string& msg) /** \page client_osc_namespace - *

/ingen/error

+ *

/error

* \arg \b message (string) - Error message (natural language text) * * Notification that an error has occurred. @@ -91,12 +91,12 @@ OSCClientSender::response_error(int32_t id, const std::string& msg) void OSCClientSender::error(const std::string& msg) { - send("/ingen/error", "s", msg.c_str(), LO_ARGS_END); + send("/error", "s", msg.c_str(), LO_ARGS_END); } /** \page client_osc_namespace - *

/ingen/put

+ *

/put

* \arg \b path (string) - Path of object * \arg \b predicate * \arg \b value @@ -115,12 +115,21 @@ OSCClientSender::put(const Raul::URI& path, lo_message_add_string(m, i->first.c_str()); Raul::AtomLiblo::lo_message_add_atom(m, i->second); } - send_message("/ingen/put", m); + send_message("/put", m); +} + + +void +OSCClientSender::delta(const Raul::URI& path, + const Shared::Resource::Properties& remove, + const Shared::Resource::Properties& add) +{ + warn << "FIXME: OSC DELTA" << endl; } /** \page client_osc_namespace - *

/ingen/move

+ *

/move

* \arg \b old-path (string) - Old path of object * \arg \b new-path (string) - New path of object * @@ -130,13 +139,13 @@ OSCClientSender::put(const Raul::URI& path, void OSCClientSender::move(const Path& old_path, const Path& new_path) { - send("/ingen/move", "ss", old_path.c_str(), new_path.c_str(), LO_ARGS_END); + send("/move", "ss", old_path.c_str(), new_path.c_str(), LO_ARGS_END); } /** \page client_osc_namespace - *

/ingen/delete

+ *

/delete

* \arg \b path (string) - Path of object (which no longer exists) * * DELETE an object (see \ref methods). @@ -144,12 +153,12 @@ OSCClientSender::move(const Path& old_path, const Path& new_path) void OSCClientSender::del(const Path& path) { - send("/ingen/delete", "s", path.c_str(), LO_ARGS_END); + send("/delete", "s", path.c_str(), LO_ARGS_END); } /** \page client_osc_namespace - *

/ingen/new_connection

+ *

/connect

* \arg \b src-path (string) - Path of the source port * \arg \b dst-path (string) - Path of the destination port * @@ -158,12 +167,12 @@ OSCClientSender::del(const Path& path) void OSCClientSender::connect(const Path& src_port_path, const Path& dst_port_path) { - send("/ingen/new_connection", "ss", src_port_path.c_str(), dst_port_path.c_str(), LO_ARGS_END); + send("/connect", "ss", src_port_path.c_str(), dst_port_path.c_str(), LO_ARGS_END); } /** \page client_osc_namespace - *

/ingen/disconnection

+ *

/disconnect

* \arg \b src-path (string) - Path of the source port * \arg \b dst-path (string) - Path of the destination port * @@ -172,12 +181,12 @@ OSCClientSender::connect(const Path& src_port_path, const Path& dst_port_path) void OSCClientSender::disconnect(const Path& src_port_path, const Path& dst_port_path) { - send("/ingen/disconnection", "ss", src_port_path.c_str(), dst_port_path.c_str(), LO_ARGS_END); + send("/disconnect", "ss", src_port_path.c_str(), dst_port_path.c_str(), LO_ARGS_END); } /** \page client_osc_namespace - *

/ingen/set_property

+ *

/set_property

* \arg \b path (string) - Path of the object associated with property (node, patch, or port) * \arg \b key (string) * \arg \b value (string) @@ -191,12 +200,12 @@ OSCClientSender::set_property(const URI& path, const URI& key, const Atom& value lo_message_add_string(m, path.c_str()); lo_message_add_string(m, key.c_str()); AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_property", m); + send_message("/set_property", m); } /** \page client_osc_namespace - *

/ingen/set_port_value

+ *

/set_port_value

* \arg \b path (string) - Path of port * \arg \b voice (int) - Voice which is set to this value * \arg \b value (any) - New value of port @@ -209,12 +218,12 @@ OSCClientSender::set_voice_value(const Path& port_path, uint32_t voice, const At lo_message m = lo_message_new(); lo_message_add_string(m, port_path.c_str()); AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_port_value", m); + send_message("/set_port_value", m); } /** \page client_osc_namespace - *

/ingen/activity

+ *

/activity

* \arg \b path (string) - Path of object * * Notification of "activity" (e.g. port message blinkenlights). @@ -225,7 +234,7 @@ OSCClientSender::activity(const Path& path) if (!_enabled) return; - lo_send(_address, "/ingen/activity", "s", path.c_str(), LO_ARGS_END); + lo_send(_address, "/activity", "s", path.c_str(), LO_ARGS_END); } diff --git a/src/engine/OSCClientSender.hpp b/src/engine/OSCClientSender.hpp index f8e3023b..ca0783b0 100644 --- a/src/engine/OSCClientSender.hpp +++ b/src/engine/OSCClientSender.hpp @@ -69,6 +69,10 @@ public: virtual void put(const Raul::URI& path, const Shared::Resource::Properties& properties); + virtual void delta(const Raul::URI& path, + const Shared::Resource::Properties& remove, + const Shared::Resource::Properties& add); + virtual void del(const Raul::Path& path); virtual void move(const Raul::Path& old_path, diff --git a/src/engine/OSCEngineReceiver.cpp b/src/engine/OSCEngineReceiver.cpp index c186dbcd..38ef3273 100644 --- a/src/engine/OSCEngineReceiver.cpp +++ b/src/engine/OSCEngineReceiver.cpp @@ -85,32 +85,31 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t lo_server_add_method(_server, NULL, NULL, set_response_address_cb, this); // Commands - lo_server_add_method(_server, "/ingen/ping", "i", ping_cb, this); - lo_server_add_method(_server, "/ingen/ping_queued", "i", ping_slow_cb, this); - lo_server_add_method(_server, "/ingen/quit", "i", quit_cb, this); - //lo_server_add_method(_server, "/ingen/register_client", "is", register_client_cb, this); - lo_server_add_method(_server, "/ingen/register_client", "i", register_client_cb, this); - lo_server_add_method(_server, "/ingen/unregister_client", "i", unregister_client_cb, this); - lo_server_add_method(_server, "/ingen/load_plugins", "i", load_plugins_cb, this); - lo_server_add_method(_server, "/ingen/activate", "i", engine_activate_cb, this); - lo_server_add_method(_server, "/ingen/deactivate", "i", engine_deactivate_cb, this); - lo_server_add_method(_server, "/ingen/put", NULL, put_cb, this); - lo_server_add_method(_server, "/ingen/move", "iss", move_cb, this); - lo_server_add_method(_server, "/ingen/delete", "is", del_cb, this); - lo_server_add_method(_server, "/ingen/connect", "iss", connect_cb, this); - lo_server_add_method(_server, "/ingen/disconnect", "iss", disconnect_cb, this); - lo_server_add_method(_server, "/ingen/disconnect_all", "iss", disconnect_all_cb, this); - lo_server_add_method(_server, "/ingen/note_on", "isii", note_on_cb, this); - lo_server_add_method(_server, "/ingen/note_off", "isi", note_off_cb, this); - lo_server_add_method(_server, "/ingen/all_notes_off", "isi", all_notes_off_cb, this); - lo_server_add_method(_server, "/ingen/learn", "is", learn_cb, this); - lo_server_add_method(_server, "/ingen/set_property", NULL, set_property_cb, this); + lo_server_add_method(_server, "/ping", "i", ping_cb, this); + lo_server_add_method(_server, "/ping_queued", "i", ping_slow_cb, this); + lo_server_add_method(_server, "/quit", "i", quit_cb, this); + lo_server_add_method(_server, "/register_client", "i", register_client_cb, this); + lo_server_add_method(_server, "/unregister_client", "i", unregister_client_cb, this); + lo_server_add_method(_server, "/load_plugins", "i", load_plugins_cb, this); + lo_server_add_method(_server, "/activate", "i", engine_activate_cb, this); + lo_server_add_method(_server, "/deactivate", "i", engine_deactivate_cb, this); + lo_server_add_method(_server, "/put", NULL, put_cb, this); + lo_server_add_method(_server, "/move", "iss", move_cb, this); + lo_server_add_method(_server, "/delete", "is", del_cb, this); + lo_server_add_method(_server, "/connect", "iss", connect_cb, this); + lo_server_add_method(_server, "/disconnect", "iss", disconnect_cb, this); + lo_server_add_method(_server, "/disconnect_all", "iss", disconnect_all_cb, this); + lo_server_add_method(_server, "/note_on", "isii", note_on_cb, this); + lo_server_add_method(_server, "/note_off", "isi", note_off_cb, this); + lo_server_add_method(_server, "/all_notes_off", "isi", all_notes_off_cb, this); + lo_server_add_method(_server, "/learn", "is", learn_cb, this); + lo_server_add_method(_server, "/set_property", NULL, set_property_cb, this); // Queries - lo_server_add_method(_server, "/ingen/request_property", "iss", request_property_cb, this); - lo_server_add_method(_server, "/ingen/get", "is", get_cb, this); - lo_server_add_method(_server, "/ingen/request_plugins", "i", request_plugins_cb, this); - lo_server_add_method(_server, "/ingen/request_all_objects", "i", request_all_objects_cb, this); + lo_server_add_method(_server, "/request_property", "iss", request_property_cb, this); + lo_server_add_method(_server, "/get", "is", get_cb, this); + lo_server_add_method(_server, "/request_plugins", "i", request_plugins_cb, this); + lo_server_add_method(_server, "/request_all_objects", "i", request_all_objects_cb, this); lo_server_add_method(_server, NULL, NULL, unknown_cb, NULL); @@ -237,7 +236,7 @@ OSCEngineReceiver::error_cb(int num, const char* msg, const char* path) /** \page engine_osc_namespace - *

/ingen/ping

+ *

/ping

* \arg \b response-id (integer) * * Reply to sender immediately with a successful response. @@ -246,14 +245,14 @@ int OSCEngineReceiver::_ping_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { const lo_address addr = lo_message_get_source(msg); - if (lo_send(addr, "/ingen/ok", "i", argv[0]->i) < 0) + if (lo_send(addr, "/ok", "i", argv[0]->i) < 0) warn << "Unable to send response (" << lo_address_errstr(addr) << ")" << endl; return 0; } /** \page engine_osc_namespace - *

/ingen/ping_queued

+ *

/ping_queued

* \arg \b response-id (integer) * * Reply to sender with a successful response after going through the event queue. @@ -270,7 +269,7 @@ OSCEngineReceiver::_ping_slow_cb(const char* path, const char* types, lo_arg** a /** \page engine_osc_namespace - *

/ingen/quit

+ *

/quit

* \arg \b response-id (integer) * * Terminate the engine. @@ -287,7 +286,7 @@ OSCEngineReceiver::_quit_cb(const char* path, const char* types, lo_arg** argv, /** \page engine_osc_namespace - *

/ingen/register_client

+ *

/register_client

* \arg \b response-id (integer) * * Register a new client with the engine. @@ -309,7 +308,7 @@ OSCEngineReceiver::_register_client_cb(const char* path, const char* types, lo_a /** \page engine_osc_namespace - *

/ingen/unregister_client

+ *

/unregister_client

* \arg \b response-id (integer) * * Unregister a client. @@ -328,7 +327,7 @@ OSCEngineReceiver::_unregister_client_cb(const char* path, const char* types, lo /** \page engine_osc_namespace - *

/ingen/load_plugins

+ *

/load_plugins

* \arg \b response-id (integer) * * Locate all available plugins, making them available for use. @@ -342,7 +341,7 @@ OSCEngineReceiver::_load_plugins_cb(const char* path, const char* types, lo_arg* /** \page engine_osc_namespace - *

/ingen/activate

+ *

/activate

* \arg \b response-id (integer) * * Activate the engine (event processing and all drivers, e.g. audio and MIDI). @@ -358,7 +357,7 @@ OSCEngineReceiver::_engine_activate_cb(const char* path, const char* types, lo_a /** \page engine_osc_namespace - *

/ingen/deactivate

+ *

/deactivate

* \arg \b response-id (integer) * * Deactivate the engine. @@ -372,7 +371,7 @@ OSCEngineReceiver::_engine_deactivate_cb(const char* path, const char* types, lo /** \page engine_osc_namespace - *

/ingen/get

+ *

/get

* \arg \b response-id (integer) * \arg \b uri (string) - URI of object (patch, port, node, plugin) to send * @@ -387,7 +386,7 @@ OSCEngineReceiver::_get_cb(const char* path, const char* types, lo_arg** argv, i /** \page engine_osc_namespace - *

/ingen/put

+ *

/put

* \arg \b response-id (integer) * \arg \b path (string) - Path of object * \arg \b predicate @@ -409,7 +408,7 @@ OSCEngineReceiver::_put_cb(const char* path, const char* types, lo_arg** argv, i /** \page engine_osc_namespace - *

/ingen/move

+ *

/move

* \arg \b response-id (integer) * \arg \b old-path - Object's path * \arg \b new-path - Object's new path @@ -428,7 +427,7 @@ OSCEngineReceiver::_move_cb(const char* path, const char* types, lo_arg** argv, /** \page engine_osc_namespace - *

/ingen/del

+ *

/del

* \arg \b response-id (integer) * \arg \b path (string) - Full path of the object * @@ -445,7 +444,7 @@ OSCEngineReceiver::_del_cb(const char* path, const char* types, lo_arg** argv, i /** \page engine_osc_namespace - *

/ingen/connect

+ *

/connect

* \arg \b response-id (integer) * \arg \b src-port-path (string) - Full path of source port * \arg \b dst-port-path (string) - Full path of destination port @@ -464,7 +463,7 @@ OSCEngineReceiver::_connect_cb(const char* path, const char* types, lo_arg** arg /** \page engine_osc_namespace - *

/ingen/disconnect

+ *

/disconnect

* \arg \b response-id (integer) * \arg \b src-port-path (string) - Full path of source port * \arg \b dst-port-path (string) - Full path of destination port @@ -483,7 +482,7 @@ OSCEngineReceiver::_disconnect_cb(const char* path, const char* types, lo_arg** /** \page engine_osc_namespace - *

/ingen/disconnect_all

+ *

/disconnect_all

* \arg \b response-id (integer) * \arg \b patch-path (string) - The (parent) patch in which to disconnect object. * \arg \b object-path (string) - Full path of object. @@ -502,7 +501,7 @@ OSCEngineReceiver::_disconnect_all_cb(const char* path, const char* types, lo_ar /** \page engine_osc_namespace - *

/ingen/note_on

+ *

/note_on

* \arg \b response-id (integer) * \arg \b node-path (string) - Patch of Node to trigger (must be a trigger or note node) * \arg \b note-num (int) - MIDI style note number (0-127) @@ -525,7 +524,7 @@ OSCEngineReceiver::_note_on_cb(const char* path, const char* types, lo_arg** arg /** \page engine_osc_namespace - *

/ingen/note_off

+ *

/note_off

* \arg \b response-id (integer) * \arg \b node-path (string) - Patch of Node to trigger (must be a trigger or note node) * \arg \b note-num (int) - MIDI style note number (0-127) @@ -546,7 +545,7 @@ OSCEngineReceiver::_note_off_cb(const char* path, const char* types, lo_arg** ar /** \page engine_osc_namespace - *

/ingen/all_notes_off

+ *

/all_notes_off

* \arg \b response-id (integer) * \arg \b patch-path (string) - Patch of patch to send event to * @@ -566,27 +565,7 @@ OSCEngineReceiver::_all_notes_off_cb(const char* path, const char* types, lo_arg /** \page engine_osc_namespace - *

/ingen/learn

- * \arg \b response-id (integer) - * \arg \b node-path (string) - Path of control node. - * - * Initiate MIDI learn for a given control node. - * The node will learn the next MIDI control event it receives and set - * its outputs accordingly. - * This command does nothing for objects that are not a control internal. - */ -int -OSCEngineReceiver::_learn_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* object_path = &argv[1]->s; - - learn(object_path); - return 0; -} - - -/** \page engine_osc_namespace - *

/ingen/set_property

+ *

/set_property

* \arg \b response-id (integer) * \arg \b object-path (string) - Full path of object to associate property with * \arg \b key (string) - URI for predicate of this property (e.g. "http://drobilla.net/ns/ingen#enabled") @@ -603,6 +582,9 @@ OSCEngineReceiver::_set_property_cb(const char* path, const char* types, lo_arg* const char* object_path = &argv[1]->s; const char* key = &argv[2]->s; + cout << "SET PROPERTY " << object_path << " : " << key << " PENDING: " << + lo_server_events_pending(_server) << endl; + Raul::Atom value = Raul::AtomLiblo::lo_arg_to_atom(types[3], argv[3]); set_property(object_path, key, value); @@ -611,7 +593,7 @@ OSCEngineReceiver::_set_property_cb(const char* path, const char* types, lo_arg* /** \page engine_osc_namespace - *

/ingen/request_property

+ *

/request_property

* \arg \b response-id (integer) * \arg \b uri (string) - Subject * \arg \b key (string) - Predicate @@ -630,7 +612,7 @@ OSCEngineReceiver::_request_property_cb(const char* path, const char* types, lo_ /** \page engine_osc_namespace - *

/ingen/request_plugins

+ *

/request_plugins

* \arg \b response-id (integer) * * Request the engine send a list of all known plugins. @@ -644,7 +626,7 @@ OSCEngineReceiver::_request_plugins_cb(const char* path, const char* types, lo_a /** \page engine_osc_namespace - *

/ingen/request_all_objects

+ *

/request_all_objects

* \arg \b response-id (integer) * * Requests all information about all known objects. diff --git a/src/engine/QueuedEngineInterface.cpp b/src/engine/QueuedEngineInterface.cpp index dbbc0099..6122c80d 100644 --- a/src/engine/QueuedEngineInterface.cpp +++ b/src/engine/QueuedEngineInterface.cpp @@ -160,16 +160,22 @@ QueuedEngineInterface::put(const URI& uri, bool meta = ResourceImpl::is_meta_uri(uri); URI subject(meta ? (string("path:/") + uri.substr(6)) : uri.str()); - LOG(debug) << "PUT " << subject << " {" << endl; - typedef Resource::Properties::const_iterator iterator; - for (iterator i = properties.begin(); i != properties.end(); ++i) - LOG(debug) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl; - LOG(debug) << "}" << endl; - push_queued(new Events::SetMetadata(_engine, _request, now(), true, meta, subject, properties)); } +void +QueuedEngineInterface::delta(const URI& uri, + const Shared::Resource::Properties& remove, + const Shared::Resource::Properties& add) +{ + bool meta = ResourceImpl::is_meta_uri(uri); + URI subject(meta ? (string("path:/") + uri.substr(6)) : uri.str()); + + push_queued(new Events::SetMetadata(_engine, _request, now(), false, meta, subject, add, remove)); +} + + void QueuedEngineInterface::move(const Path& old_path, const Path& new_path) @@ -219,13 +225,6 @@ QueuedEngineInterface::set_voice_value(const Path& port_path, } -void -QueuedEngineInterface::learn(const Path& path) -{ - push_queued(new Events::Learn(_engine, _request, now(), path)); -} - - void QueuedEngineInterface::set_property(const URI& uri, const URI& predicate, @@ -234,9 +233,11 @@ QueuedEngineInterface::set_property(const URI& uri, size_t hash = uri.find("#"); bool meta = (hash != string::npos); Path path = meta ? (string("/") + path.chop_start("/")) : uri.str(); - Resource::Properties properties; - properties.insert(make_pair(predicate, value)); - push_queued(new Events::SetMetadata(_engine, _request, now(), true, meta, path, properties)); + Resource::Properties remove; + remove.insert(make_pair(predicate, Shared::LV2URIMap::instance().wildcard)); + Resource::Properties add; + add.insert(make_pair(predicate, value)); + push_queued(new Events::SetMetadata(_engine, _request, now(), false, meta, path, add, remove)); } // Requests // diff --git a/src/engine/QueuedEngineInterface.hpp b/src/engine/QueuedEngineInterface.hpp index 463cdfc3..8aa44f31 100644 --- a/src/engine/QueuedEngineInterface.hpp +++ b/src/engine/QueuedEngineInterface.hpp @@ -74,6 +74,10 @@ public: virtual void put(const Raul::URI& path, const Shared::Resource::Properties& properties); + virtual void delta(const Raul::URI& path, + const Shared::Resource::Properties& remove, + const Shared::Resource::Properties& add); + virtual void move(const Raul::Path& old_path, const Raul::Path& new_path); @@ -98,8 +102,6 @@ public: virtual void disconnect_all(const Raul::Path& parent_patch_path, const Raul::Path& path); - virtual void learn(const Raul::Path& path); - // Requests virtual void ping(); virtual void get(const Raul::URI& uri); diff --git a/src/engine/events.hpp b/src/engine/events.hpp index ea8d7efd..54fb63c7 100644 --- a/src/engine/events.hpp +++ b/src/engine/events.hpp @@ -30,7 +30,6 @@ #include "events/Disconnect.hpp" #include "events/DisconnectAll.hpp" #include "events/Get.hpp" -#include "events/Learn.hpp" #include "events/LoadPlugins.hpp" #include "events/Move.hpp" #include "events/Note.hpp" diff --git a/src/engine/events/Learn.cpp b/src/engine/events/Learn.cpp deleted file mode 100644 index bf453bc3..00000000 --- a/src/engine/events/Learn.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "events/Learn.hpp" -#include "ClientBroadcaster.hpp" -#include "ControlBindings.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "PortImpl.hpp" -#include "Request.hpp" -#include "internals/Controller.hpp" - -using namespace std; - -namespace Ingen { -namespace Events { - - -Learn::Learn(Engine& engine, SharedPtr request, SampleCount timestamp, const Raul::Path& path) - : QueuedEvent(engine, request, timestamp) - , _error(NO_ERROR) - , _path(path) - , _object(NULL) - , _done(false) -{ -} - - -void -Learn::pre_process() -{ - _object = _engine.engine_store()->find_object(_path); - - PortImpl* port = dynamic_cast(_object); - if (port) { - _done = true; - if (port->type() == Shared::PortType::CONTROL) - _engine.control_bindings()->learn(port); - } - - QueuedEvent::pre_process(); -} - - -void -Learn::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_done || !_object) - return; - - NodeImpl* node = dynamic_cast(_object); - if (node) { - if (node->plugin_impl()->type() == Shared::Plugin::Internal) { - ((NodeBase*)_object)->learn(); - } else { - _error = INVALID_NODE_TYPE; - } - } -} - - -void -Learn::post_process() -{ - if (_error == NO_ERROR) { - _request->respond_ok(); - } else if (_object == NULL) { - string msg = "Did not find node '"; - msg.append(_path.str()).append("' for learn."); - _request->respond_error(msg); - } else { - const string msg = string("Object '") + _path.str() + "' is not capable of learning."; - _request->respond_error(msg); - } -} - - -} // namespace Ingen -} // namespace Events - - diff --git a/src/engine/events/Learn.hpp b/src/engine/events/Learn.hpp deleted file mode 100644 index fea8a53e..00000000 --- a/src/engine/events/Learn.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 Dave Robillard - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INGEN_EVENTS_LEARN_HPP -#define INGEN_EVENTS_LEARN_HPP - -#include "QueuedEvent.hpp" -#include "internals/Controller.hpp" -#include "types.hpp" - -namespace Ingen { - -class NodeImpl; - -namespace Events { - - -/** A MIDI learn event (used by control node to learn controller number). - * - * \ingroup engine - */ -class Learn : public QueuedEvent -{ -public: - Learn(Engine& engine, SharedPtr request, SampleCount timestamp, const Raul::Path& path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { - NO_ERROR, - INVALID_NODE_TYPE - }; - - ErrorType _error; - const Raul::Path _path; - GraphObjectImpl* _object; - bool _done; -}; - - -} // namespace Ingen -} // namespace Events - -#endif // INGEN_EVENTS_LEARN_HPP diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp index 77b67543..48de6b85 100644 --- a/src/engine/events/SetMetadata.cpp +++ b/src/engine/events/SetMetadata.cpp @@ -35,6 +35,8 @@ #include "SetMetadata.hpp" #include "SetPortValue.hpp" +#define LOG(s) s << "[SetMetadata] " + using namespace std; using namespace Raul; @@ -49,22 +51,34 @@ SetMetadata::SetMetadata( Engine& engine, SharedPtr request, SampleCount timestamp, - bool replace, + bool create, bool meta, const URI& subject, - const Properties& properties) + const Properties& properties, + const Properties& remove) : QueuedEvent(engine, request, timestamp, false) , _error(NO_ERROR) , _create_event(NULL) , _subject(subject) , _properties(properties) + , _remove(remove) , _object(NULL) , _patch(NULL) , _compiled_patch(NULL) - , _replace(replace) + , _create(create) , _is_meta(meta) - , _success(false) { + LOG(debug) << "Set " << subject << " {" << endl; + typedef Resource::Properties::const_iterator iterator; + for (iterator i = properties.begin(); i != properties.end(); ++i) + LOG(debug) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl; + LOG(debug) << "}" << endl; + + LOG(debug) << "Unset " << subject << " {" << endl; + typedef Resource::Properties::const_iterator iterator; + for (iterator i = remove.begin(); i != remove.end(); ++i) + LOG(debug) << " " << i->first << " = " << i->second << " :: " << i->second.type() << endl; + LOG(debug) << "}" << endl; } @@ -88,7 +102,7 @@ SetMetadata::pre_process() ? _engine.engine_store()->find_object(Path(_subject.str())) : _object = _engine.node_factory()->plugin(_subject); - if (!_object && !is_graph_object) { + if (!_object && (!is_graph_object || !_create)) { _error = NOT_FOUND; QueuedEvent::pre_process(); return; @@ -133,6 +147,7 @@ SetMetadata::pre_process() GraphObjectImpl* obj = dynamic_cast(_object); +#if 0 // If we're replacing (i.e. this is a PUT, not a POST), first remove all properties // with keys we will later set. This must be done first so a PUT with several properties // of the same predicate (e.g. rdf:type) retains the multiple values. Only previously @@ -140,6 +155,7 @@ SetMetadata::pre_process() if (_replace) for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p) obj->properties().erase(p->first); +#endif for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p) { const Raul::URI& key = p->first; @@ -149,14 +165,38 @@ SetMetadata::pre_process() Resource& resource = _is_meta ? obj->meta() : *obj; resource.add_property(key, value); - _patch = dynamic_cast(_object); - - if (key == uris.ingen_broadcast) { - if (value.type() == Atom::BOOL) - op = ENABLE_BROADCAST; - else - _error = BAD_VALUE_TYPE; - } else if (_patch) { + PortImpl* port = dynamic_cast(_object); + if (port) { + if (key == uris.ingen_broadcast) { + if (value.type() == Atom::BOOL) { + op = ENABLE_BROADCAST; + } else { + _error = BAD_VALUE_TYPE; + } + } else if (key == uris.ingen_value) { + PortImpl* port = dynamic_cast(_object); + if (port) { + SetPortValue* ev = new SetPortValue(_engine, _request, _time, port, value); + ev->pre_process(); + _set_events.push_back(ev); + } else { + _error = BAD_OBJECT_TYPE; + } + } else if (key == uris.ingen_controlBinding) { + PortImpl* port = dynamic_cast(_object); + if (port && port->type() == Shared::PortType::CONTROL) { + if (value == uris.wildcard) { + _engine.control_bindings()->learn(port); + } else if (value.type() == Atom::DICT) { + op = CONTROL_BINDING; + } else { + _error = BAD_VALUE_TYPE; + } + } else { + _error = BAD_OBJECT_TYPE; + } + } + } else if ((_patch = dynamic_cast(_object))) { if (key == uris.ingen_enabled) { if (value.type() == Atom::BOOL) { op = ENABLE; @@ -179,26 +219,6 @@ SetMetadata::pre_process() _error = BAD_VALUE_TYPE; } } - } else if (key == uris.ingen_value) { - PortImpl* port = dynamic_cast(_object); - if (port) { - SetPortValue* ev = new SetPortValue(_engine, _request, _time, port, value); - ev->pre_process(); - _set_events.push_back(ev); - } else { - warn << "Set value for non-port " << _object->uri() << endl; - } - } else if (key == uris.ingen_controlBinding) { - PortImpl* port = dynamic_cast(_object); - if (port) { - if (value.type() == Atom::DICT) { - op = CONTROL_BINDING; - } else { - _error = BAD_VALUE_TYPE; - } - } else { - warn << "Set binding for non-port " << _object->uri() << endl; - } } } @@ -210,6 +230,17 @@ SetMetadata::pre_process() _types.push_back(op); } + for (Properties::iterator p = _remove.begin(); p != _remove.end(); ++p) { + const Raul::URI& key = p->first; + const Raul::Atom& value = p->second; + if (key == uris.ingen_controlBinding && value == uris.wildcard) { + PortImpl* port = dynamic_cast(_object); + if (port) + _old_bindings = _engine.control_bindings()->remove(port); + } + _object->remove_property(key, value); + } + QueuedEvent::pre_process(); } @@ -233,14 +264,16 @@ SetMetadata::execute(ProcessContext& context) for (SetEvents::iterator i = _set_events.begin(); i != _set_events.end(); ++i) (*i)->execute(context); + GraphObjectImpl* const object = dynamic_cast(_object); + NodeBase* const node = dynamic_cast(_object); + PortImpl* const port = dynamic_cast(_object); + std::vector::const_iterator t = _types.begin(); - for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p, ++t) { - const Raul::Atom& value = p->second; - PortImpl* port = 0; - GraphObjectImpl* object = 0; + for (Properties::const_iterator p = _properties.begin(); p != _properties.end(); ++p, ++t) { + const Raul::Atom& value = p->second; switch (*t) { case ENABLE_BROADCAST: - if ((port = dynamic_cast(_object))) + if (port) port->broadcast(value.get_bool()); break; case ENABLE: @@ -253,7 +286,7 @@ SetMetadata::execute(ProcessContext& context) } break; case POLYPHONIC: - if ((object = dynamic_cast(_object))) + if (object) if (!object->set_polyphonic(*_engine.maid(), value.get_bool())) _error = INTERNAL; break; @@ -262,13 +295,22 @@ SetMetadata::execute(ProcessContext& context) _error = INTERNAL; break; case CONTROL_BINDING: - if ((port = dynamic_cast(_object))) + if (port) { _engine.control_bindings()->port_binding_changed(context, port); - default: - _success = true; + } else if (node) { + if (node->plugin_impl()->type() == Shared::Plugin::Internal) { + node->learn(); + } + } + break; + case NONE: + break; } } + for (Properties::const_iterator p = _remove.begin(); p != _remove.end(); ++p, ++t) + _object->remove_property(p->first, p->second); + QueuedEvent::execute(context); } @@ -282,7 +324,10 @@ SetMetadata::post_process() switch (_error) { case NO_ERROR: _request->respond_ok(); - _engine.broadcaster()->put(_subject, _properties); + if (_create) + _engine.broadcaster()->put(_subject, _properties); + else + _engine.broadcaster()->delta(_subject, _remove, _properties); if (_create_event) _create_event->post_process(); break; diff --git a/src/engine/events/SetMetadata.hpp b/src/engine/events/SetMetadata.hpp index 0abdd52a..b4b1d0ef 100644 --- a/src/engine/events/SetMetadata.hpp +++ b/src/engine/events/SetMetadata.hpp @@ -69,10 +69,11 @@ public: Engine& engine, SharedPtr request, SampleCount timestamp, - bool replace, + bool create, bool meta, const Raul::URI& subject, - const Shared::Resource::Properties& properties); + const Shared::Resource::Properties& properties, + const Shared::Resource::Properties& remove=Shared::Resource::Properties()); ~SetMetadata(); @@ -102,15 +103,19 @@ private: QueuedEvent* _create_event; SetEvents _set_events; std::vector _types; + std::vector _remove_types; Raul::URI _subject; Shared::Resource::Properties _properties; + Shared::Resource::Properties _remove; Shared::ResourceImpl* _object; PatchImpl* _patch; CompiledPatch* _compiled_patch; std::string _error_predicate; - bool _replace; + bool _create; bool _is_meta; bool _success; + + SharedPtr _old_bindings; }; diff --git a/src/engine/internals/Controller.cpp b/src/engine/internals/Controller.cpp index 941f7e49..634fc152 100644 --- a/src/engine/internals/Controller.cpp +++ b/src/engine/internals/Controller.cpp @@ -20,7 +20,6 @@ #include "shared/LV2URIMap.hpp" #include "internals/Controller.hpp" #include "PostProcessor.hpp" -#include "events/Learn.hpp" #include "events/SendPortValue.hpp" #include "InputPort.hpp" #include "OutputPort.hpp" diff --git a/src/engine/wscript b/src/engine/wscript index 7e630387..12e61121 100644 --- a/src/engine/wscript +++ b/src/engine/wscript @@ -43,7 +43,6 @@ def build(bld): events/Disconnect.cpp events/DisconnectAll.cpp events/Get.cpp - events/Learn.cpp events/LoadPlugins.cpp events/Move.cpp events/Note.cpp -- cgit v1.2.1