summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-06-09 17:21:44 +0000
committerDavid Robillard <d@drobilla.net>2008-06-09 17:21:44 +0000
commit4e736d0b31c56a7ab397c7399b3a53f726466c78 (patch)
treea9640733f976926b5e4a9ddcea4fcffed9337fbe
parentb3448dcc7c06fb19daee66dc2cf1cea79086e770 (diff)
downloadingen-4e736d0b31c56a7ab397c7399b3a53f726466c78.tar.gz
ingen-4e736d0b31c56a7ab397c7399b3a53f726466c78.tar.bz2
ingen-4e736d0b31c56a7ab397c7399b3a53f726466c78.zip
Bump liblo dependency to 0.24.
Bundleify communications where order is relevant (fixes 'random' issues like node positions being off, ticket #89, etc). git-svn-id: http://svn.drobilla.net/lad/ingen@1248 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--configure.ac2
-rw-r--r--src/libs/client/OSCClientReceiver.cpp6
-rw-r--r--src/libs/engine/ClientBroadcaster.cpp16
-rw-r--r--src/libs/engine/ClientBroadcaster.hpp3
-rw-r--r--src/libs/engine/OSCClientSender.cpp148
-rw-r--r--src/libs/engine/OSCClientSender.hpp11
-rw-r--r--src/libs/engine/ObjectSender.cpp20
-rw-r--r--src/libs/engine/events/DestroyEvent.cpp4
8 files changed, 121 insertions, 89 deletions
diff --git a/configure.ac b/configure.ac
index 975d7b76..a978a02e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -140,7 +140,7 @@ if test "$build_jack" = "yes"; then
fi
# OSC support (mandatory for now due to laziness)
-PKG_CHECK_MODULES(LIBLO, liblo)
+PKG_CHECK_MODULES(LIBLO, liblo >= 0.24)
# LV2 support
build_lv2="yes"
diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp
index 6002ca59..3f5447d0 100644
--- a/src/libs/client/OSCClientReceiver.cpp
+++ b/src/libs/client/OSCClientReceiver.cpp
@@ -31,9 +31,9 @@ namespace Client {
OSCClientReceiver::OSCClientReceiver(int listen_port)
-: ClientInterface("localhost"),
- _listen_port(listen_port),
- _st(NULL)
+ : ClientInterface("localhost")
+ , _listen_port(listen_port)
+ , _st(NULL)
{
start(false); // true = dump, false = shutup
}
diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp
index 16785b42..a3e7bc42 100644
--- a/src/libs/engine/ClientBroadcaster.cpp
+++ b/src/libs/engine/ClientBroadcaster.cpp
@@ -91,6 +91,22 @@ ClientBroadcaster::client(const string& uri)
}
}
+
+void
+ClientBroadcaster::bundle_begin()
+{
+ for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i)
+ (*i).second->bundle_begin();
+}
+
+
+void
+ClientBroadcaster::bundle_end()
+{
+ for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i)
+ (*i).second->bundle_end();
+}
+
void
ClientBroadcaster::send_error(const string& msg)
diff --git a/src/libs/engine/ClientBroadcaster.hpp b/src/libs/engine/ClientBroadcaster.hpp
index 73353588..800f6950 100644
--- a/src/libs/engine/ClientBroadcaster.hpp
+++ b/src/libs/engine/ClientBroadcaster.hpp
@@ -60,6 +60,9 @@ public:
//void send_client_registration(const string& url, int client_id);
+ void bundle_begin();
+ void bundle_end();
+
// Error that isn't the direct result of a request
void send_error(const string& msg);
diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp
index 7a62b3b7..aff7fa50 100644
--- a/src/libs/engine/OSCClientSender.cpp
+++ b/src/libs/engine/OSCClientSender.cpp
@@ -38,14 +38,15 @@ namespace Ingen {
void
OSCClientSender::bundle_begin()
{
- // FIXME: Don't split bundles as for 'transfers'
+ assert(!_transfer);
_transfer = lo_bundle_new(LO_TT_IMMEDIATE);
+ _send_state = SendingBundle;
+
}
void
OSCClientSender::bundle_end()
{
- // FIXME: Don't split bundles as for 'transfers'
transfer_end();
}
@@ -53,20 +54,72 @@ OSCClientSender::bundle_end()
void
OSCClientSender::transfer_begin()
{
+ //cerr << "TRANSFER {" << endl;
+ assert(!_transfer);
_transfer = lo_bundle_new(LO_TT_IMMEDIATE);
+ _send_state = SendingTransfer;
}
void
OSCClientSender::transfer_end()
{
+ //cerr << "} TRANSFER" << endl;
assert(_transfer);
lo_send_bundle(_address, _transfer);
lo_bundle_free(_transfer);
_transfer = NULL;
+ _send_state = Immediate;
+}
+
+
+int
+OSCClientSender::send(const char *path, const char *types, ...)
+{
+ if (!_enabled)
+ return 0;
+
+ va_list args;
+ va_start(args, types);
+
+ lo_message msg = lo_message_new();
+ int ret = lo_message_add_varargs(msg, types, args);
+
+ if (!ret)
+ send_message(path, msg);
+
+ va_end(args);
+
+ return ret;
+}
+
+
+void
+OSCClientSender::send_message(const char* path, lo_message msg)
+{
+ // FIXME: size? liblo doesn't export this.
+ // Don't want to exceed max UDP packet size (1500 bytes?})
+ static const size_t MAX_BUNDLE_SIZE = 1500 - 32*5;
+
+ if (!_enabled)
+ return;
+
+ if (_transfer) {
+ if (lo_bundle_length(_transfer) + lo_message_length(msg, path) > MAX_BUNDLE_SIZE) {
+ if (_send_state == SendingBundle)
+ cerr << "WARNING: Maximum bundle size reached, bundle split" << endl;
+ lo_send_bundle(_address, _transfer);
+ _transfer = lo_bundle_new(LO_TT_IMMEDIATE);
+ }
+ lo_bundle_add_message(_transfer, path, msg);
+
+ } else {
+ lo_send_message(_address, path, msg);
+ }
}
+
/*! \page client_osc_namespace Client OSC Namespace Documentation
*
* <p>NOTE: this comment doesn't really apply any longer.. sort of.
@@ -149,10 +202,7 @@ OSCClientSender::response_error(int32_t id, const std::string& msg)
void
OSCClientSender::error(const std::string& msg)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/error", "s", msg.c_str());
+ send("/ingen/error", "s", msg.c_str(), LO_ARGS_END);
}
@@ -173,12 +223,7 @@ OSCClientSender::error(const std::string& msg)
void
OSCClientSender::num_plugins(uint32_t num)
{
- if (!_enabled)
- return;
-
- lo_message m = lo_message_new();
- lo_message_add_int32(m, num);
- lo_send_message(_address, "/ingen/num_plugins", m);
+ send("/ingen/num_plugins", "i", num, LO_ARGS_END);
}
@@ -255,15 +300,12 @@ void OSCClientSender::new_node(const std::string& plugin_uri,
bool is_polyphonic,
uint32_t num_ports)
{
- if (!_enabled)
- return;
-
if (is_polyphonic)
- lo_send(_address, "/ingen/new_node", "ssTi", plugin_uri.c_str(),
- node_path.c_str(), num_ports);
+ send("/ingen/new_node", "ssTi", plugin_uri.c_str(),
+ node_path.c_str(), num_ports, LO_ARGS_END);
else
- lo_send(_address, "/ingen/new_node", "ssFi", plugin_uri.c_str(),
- node_path.c_str(), num_ports);
+ send("/ingen/new_node", "ssFi", plugin_uri.c_str(),
+ node_path.c_str(), num_ports, LO_ARGS_END);
}
@@ -289,10 +331,7 @@ OSCClientSender::new_port(const std::string& path,
const std::string& data_type,
bool is_output)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/new_port", "sisi", path.c_str(), index, data_type.c_str(), is_output);
+ send("/ingen/new_port", "sisi", path.c_str(), index, data_type.c_str(), is_output, LO_ARGS_END);
}
@@ -327,12 +366,9 @@ OSCClientSender::polyphonic(const std::string& path,
void
OSCClientSender::object_destroyed(const std::string& path)
{
- if (!_enabled)
- return;
-
assert(path != "/");
- lo_send(_address, "/ingen/destroyed", "s", path.c_str());
+ send("/ingen/destroyed", "s", path.c_str(), LO_ARGS_END);
}
@@ -343,10 +379,7 @@ OSCClientSender::object_destroyed(const std::string& path)
void
OSCClientSender::patch_cleared(const std::string& patch_path)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/patch_cleared", "s", patch_path.c_str());
+ send("/ingen/patch_cleared", "s", patch_path.c_str(), LO_ARGS_END);
}
@@ -357,10 +390,7 @@ OSCClientSender::patch_cleared(const std::string& patch_path)
void
OSCClientSender::patch_enabled(const std::string& patch_path)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/patch_enabled", "s", patch_path.c_str());
+ send("/ingen/patch_enabled", "s", patch_path.c_str(), LO_ARGS_END);
}
@@ -371,10 +401,7 @@ OSCClientSender::patch_enabled(const std::string& patch_path)
void
OSCClientSender::patch_disabled(const std::string& patch_path)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/patch_disabled", "s", patch_path.c_str());
+ send("/ingen/patch_disabled", "s", patch_path.c_str(), LO_ARGS_END);
}
@@ -401,10 +428,7 @@ OSCClientSender::patch_polyphony(const std::string& patch_path, uint32_t poly)
void
OSCClientSender::connection(const std::string& src_port_path, const std::string& dst_port_path)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/new_connection", "ss", src_port_path.c_str(), dst_port_path.c_str());
+ send("/ingen/new_connection", "ss", src_port_path.c_str(), dst_port_path.c_str(), LO_ARGS_END);
}
@@ -416,10 +440,7 @@ OSCClientSender::connection(const std::string& src_port_path, const std::string&
void
OSCClientSender::disconnection(const std::string& src_port_path, const std::string& dst_port_path)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/disconnection", "ss", src_port_path.c_str(), dst_port_path.c_str());
+ send("/ingen/disconnection", "ss", src_port_path.c_str(), dst_port_path.c_str(), LO_ARGS_END);
}
@@ -432,14 +453,11 @@ OSCClientSender::disconnection(const std::string& src_port_path, const std::stri
void
OSCClientSender::variable_change(const std::string& path, const std::string& key, const Atom& value)
{
- if (!_enabled)
- return;
-
lo_message m = lo_message_new();
lo_message_add_string(m, path.c_str());
lo_message_add_string(m, key.c_str());
Raul::AtomLiblo::lo_message_add_atom(m, value);
- lo_send_message(_address, "/ingen/variable_change", m);
+ send_message("/ingen/variable_change", m);
}
@@ -451,10 +469,7 @@ OSCClientSender::variable_change(const std::string& path, const std::string& key
void
OSCClientSender::control_change(const std::string& port_path, float value)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/control_change", "sf", port_path.c_str(), value);
+ send("/ingen/control_change", "sf", port_path.c_str(), value, LO_ARGS_END);
}
@@ -485,9 +500,6 @@ OSCClientSender::new_plugin(const std::string& uri,
const std::string& symbol,
const std::string& name)
{
- if (!_enabled)
- return;
-
// FIXME: size? liblo doesn't export this.
// Don't want to exceed max UDP packet size (1500 bytes)
static const size_t MAX_BUNDLE_SIZE = 1500 - 32*5;
@@ -521,10 +533,7 @@ OSCClientSender::new_plugin(const std::string& uri,
void
OSCClientSender::new_patch(const std::string& path, uint32_t poly)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/new_patch", "si", path.c_str(), poly);
+ send("/ingen/new_patch", "si", path.c_str(), poly, LO_ARGS_END);
/*
if (p->process())
@@ -547,10 +556,7 @@ OSCClientSender::new_patch(const std::string& path, uint32_t poly)
void
OSCClientSender::object_renamed(const std::string& old_path, const std::string& new_path)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/object_renamed", "ss", old_path.c_str(), new_path.c_str());
+ send("/ingen/object_renamed", "ss", old_path.c_str(), new_path.c_str(), LO_ARGS_END);
}
@@ -559,10 +565,7 @@ OSCClientSender::object_renamed(const std::string& old_path, const std::string&
void
OSCClientSender::program_add(const std::string& node_path, uint32_t bank, uint32_t program, const std::string& name)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/program_add", "siis",
+ send("/ingen/program_add", "siis",
node_path.c_str(), bank, program, name.c_str());
}
@@ -570,10 +573,7 @@ OSCClientSender::program_add(const std::string& node_path, uint32_t bank, uint32
void
OSCClientSender::program_remove(const std::string& node_path, uint32_t bank, uint32_t program)
{
- if (!_enabled)
- return;
-
- lo_send(_address, "/ingen/program_remove", "sii",
+ send("/ingen/program_remove", "sii",
node_path.c_str(), bank, program);
}
diff --git a/src/libs/engine/OSCClientSender.hpp b/src/libs/engine/OSCClientSender.hpp
index d6a25fd2..cd2264df 100644
--- a/src/libs/engine/OSCClientSender.hpp
+++ b/src/libs/engine/OSCClientSender.hpp
@@ -134,11 +134,16 @@ public:
uint32_t program);
private:
- lo_address _address;
+ int send(const char *path, const char *types, ...);
+ void send_message(const char* path, lo_message m);
- lo_bundle _transfer;
+ enum SendState { Immediate, SendingBundle, SendingTransfer };
- bool _enabled;
+ string _url;
+ lo_address _address;
+ SendState _send_state;
+ lo_bundle _transfer;
+ bool _enabled;
};
diff --git a/src/libs/engine/ObjectSender.cpp b/src/libs/engine/ObjectSender.cpp
index f51f0ad0..fff2a797 100644
--- a/src/libs/engine/ObjectSender.cpp
+++ b/src/libs/engine/ObjectSender.cpp
@@ -33,9 +33,21 @@ namespace Ingen {
void
ObjectSender::send_patch(ClientInterface* client, const PatchImpl* patch, bool recursive)
{
+ client->bundle_begin();
+
client->new_patch(patch->path(), patch->internal_polyphony());
client->polyphonic(patch->path(), patch->polyphonic());
+ // Send variable
+ const GraphObjectImpl::Variables& data = patch->variables();
+ for (GraphObjectImpl::Variables::const_iterator j = data.begin(); j != data.end(); ++j)
+ client->variable_change(patch->path(), (*j).first, (*j).second);
+
+ if (patch->enabled())
+ client->patch_enabled(patch->path());
+
+ client->bundle_end();
+
if (recursive) {
// Send nodes
@@ -60,14 +72,6 @@ ObjectSender::send_patch(ClientInterface* client, const PatchImpl* patch, bool r
client->connection((*j)->src_port_path(), (*j)->dst_port_path());
}
-
- // Send variable
- const GraphObjectImpl::Variables& data = patch->variables();
- for (GraphObjectImpl::Variables::const_iterator j = data.begin(); j != data.end(); ++j)
- client->variable_change(patch->path(), (*j).first, (*j).second);
-
- if (patch->enabled())
- client->patch_enabled(patch->path());
}
diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp
index 9a235807..eef7ea0e 100644
--- a/src/libs/engine/events/DestroyEvent.cpp
+++ b/src/libs/engine/events/DestroyEvent.cpp
@@ -182,16 +182,20 @@ DestroyEvent::post_process()
assert(_node);
_node->deactivate();
_responder->respond_ok();
+ _engine.broadcaster()->bundle_begin();
if (_disconnect_node_event)
_disconnect_node_event->post_process();
_engine.broadcaster()->send_destroyed(_path);
+ _engine.broadcaster()->bundle_end();
_engine.maid()->push(_patch_node_listnode);
} else if (_patch_port_listnode) {
assert(_port);
_responder->respond_ok();
+ _engine.broadcaster()->bundle_begin();
if (_disconnect_port_event)
_disconnect_port_event->post_process();
_engine.broadcaster()->send_destroyed(_path);
+ _engine.broadcaster()->bundle_end();
_engine.maid()->push(_patch_port_listnode);
} else {
_responder->respond_error("Unable to destroy object");