summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/ClientBroadcaster.hpp6
-rw-r--r--src/engine/ControlBindings.cpp23
-rw-r--r--src/engine/ControlBindings.hpp6
-rw-r--r--src/engine/HTTPClientSender.cpp8
-rw-r--r--src/engine/HTTPClientSender.hpp4
-rw-r--r--src/engine/LV2Node.cpp1
-rw-r--r--src/engine/OSCClientSender.cpp53
-rw-r--r--src/engine/OSCClientSender.hpp4
-rw-r--r--src/engine/OSCEngineReceiver.cpp116
-rw-r--r--src/engine/QueuedEngineInterface.cpp33
-rw-r--r--src/engine/QueuedEngineInterface.hpp6
-rw-r--r--src/engine/events.hpp1
-rw-r--r--src/engine/events/Learn.cpp99
-rw-r--r--src/engine/events/Learn.hpp61
-rw-r--r--src/engine/events/SetMetadata.cpp131
-rw-r--r--src/engine/events/SetMetadata.hpp11
-rw-r--r--src/engine/internals/Controller.cpp1
-rw-r--r--src/engine/wscript1
18 files changed, 248 insertions, 317 deletions
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::Bindings>
+ControlBindings::remove(PortImpl* port)
+{
+ ThreadManager::assert_thread(THREAD_PRE_PROCESS);
+
+ SharedPtr<Bindings> old_bindings(_bindings);
+ SharedPtr<Bindings> 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<Bindings> 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<Bindings> 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
@@ -72,6 +72,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)
{
assert(!path.is_root());
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
- * <h2>/ingen/ok</h2>
+ * <h2>/ok</h2>
* \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
- * <h2>/ingen/error</h2>
+ * <h2>/error</h2>
* \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
- * <h2>/ingen/error</h2>
+ * <h2>/error</h2>
* \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
- * <h2>/ingen/put</h2>
+ * <h2>/put</h2>
* \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
- * <h2>/ingen/move</h2>
+ * <h2>/move</h2>
* \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
- * <h2>/ingen/delete</h2>
+ * <h2>/delete</h2>
* \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
- * <h2>/ingen/new_connection</h2>
+ * <h2>/connect</h2>
* \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
- * <h2>/ingen/disconnection</h2>
+ * <h2>/disconnect</h2>
* \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
- * <h2>/ingen/set_property</h2>
+ * <h2>/set_property</h2>
* \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
- * <h2>/ingen/set_port_value</h2>
+ * <h2>/set_port_value</h2>
* \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
- * <h2>/ingen/activity</h2>
+ * <h2>/activity</h2>
* \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
- * <h2>/ingen/ping</h2>
+ * <h2>/ping</h2>
* \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
- * <h2>/ingen/ping_queued</h2>
+ * <h2>/ping_queued</h2>
* \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
- * <h2>/ingen/quit</h2>
+ * <h2>/quit</h2>
* \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
- * <h2>/ingen/register_client</h2>
+ * <h2>/register_client</h2>
* \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
- * <h2>/ingen/unregister_client</h2>
+ * <h2>/unregister_client</h2>
* \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
- * <h2>/ingen/load_plugins</h2>
+ * <h2>/load_plugins</h2>
* \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
- * <h2>/ingen/activate</h2>
+ * <h2>/activate</h2>
* \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
- * <h2>/ingen/deactivate</h2>
+ * <h2>/deactivate</h2>
* \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
- * <h2>/ingen/get</h2>
+ * <h2>/get</h2>
* \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
- * <h2>/ingen/put</h2>
+ * <h2>/put</h2>
* \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
- * <h2>/ingen/move</h2>
+ * <h2>/move</h2>
* \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
- * <h2>/ingen/del</h2>
+ * <h2>/del</h2>
* \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
- * <h2>/ingen/connect</h2>
+ * <h2>/connect</h2>
* \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
- * <h2>/ingen/disconnect</h2>
+ * <h2>/disconnect</h2>
* \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
- * <h2>/ingen/disconnect_all</h2>
+ * <h2>/disconnect_all</h2>
* \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
- * <h2>/ingen/note_on</h2>
+ * <h2>/note_on</h2>
* \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
- * <h2>/ingen/note_off</h2>
+ * <h2>/note_off</h2>
* \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
- * <h2>/ingen/all_notes_off</h2>
+ * <h2>/all_notes_off</h2>
* \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
- * <h2>/ingen/learn</h2>
- * \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
- * <h2>/ingen/set_property</h2>
+ * <h2>/set_property</h2>
* \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
- * <h2>/ingen/request_property</h2>
+ * <h2>/request_property</h2>
* \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
- * <h2>/ingen/request_plugins</h2>
+ * <h2>/request_plugins</h2>
* \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
- * <h2>/ingen/request_all_objects</h2>
+ * <h2>/request_all_objects</h2>
* \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,17 +160,23 @@ 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)
{
@@ -220,13 +226,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,
const Atom& value)
@@ -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 <http://drobilla.net>
- *
- * 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> 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<PortImpl*>(_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<NodeImpl*>(_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 <http://drobilla.net>
- *
- * 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> 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> 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<GraphObjectImpl*>(_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<PatchImpl*>(_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<PortImpl*>(_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<PortImpl*>(_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<PortImpl*>(_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<PatchImpl*>(_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<PortImpl*>(_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<PortImpl*>(_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<PortImpl*>(_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<GraphObjectImpl*>(_object);
+ NodeBase* const node = dynamic_cast<NodeBase*>(_object);
+ PortImpl* const port = dynamic_cast<PortImpl*>(_object);
+
std::vector<SpecialType>::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<PortImpl*>(_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<GraphObjectImpl*>(_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<PortImpl*>(_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> 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<SpecialType> _types;
+ std::vector<SpecialType> _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<ControlBindings::Bindings> _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