summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common/interface/ClientInterface.hpp2
-rw-r--r--src/common/interface/EngineInterface.hpp2
-rw-r--r--src/libs/client/ClientStore.cpp10
-rw-r--r--src/libs/client/HTTPClientReceiver.cpp97
-rw-r--r--src/libs/client/HTTPClientReceiver.hpp62
-rw-r--r--src/libs/client/HTTPEngineSender.cpp300
-rw-r--r--src/libs/client/HTTPEngineSender.hpp162
-rw-r--r--src/libs/client/Makefile.am16
-rw-r--r--src/libs/client/NodeModel.cpp12
-rw-r--r--src/libs/client/NodeModel.hpp9
-rw-r--r--src/libs/client/OSCClientReceiver.hpp14
-rw-r--r--src/libs/client/OSCEngineSender.hpp8
-rw-r--r--src/libs/client/ObjectModel.cpp33
-rw-r--r--src/libs/client/PortModel.cpp4
-rw-r--r--src/libs/client/PortModel.hpp2
-rw-r--r--src/libs/client/SigClientInterface.hpp2
-rw-r--r--src/libs/client/ThreadedSigClientInterface.cpp32
-rw-r--r--src/libs/client/ThreadedSigClientInterface.hpp13
-rw-r--r--src/libs/client/client.cpp24
-rw-r--r--src/libs/client/client.hpp2
-rw-r--r--src/libs/engine/OSCClientSender.hpp2
-rw-r--r--src/libs/engine/OSCEngineReceiver.cpp2
-rw-r--r--src/libs/engine/QueuedEngineInterface.hpp3
-rw-r--r--src/libs/gui/ConnectWindow.cpp26
-rw-r--r--src/libs/gui/ConnectWindow.hpp2
-rw-r--r--src/libs/gui/ControlPanel.cpp2
-rw-r--r--src/libs/gui/Makefile.am6
-rw-r--r--src/libs/gui/NodeControlWindow.cpp2
-rw-r--r--src/libs/gui/NodeMenu.cpp2
-rw-r--r--src/libs/gui/NodeModule.cpp8
-rw-r--r--src/libs/gui/NodePropertiesWindow.cpp2
-rw-r--r--src/libs/gui/PatchCanvas.cpp5
-rw-r--r--src/libs/gui/PatchTreeWindow.cpp2
-rw-r--r--src/libs/gui/PatchWindow.cpp4
-rw-r--r--src/libs/serialisation/Parser.cpp49
-rw-r--r--src/libs/serialisation/Parser.hpp8
-rw-r--r--src/libs/shared/OSCSender.cpp4
-rw-r--r--src/libs/shared/OSCSender.hpp2
-rw-r--r--src/progs/ingen/main.cpp14
39 files changed, 819 insertions, 132 deletions
diff --git a/src/common/interface/ClientInterface.hpp b/src/common/interface/ClientInterface.hpp
index e7ddfeaf..2d604ced 100644
--- a/src/common/interface/ClientInterface.hpp
+++ b/src/common/interface/ClientInterface.hpp
@@ -42,6 +42,8 @@ public:
virtual void response_ok(int32_t id) = 0;
virtual void response_error(int32_t id, const std::string& msg) = 0;
+
+ virtual bool enabled() const = 0;
virtual void enable() = 0;
diff --git a/src/common/interface/EngineInterface.hpp b/src/common/interface/EngineInterface.hpp
index b82bf8c2..a9b2a0c1 100644
--- a/src/common/interface/EngineInterface.hpp
+++ b/src/common/interface/EngineInterface.hpp
@@ -38,6 +38,8 @@ class EngineInterface : public CommonInterface
{
public:
virtual ~EngineInterface() {}
+
+ virtual std::string uri() const = 0;
// Responses
virtual void set_next_response_id(int32_t id) = 0;
diff --git a/src/libs/client/ClientStore.cpp b/src/libs/client/ClientStore.cpp
index 0597aa21..18582046 100644
--- a/src/libs/client/ClientStore.cpp
+++ b/src/libs/client/ClientStore.cpp
@@ -72,17 +72,15 @@ ClientStore::add_plugin_orphan(SharedPtr<NodeModel> node)
{
if (!_handle_orphans)
return;
- cerr << "WARNING: Node " << node->path() << " received, but plugin "
- << node->plugin_uri() << " unknown." << endl;
Raul::Table<string, list<SharedPtr<NodeModel> > >::iterator spawn
= _plugin_orphans.find(node->plugin_uri());
- _engine->request_plugin(node->plugin_uri());
-
if (spawn != _plugin_orphans.end()) {
spawn->second.push_back(node);
} else {
+ cerr << "WARNING: Orphans of plugin " << node->plugin_uri() << " received" << endl;
+ _engine->request_plugin(node->plugin_uri());
list<SharedPtr<NodeModel> > l;
l.push_back(node);
_plugin_orphans[node->plugin_uri()] = l;
@@ -108,7 +106,7 @@ ClientStore::resolve_plugin_orphans(SharedPtr<PluginModel> plugin)
for (list<SharedPtr<NodeModel> >::iterator i = spawn.begin();
i != spawn.end(); ++i) {
(*i)->_plugin = plugin;
- add_object(*i);
+ //add_object(*i);
}
}
}
@@ -248,7 +246,6 @@ ClientStore::add_object(SharedPtr<ObjectModel> object)
// one (with precedence to the new values).
iterator existing = find(object->path());
if (existing != end()) {
- cout << "WARNING: Object " << object->path() << " already exists in store" << endl;
PtrCast<ObjectModel>(existing->second)->set(object);
} else {
@@ -444,6 +441,7 @@ ClientStore::new_node(const string& path, const string& plugin_uri)
if (!plug) {
SharedPtr<NodeModel> n(new NodeModel(plugin_uri, path));
add_plugin_orphan(n);
+ add_object(n);
} else {
SharedPtr<NodeModel> n(new NodeModel(plug, path));
add_object(n);
diff --git a/src/libs/client/HTTPClientReceiver.cpp b/src/libs/client/HTTPClientReceiver.cpp
new file mode 100644
index 00000000..ece55ab2
--- /dev/null
+++ b/src/libs/client/HTTPClientReceiver.cpp
@@ -0,0 +1,97 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2008 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 <list>
+#include <cassert>
+#include <cstring>
+#include <iostream>
+#include <sstream>
+#include <raul/AtomLiblo.hpp>
+#include "module/Module.hpp"
+#include "HTTPClientReceiver.hpp"
+
+using namespace std;
+using namespace Raul;
+
+namespace Ingen {
+namespace Client {
+
+
+HTTPClientReceiver::HTTPClientReceiver(
+ Shared::World* world,
+ const std::string& url,
+ SharedPtr<Shared::ClientInterface> target)
+ : _target(target)
+ , _world(world)
+ , _url(url)
+ , _session(NULL)
+{
+ start(false);
+}
+
+
+HTTPClientReceiver::~HTTPClientReceiver()
+{
+ stop();
+}
+
+
+void
+HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, void* ptr)
+{
+ HTTPClientReceiver* me = (HTTPClientReceiver*)ptr;
+ cout << "RECEIVED ASYNC MESSAGE: " << msg->response_body->data << endl;
+ me->_target->response_ok(0);
+ me->_target->enable();
+ me->_parser->parse_string(me->_world, me->_target.get(), Glib::ustring(msg->response_body->data),
+ Glib::ustring("/"), Glib::ustring(""));
+}
+
+
+void
+HTTPClientReceiver::start(bool dump)
+{
+ Glib::Mutex::Lock lock(_world->rdf_world->mutex());
+ if (!_parser) {
+ if (!_world->serialisation_module)
+ _world->serialisation_module = Ingen::Shared::load_module("ingen_serialisation");
+
+ if (_world->serialisation_module) {
+ Parser* (*new_parser)() = NULL;
+ if (_world->serialisation_module->get_symbol("new_parser", (void*&)new_parser))
+ _parser = SharedPtr<Parser>(new_parser());
+ }
+ }
+ _session = soup_session_async_new();
+ SoupMessage* msg = soup_message_new("GET", _url.c_str());
+ soup_session_queue_message (_session, msg, message_callback, this);
+}
+
+
+void
+HTTPClientReceiver::stop()
+{
+ if (_session != NULL) {
+ //unregister_client();
+ soup_session_abort(_session);
+ _session = NULL;
+ }
+}
+
+
+} // namespace Client
+} // namespace Ingen
diff --git a/src/libs/client/HTTPClientReceiver.hpp b/src/libs/client/HTTPClientReceiver.hpp
new file mode 100644
index 00000000..bab55578
--- /dev/null
+++ b/src/libs/client/HTTPClientReceiver.hpp
@@ -0,0 +1,62 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2008 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 HTTPCLIENTRECEIVER_H
+#define HTTPCLIENTRECEIVER_H
+
+#include <cstdlib>
+#include <boost/utility.hpp>
+#include <libsoup/soup.h>
+#include "interface/ClientInterface.hpp"
+#include "serialisation/Parser.hpp"
+#include "redlandmm/World.hpp"
+#include "raul/Deletable.hpp"
+
+namespace Ingen {
+namespace Client {
+
+
+class HTTPClientReceiver : public boost::noncopyable, public Raul::Deletable
+{
+public:
+ HTTPClientReceiver(Shared::World* world,
+ const std::string& url,
+ SharedPtr<Shared::ClientInterface> target);
+
+ ~HTTPClientReceiver();
+
+ std::string uri() const { return _url; }
+
+ void start(bool dump);
+ void stop();
+
+private:
+ static void message_callback(SoupSession* session, SoupMessage* msg, void* ptr);
+
+ SharedPtr<Shared::ClientInterface> _target;
+
+ Shared::World* _world;
+ const std::string _url;
+ SoupSession* _session;
+ SharedPtr<Parser> _parser;
+};
+
+
+} // namespace Client
+} // namespace Ingen
+
+#endif // HTTPCLIENTRECEIVER_H
diff --git a/src/libs/client/HTTPEngineSender.cpp b/src/libs/client/HTTPEngineSender.cpp
new file mode 100644
index 00000000..882a4bc4
--- /dev/null
+++ b/src/libs/client/HTTPEngineSender.cpp
@@ -0,0 +1,300 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2008 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 <iostream>
+#include <libsoup/soup.h>
+#include "HTTPEngineSender.hpp"
+
+using namespace std;
+
+namespace Ingen {
+namespace Client {
+
+
+HTTPEngineSender::HTTPEngineSender(const string& engine_url)
+ : _engine_url(engine_url)
+ , _id(0)
+ , _enabled(true)
+{
+ _session = soup_session_sync_new();
+}
+
+
+HTTPEngineSender::~HTTPEngineSender()
+{
+ soup_session_abort(_session);
+}
+
+
+void
+HTTPEngineSender::attach(int32_t ping_id, bool block)
+{
+ /*SoupMessage *msg;
+ msg = soup_message_new ("GET", _engine_url.c_str());
+ int status = soup_session_send_message (_session, msg);
+ cout << "STATUS: " << status << endl;
+ cout << "RESPONSE: " << msg->response_body->data << endl;*/
+}
+
+
+/* *** EngineInterface implementation below here *** */
+
+
+/** Register with the engine via HTTP.
+ *
+ * Note that this does not actually use 'key', since the engine creates
+ * it's own key for HTTP clients (namely the incoming URL), for NAT
+ * traversal. It is a parameter to remain compatible with EngineInterface.
+ */
+void
+HTTPEngineSender::register_client(ClientInterface* client)
+{
+
+}
+
+
+void
+HTTPEngineSender::unregister_client(const string& uri)
+{
+
+}
+
+
+// Engine commands
+void
+HTTPEngineSender::load_plugins()
+{
+
+}
+
+
+void
+HTTPEngineSender::activate()
+{
+
+}
+
+
+void
+HTTPEngineSender::deactivate()
+{
+
+}
+
+
+void
+HTTPEngineSender::quit()
+{
+
+}
+
+
+
+// Object commands
+
+void
+HTTPEngineSender::new_patch(const string& path,
+ uint32_t poly)
+{
+}
+
+
+void
+HTTPEngineSender::new_port(const string& path,
+ uint32_t index,
+ const string& data_type,
+ bool is_output)
+{
+}
+
+
+void
+HTTPEngineSender::new_node(const string& path,
+ const string& plugin_uri)
+{
+}
+
+
+/** Create a node using library name and plugin label (DEPRECATED).
+ *
+ * DO NOT USE THIS.
+ */
+void
+HTTPEngineSender::new_node_deprecated(const string& path,
+ const string& plugin_type,
+ const string& library_name,
+ const string& plugin_label)
+{
+}
+
+
+void
+HTTPEngineSender::rename(const string& old_path,
+ const string& new_name)
+{
+}
+
+
+void
+HTTPEngineSender::destroy(const string& path)
+{
+}
+
+
+void
+HTTPEngineSender::clear_patch(const string& patch_path)
+{
+}
+
+
+void
+HTTPEngineSender::connect(const string& src_port_path,
+ const string& dst_port_path)
+{
+}
+
+
+void
+HTTPEngineSender::disconnect(const string& src_port_path,
+ const string& dst_port_path)
+{
+}
+
+
+void
+HTTPEngineSender::disconnect_all(const string& parent_patch_path,
+ const string& node_path)
+{
+}
+
+
+void
+HTTPEngineSender::set_port_value(const string& port_path,
+ const Raul::Atom& value)
+{
+}
+
+
+void
+HTTPEngineSender::set_voice_value(const string& port_path,
+ uint32_t voice,
+ const Raul::Atom& value)
+{
+}
+
+
+void
+HTTPEngineSender::set_port_value_immediate(const string& port_path,
+ const Raul::Atom& value)
+{
+}
+
+
+void
+HTTPEngineSender::set_voice_value_immediate(const string& port_path,
+ uint32_t voice,
+ const Raul::Atom& value)
+{
+}
+
+
+void
+HTTPEngineSender::set_program(const string& node_path,
+ uint32_t bank,
+ uint32_t program)
+{
+}
+
+
+void
+HTTPEngineSender::midi_learn(const string& node_path)
+{
+}
+
+
+void
+HTTPEngineSender::set_variable(const string& obj_path,
+ const string& predicate,
+ const Raul::Atom& value)
+{
+}
+
+
+void
+HTTPEngineSender::set_property(const string& obj_path,
+ const string& predicate,
+ const Raul::Atom& value)
+{
+}
+
+
+
+// Requests //
+
+void
+HTTPEngineSender::ping()
+{
+}
+
+
+void
+HTTPEngineSender::request_plugin(const string& uri)
+{
+}
+
+
+void
+HTTPEngineSender::request_object(const string& path)
+{
+}
+
+
+void
+HTTPEngineSender::request_port_value(const string& port_path)
+{
+}
+
+
+void
+HTTPEngineSender::request_variable(const string& object_path, const string& key)
+{
+}
+
+
+void
+HTTPEngineSender::request_property(const string& object_path, const string& key)
+{
+}
+
+
+void
+HTTPEngineSender::request_plugins()
+{
+}
+
+
+void
+HTTPEngineSender::request_all_objects()
+{
+}
+
+
+
+} // namespace Client
+} // namespace Ingen
+
+
diff --git a/src/libs/client/HTTPEngineSender.hpp b/src/libs/client/HTTPEngineSender.hpp
new file mode 100644
index 00000000..f753eea3
--- /dev/null
+++ b/src/libs/client/HTTPEngineSender.hpp
@@ -0,0 +1,162 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2008 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 HTTPENGINESENDER_H
+#define HTTPENGINESENDER_H
+
+#include <inttypes.h>
+#include <string>
+#include <libsoup/soup.h>
+#include "interface/EngineInterface.hpp"
+using std::string;
+using Ingen::Shared::EngineInterface;
+using Ingen::Shared::ClientInterface;
+
+namespace Ingen {
+namespace Client {
+
+
+/* HTTP (via libsoup) interface to the engine.
+ *
+ * Clients can use this opaquely as an EngineInterface to control the engine
+ * over HTTP (whether over a network or not).
+ *
+ * \ingroup IngenClient
+ */
+class HTTPEngineSender : public EngineInterface {
+public:
+ HTTPEngineSender(const string& engine_url);
+ ~HTTPEngineSender();
+
+ string uri() const { return _engine_url; }
+
+ inline int32_t next_id()
+ { int32_t ret = (_id == -1) ? -1 : _id++; return ret; }
+
+ void set_next_response_id(int32_t id) { _id = id; }
+ void disable_responses() { _id = -1; }
+
+ void attach(int32_t ping_id, bool block);
+
+
+ /* *** EngineInterface implementation below here *** */
+
+ void enable() { _enabled = true; }
+ void disable() { _enabled = false; }
+
+ void bundle_begin() { transfer_begin(); }
+ void bundle_end() { transfer_end(); }
+
+ void transfer_begin();
+ void transfer_end();
+
+ // Client registration
+ void register_client(ClientInterface* client);
+ void unregister_client(const string& uri);
+
+ // Engine commands
+ void load_plugins();
+ void activate();
+ void deactivate();
+ void quit();
+
+ // Object commands
+
+ void new_patch(const string& path,
+ uint32_t poly);
+
+ void new_port(const string& path,
+ uint32_t index,
+ const string& data_type,
+ bool is_output);
+
+ void new_node(const string& path,
+ const string& plugin_uri);
+
+ void new_node_deprecated(const string& path,
+ const string& plugin_type,
+ const string& library_name,
+ const string& plugin_label);
+
+ void rename(const string& old_path,
+ const string& new_name);
+
+ void destroy(const string& path);
+
+ void clear_patch(const string& patch_path);
+
+ void connect(const string& src_port_path,
+ const string& dst_port_path);
+
+ void disconnect(const string& src_port_path,
+ const string& dst_port_path);
+
+ void disconnect_all(const string& parent_patch_path,
+ const string& node_path);
+
+ void set_port_value(const string& port_path,
+ const Raul::Atom& value);
+
+ void set_voice_value(const string& port_path,
+ uint32_t voice,
+ const Raul::Atom& value);
+
+ void set_port_value_immediate(const string& port_path,
+ const Raul::Atom& value);
+
+ void set_voice_value_immediate(const string& port_path,
+ uint32_t voice,
+ const Raul::Atom& value);
+
+ void set_program(const string& node_path,
+ uint32_t bank,
+ uint32_t program);
+
+ void midi_learn(const string& node_path);
+
+ void set_variable(const string& obj_path,
+ const string& predicate,
+ const Raul::Atom& value);
+
+ void set_property(const string& obj_path,
+ const string& predicate,
+ const Raul::Atom& value);
+
+ // Requests //
+ void ping();
+ void request_plugin(const string& uri);
+ void request_object(const string& path);
+ void request_port_value(const string& port_path);
+ void request_variable(const string& path, const string& key);
+ void request_property(const string& path, const string& key);
+ void request_plugins();
+ void request_all_objects();
+
+protected:
+ SoupSession* _session;
+ const string _engine_url;
+ int _client_port;
+ int32_t _id;
+ bool _enabled;
+};
+
+
+} // namespace Client
+} // namespace Ingen
+
+#endif // HTTPENGINESENDER_H
+
diff --git a/src/libs/client/Makefile.am b/src/libs/client/Makefile.am
index 88e2b393..76835de6 100644
--- a/src/libs/client/Makefile.am
+++ b/src/libs/client/Makefile.am
@@ -15,7 +15,8 @@ libingen_client_la_CXXFLAGS = \
@LXML2_CFLAGS@ \
@RAUL_CFLAGS@ \
@REDLANDMM_CFLAGS@ \
- @SLV2_CFLAGS@
+ @SLV2_CFLAGS@ \
+ @SOUP_CFLAGS@
libingen_client_la_LIBADD = \
../shared/libingen_shared.la \
@@ -25,14 +26,21 @@ libingen_client_la_LIBADD = \
@LXML2_LIBS@ \
@RAUL_LIBS@ \
@REDLANDMM_LIBS@ \
- @SLV2_LIBS@
+ @SLV2_LIBS@ \
+ @SOUP_LIBS@
libingen_client_la_SOURCES = \
$(top_srcdir)/ingen/src/common/interface/ClientInterface.hpp \
$(top_srcdir)/ingen/src/common/interface/EngineInterface.hpp \
+ ClientStore.cpp \
+ ClientStore.hpp \
ConnectionModel.hpp \
DeprecatedLoader.cpp \
DeprecatedLoader.hpp \
+ HTTPClientReceiver.cpp \
+ HTTPClientReceiver.hpp \
+ HTTPEngineSender.cpp \
+ HTTPEngineSender.hpp \
NodeModel.cpp \
NodeModel.hpp \
OSCClientReceiver.cpp \
@@ -45,13 +53,11 @@ libingen_client_la_SOURCES = \
PatchModel.hpp \
PluginModel.cpp \
PluginModel.hpp \
- PluginUI.hpp \
PluginUI.cpp \
+ PluginUI.hpp \
PortModel.cpp \
PortModel.hpp \
SigClientInterface.hpp \
- ClientStore.cpp \
- ClientStore.hpp \
ThreadedSigClientInterface.cpp \
ThreadedSigClientInterface.hpp \
client.cpp \
diff --git a/src/libs/client/NodeModel.cpp b/src/libs/client/NodeModel.cpp
index 02a0a678..ac0c8e68 100644
--- a/src/libs/client/NodeModel.cpp
+++ b/src/libs/client/NodeModel.cpp
@@ -69,7 +69,7 @@ void
NodeModel::remove_port(SharedPtr<PortModel> port)
{
// FIXME: slow
- for (PortModelList::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
if ((*i) == port) {
_ports.erase(i);
break;
@@ -83,7 +83,7 @@ void
NodeModel::remove_port(const Path& port_path)
{
// FIXME: slow
- for (PortModelList::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
if ((*i)->path() == port_path) {
_ports.erase(i);
break;
@@ -141,7 +141,7 @@ NodeModel::add_port(SharedPtr<PortModel> pm)
assert(pm->path().is_child_of(_path));
assert(pm->parent().get() == this);
- PortModelList::iterator existing = find(_ports.begin(), _ports.end(), pm);
+ Ports::iterator existing = find(_ports.begin(), _ports.end(), pm);
// Store should have handled this by merging the two
assert(existing == _ports.end());
@@ -155,7 +155,7 @@ SharedPtr<PortModel>
NodeModel::get_port(const string& port_name) const
{
assert(port_name.find("/") == string::npos);
- for (PortModelList::const_iterator i = _ports.begin(); i != _ports.end(); ++i)
+ for (Ports::const_iterator i = _ports.begin(); i != _ports.end(); ++i)
if ((*i)->path().name() == port_name)
return (*i);
return SharedPtr<PortModel>();
@@ -211,8 +211,10 @@ void
NodeModel::set(SharedPtr<ObjectModel> model)
{
SharedPtr<NodeModel> node = PtrCast<NodeModel>(model);
- if (node)
+ if (node) {
+ _plugin_uri = node->_plugin_uri;
_plugin = node->_plugin;
+ }
ObjectModel::set(model);
}
diff --git a/src/libs/client/NodeModel.hpp b/src/libs/client/NodeModel.hpp
index a4bcf4d8..03afc17c 100644
--- a/src/libs/client/NodeModel.hpp
+++ b/src/libs/client/NodeModel.hpp
@@ -50,6 +50,8 @@ class NodeModel : public ObjectModel, virtual public Ingen::Shared::Node
public:
NodeModel(const NodeModel& copy);
virtual ~NodeModel();
+
+ typedef vector<SharedPtr<PortModel> > Ports;
SharedPtr<PortModel> get_port(const string& port_name) const;
@@ -58,7 +60,7 @@ public:
const string& plugin_uri() const { return _plugin_uri; }
const Shared::Plugin* plugin() const { return _plugin.get(); }
uint32_t num_ports() const { return _ports.size(); }
- const PortModelList& ports() const { return _ports; }
+ const Ports& ports() const { return _ports; }
void port_value_range(SharedPtr<PortModel> port, float& min, float& max);
@@ -84,7 +86,7 @@ protected:
virtual void clear();
- PortModelList _ports; ///< List of ports (not a Table to preserve order)
+ Ports _ports; ///< Vector of ports (not a Table to preserve order)
string _plugin_uri; ///< Plugin URI (if PluginModel is unknown)
SharedPtr<PluginModel> _plugin; ///< The plugin this node is an instance of
uint32_t _num_values; ///< Size of _min_values and _max_values
@@ -93,9 +95,6 @@ protected:
};
-typedef Table<string, SharedPtr<NodeModel> > NodeModelMap;
-
-
} // namespace Client
} // namespace Ingen
diff --git a/src/libs/client/OSCClientReceiver.hpp b/src/libs/client/OSCClientReceiver.hpp
index f1d71dbb..ea5871b3 100644
--- a/src/libs/client/OSCClientReceiver.hpp
+++ b/src/libs/client/OSCClientReceiver.hpp
@@ -25,18 +25,13 @@
#include "raul/Deletable.hpp"
namespace Ingen {
-
-/** Client library */
namespace Client {
-//class NodeModel;
-
-/* Some boilerplate killing macros... */
+/** Arguments to a liblo handler */
#define LO_HANDLER_ARGS const char* path, const char* types, lo_arg** argv, int argc, lo_message msg
-/* Defines a static handler to be passed to lo_add_method, which is a trivial
- * wrapper around a non-static method that does the real work. Makes a whoole
- * lot of ugly boiler plate go away */
+/** Define a static handler to be passed to lo_add_method, which is a trivial
+ * wrapper around a non-static method that does the real work. */
#define LO_HANDLER(name) \
int _##name##_cb (LO_HANDLER_ARGS);\
inline static int name##_cb(LO_HANDLER_ARGS, void* osc_listener)\
@@ -62,6 +57,8 @@ public:
OSCClientReceiver(int listen_port, SharedPtr<Shared::ClientInterface> target);
~OSCClientReceiver();
+ std::string uri() const { return lo_server_thread_get_url(_st); }
+
void start(bool dump_osc);
void stop();
@@ -105,7 +102,6 @@ private:
} // namespace Client
-
} // namespace Ingen
#endif // OSCCLIENTRECEIVER_H
diff --git a/src/libs/client/OSCEngineSender.hpp b/src/libs/client/OSCEngineSender.hpp
index dbb7e8f5..4c92afdb 100644
--- a/src/libs/client/OSCEngineSender.hpp
+++ b/src/libs/client/OSCEngineSender.hpp
@@ -44,7 +44,7 @@ public:
~OSCEngineSender();
- string engine_url() { return _engine_url; }
+ std::string uri() const { return _engine_url; }
inline int32_t next_id()
{ int32_t ret = (_id == -1) ? -1 : _id++; return ret; }
@@ -148,9 +148,9 @@ public:
void request_all_objects();
protected:
- string _engine_url;
- int _client_port;
- int32_t _id;
+ const string _engine_url;
+ int _client_port;
+ int32_t _id;
};
diff --git a/src/libs/client/ObjectModel.cpp b/src/libs/client/ObjectModel.cpp
index e9a491a6..ede5f822 100644
--- a/src/libs/client/ObjectModel.cpp
+++ b/src/libs/client/ObjectModel.cpp
@@ -119,21 +119,26 @@ ObjectModel::polyphonic() const
* @a model as correct. The paths of the two models MUST be equal.
*/
void
-ObjectModel::set(SharedPtr<ObjectModel> model)
+ObjectModel::set(SharedPtr<ObjectModel> o)
{
- assert(_path == model->path());
-
- for (Variables::const_iterator other = model->variables().begin();
- other != model->variables().end(); ++other) {
-
- Variables::const_iterator mine = _variables.find(other->first);
-
- if (mine != _variables.end()) {
- cerr << "WARNING: " << _path << "Client/Server data mismatch: " << other->first << endl;
- }
-
- _variables[other->first] = other->second;
- signal_variable.emit(other->first, other->second);
+ assert(_path == o->path());
+ if (o->_parent)
+ _parent = o->_parent;
+
+ for (Variables::const_iterator v = o->variables().begin(); v != o->variables().end(); ++v) {
+ Variables::const_iterator mine = _variables.find(v->first);
+ if (mine != _variables.end())
+ cerr << "WARNING: " << _path << "Client/Server variable mismatch: " << v->first << endl;
+ _variables[v->first] = v->second;
+ signal_variable.emit(v->first, v->second);
+ }
+
+ for (Properties::const_iterator v = o->properties().begin(); v != o->properties().end(); ++v) {
+ Properties::const_iterator mine = _properties.find(v->first);
+ if (mine != _properties.end())
+ cerr << "WARNING: " << _path << "Client/Server property mismatch: " << v->first << endl;
+ _properties[v->first] = v->second;
+ signal_variable.emit(v->first, v->second);
}
}
diff --git a/src/libs/client/PortModel.cpp b/src/libs/client/PortModel.cpp
index fa3cb345..c18378db 100644
--- a/src/libs/client/PortModel.cpp
+++ b/src/libs/client/PortModel.cpp
@@ -51,7 +51,11 @@ PortModel::set(SharedPtr<ObjectModel> model)
{
SharedPtr<PortModel> port = PtrCast<PortModel>(model);
if (port) {
+ _index = port->_index;
+ _type = port->_type;
+ _direction = port->_direction;
_current_val = port->_current_val;
+ _connections = port->_connections;
signal_value_changed.emit(_current_val);
}
diff --git a/src/libs/client/PortModel.hpp b/src/libs/client/PortModel.hpp
index a86c9188..a7f52679 100644
--- a/src/libs/client/PortModel.hpp
+++ b/src/libs/client/PortModel.hpp
@@ -105,8 +105,6 @@ private:
size_t _connections;
};
-typedef vector<SharedPtr<PortModel> > PortModelList;
-
} // namespace Client
} // namespace Ingen
diff --git a/src/libs/client/SigClientInterface.hpp b/src/libs/client/SigClientInterface.hpp
index 32a0a43b..7ab32c12 100644
--- a/src/libs/client/SigClientInterface.hpp
+++ b/src/libs/client/SigClientInterface.hpp
@@ -41,6 +41,8 @@ class SigClientInterface : public Ingen::Shared::ClientInterface, public sigc::t
{
public:
SigClientInterface() : _enabled(true) {}
+
+ bool enabled() const { return _enabled; }
std::string uri() const { return "(internal)"; }
diff --git a/src/libs/client/ThreadedSigClientInterface.cpp b/src/libs/client/ThreadedSigClientInterface.cpp
index 3b7af80c..ef95133b 100644
--- a/src/libs/client/ThreadedSigClientInterface.cpp
+++ b/src/libs/client/ThreadedSigClientInterface.cpp
@@ -17,7 +17,8 @@
#include "ThreadedSigClientInterface.hpp"
#include <iostream>
-using std::cerr; using std::endl;
+
+using namespace std;
namespace Ingen {
namespace Client {
@@ -28,23 +29,19 @@ namespace Client {
void
ThreadedSigClientInterface::push_sig(Closure ev)
{
+ _attached = true;
if (!_enabled)
return;
bool success = false;
- bool first = true;
-
- // (Very) slow busy-wait if the queue is full
- // FIXME: Make this wait on a signal from process_sigs iff this happens
while (!success) {
- //printf("push %zu\n", _sigs.fill());
success = _sigs.push(ev);
if (!success) {
- if (first) {
- cerr << "[ThreadedSigClientInterface] WARNING: (Client) event queue full. Waiting to try again..." << endl;
- first = false;
- }
- usleep(200000); // 100 milliseconds (2* rate process_sigs is called)
+ cerr << "WARNING: Client event queue full. Waiting..." << endl;
+ _mutex.lock();
+ _cond.wait(_mutex);
+ _mutex.unlock();
+ cerr << "Queue drained, continuing" << endl;
}
}
}
@@ -58,18 +55,21 @@ ThreadedSigClientInterface::push_sig(Closure ev)
bool
ThreadedSigClientInterface::emit_signals()
{
- // Process a maximum of queue-size events, to prevent locking the GTK
+ // Process a limited number of events, to prevent locking the GTK
// thread indefinitely while processing continually arriving events
- const size_t limit = _sigs.capacity();
+
size_t num_processed = 0;
- while (!_sigs.empty() && num_processed++ < limit) {
- //printf("emit %zu\n", _sigs.fill());
+ while (!_sigs.empty() && num_processed++ < (_sigs.capacity() * 3 / 4)) {
Closure& ev = _sigs.front();
- _sigs.pop();
ev();
ev.disconnect();
+ _sigs.pop();
}
+ _mutex.lock();
+ _cond.broadcast();
+ _mutex.unlock();
+
return true;
}
diff --git a/src/libs/client/ThreadedSigClientInterface.hpp b/src/libs/client/ThreadedSigClientInterface.hpp
index b3a1b72c..3014c139 100644
--- a/src/libs/client/ThreadedSigClientInterface.hpp
+++ b/src/libs/client/ThreadedSigClientInterface.hpp
@@ -21,10 +21,12 @@
#include <inttypes.h>
#include <string>
#include <sigc++/sigc++.h>
+#include <glibmm/thread.h>
#include "interface/ClientInterface.hpp"
#include "SigClientInterface.hpp"
-#include <raul/SRSWQueue.hpp>
#include <raul/Atom.hpp>
+#include <raul/SRSWQueue.hpp>
+
using std::string;
/** Returns nothing and takes no parameters (because they have all been bound) */
@@ -65,12 +67,15 @@ public:
, port_activity_slot(signal_port_activity.make_slot())
, program_add_slot(signal_program_add.make_slot())
, program_remove_slot(signal_program_remove.make_slot())
- {}
+ {
+ }
virtual std::string uri() const { return "(internal)"; }
virtual void subscribe(Shared::EngineInterface* engine) { throw; }
+ bool enabled() const { return _attached; }
+
void bundle_begin()
{ push_sig(bundle_begin_slot); }
@@ -143,7 +148,11 @@ public:
private:
void push_sig(Closure ev);
+ Glib::Mutex _mutex;
+ Glib::Cond _cond;
+
Raul::SRSWQueue<Closure> _sigs;
+ bool _attached;
sigc::slot<void> bundle_begin_slot;
sigc::slot<void> bundle_end_slot;
diff --git a/src/libs/client/client.cpp b/src/libs/client/client.cpp
index 8b86e958..32380378 100644
--- a/src/libs/client/client.cpp
+++ b/src/libs/client/client.cpp
@@ -15,21 +15,37 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <iostream>
#include "client.hpp"
#include "OSCEngineSender.hpp"
+#include "HTTPEngineSender.hpp"
+
+using namespace std;
namespace Ingen {
namespace Client {
SharedPtr<Ingen::Shared::EngineInterface>
-new_osc_interface(const std::string& url)
+new_remote_interface(const std::string& url)
{
- OSCEngineSender* oes = new OSCEngineSender(url);
- oes->attach(rand(), true);
- return SharedPtr<Shared::EngineInterface>(oes);
+ const string scheme = url.substr(0, url.find(":"));
+ cout << "SCHEME: " << scheme << endl;
+ if (scheme == "osc.udp" || scheme == "osc.tcp") {
+ OSCEngineSender* oes = new OSCEngineSender(url);
+ oes->attach(rand(), true);
+ return SharedPtr<Shared::EngineInterface>(oes);
+ } else if (scheme == "http") {
+ HTTPEngineSender* hes = new HTTPEngineSender(url);
+ hes->attach(rand(), true);
+ return SharedPtr<Shared::EngineInterface>(hes);
+ } else {
+ cerr << "WARNING: Unknown URI scheme '" << scheme << "'" << endl;
+ return SharedPtr<Shared::EngineInterface>();
+ }
}
+
} // namespace Client
} // namespace Ingen
diff --git a/src/libs/client/client.hpp b/src/libs/client/client.hpp
index 931e4c45..82166da5 100644
--- a/src/libs/client/client.hpp
+++ b/src/libs/client/client.hpp
@@ -30,7 +30,7 @@ namespace Client {
extern "C" {
- SharedPtr<Shared::EngineInterface> new_osc_interface(const std::string& url);
+ SharedPtr<Shared::EngineInterface> new_remote_interface(const std::string& url);
SharedPtr<Shared::EngineInterface> new_queued_interface(SharedPtr<Ingen::Engine> engine);
}
diff --git a/src/libs/engine/OSCClientSender.hpp b/src/libs/engine/OSCClientSender.hpp
index d62dd1d3..c8c8418f 100644
--- a/src/libs/engine/OSCClientSender.hpp
+++ b/src/libs/engine/OSCClientSender.hpp
@@ -48,6 +48,8 @@ public:
virtual ~OSCClientSender()
{ lo_address_free(_address); }
+ bool enabled() const { return _enabled; }
+
void enable() { _enabled = true; }
void disable() { _enabled = false; }
diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp
index a63c826b..f71bdb83 100644
--- a/src/libs/engine/OSCEngineReceiver.cpp
+++ b/src/libs/engine/OSCEngineReceiver.cpp
@@ -70,7 +70,7 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t
}
// For debugging, print all incoming OSC messages
- lo_server_add_method(_server, NULL, NULL, generic_cb, NULL);
+ //lo_server_add_method(_server, NULL, NULL, generic_cb, NULL);
// Set response address for this message.
// It's important this is first and returns nonzero.
diff --git a/src/libs/engine/QueuedEngineInterface.hpp b/src/libs/engine/QueuedEngineInterface.hpp
index 17f8c75a..3aba9c7e 100644
--- a/src/libs/engine/QueuedEngineInterface.hpp
+++ b/src/libs/engine/QueuedEngineInterface.hpp
@@ -62,12 +62,13 @@ public:
QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size);
virtual ~QueuedEngineInterface() {}
+ std::string uri() const { return "ingen:internal"; }
+
void set_next_response_id(int32_t id);
// Client registration
virtual void register_client(ClientInterface* client);
virtual void unregister_client(const string& uri);
-
// Engine commands
virtual void load_plugins();
diff --git a/src/libs/gui/ConnectWindow.cpp b/src/libs/gui/ConnectWindow.cpp
index 03f8408a..eb095af5 100644
--- a/src/libs/gui/ConnectWindow.cpp
+++ b/src/libs/gui/ConnectWindow.cpp
@@ -29,6 +29,7 @@
#include "engine/Engine.hpp"
#include "engine/QueuedEngineInterface.hpp"
#include "client/OSCClientReceiver.hpp"
+#include "client/HTTPClientReceiver.hpp"
#include "client/OSCEngineSender.hpp"
#include "client/ThreadedSigClientInterface.hpp"
#include "client/ClientStore.hpp"
@@ -143,7 +144,9 @@ ConnectWindow::set_connecting_widget_states()
void
ConnectWindow::connect(bool existing)
{
- assert(!_attached);
+ if (_attached)
+ _attached = false;
+
assert(!App::instance().client());
_connect_stage = 0;
@@ -153,15 +156,22 @@ ConnectWindow::connect(bool existing)
if (_mode == CONNECT_REMOTE) {
if (!existing) {
- const string url = (_widgets_loaded ? _url_entry->get_text() : "osc.udp://localhost:16180");
+ const string url = (_widgets_loaded ? (string)_url_entry->get_text() : world->engine->uri());
world->engine = SharedPtr<EngineInterface>(new OSCEngineSender(url));
}
-
- // FIXME: static args
+
SharedPtr<ThreadedSigClientInterface> tsci(new ThreadedSigClientInterface(1024));
- SharedPtr<OSCClientReceiver> client(new OSCClientReceiver(16181, tsci));
- App::instance().attach(tsci, client);
+ SharedPtr<Raul::Deletable> client;
+
+ const string& uri = world->engine->uri();
+ const string& scheme = uri.substr(0, uri.find(":"));
+ if (scheme == "osc.udp" || scheme == "osc.tcp")
+ client = SharedPtr<OSCClientReceiver>(new OSCClientReceiver(16181, tsci)); // FIXME: port
+ else if (scheme == "http")
+ client = SharedPtr<HTTPClientReceiver>(new HTTPClientReceiver(world, uri, tsci));
+ App::instance().attach(tsci, client);
+
Glib::signal_timeout().connect(
sigc::mem_fun(App::instance(), &App::gtk_main_iteration), 40, G_PRIORITY_DEFAULT);
@@ -377,7 +387,7 @@ ConnectWindow::gtk_callback()
assert(App::instance().client());
App::instance().client()->signal_response_ok.connect(
- sigc::mem_fun(this, &ConnectWindow::response_ok_received));
+ sigc::mem_fun(this, &ConnectWindow::on_response));
_ping_id = abs(rand()) / 2 * 2; // avoid -1
App::instance().engine()->set_next_response_id(_ping_id);
@@ -391,7 +401,7 @@ ConnectWindow::gtk_callback()
++_connect_stage;
} else if (_connect_stage == 1) {
- if (_attached) {
+ if (_attached || App::instance().client()->enabled()) {
App::instance().engine()->activate();
++_connect_stage;
} else {
diff --git a/src/libs/gui/ConnectWindow.hpp b/src/libs/gui/ConnectWindow.hpp
index 8410783d..fb75d4b2 100644
--- a/src/libs/gui/ConnectWindow.hpp
+++ b/src/libs/gui/ConnectWindow.hpp
@@ -53,7 +53,7 @@ public:
void set_connected_to(SharedPtr<Shared::EngineInterface> engine);
void start(Ingen::Shared::World* world);
- void response_ok_received(int32_t id) { if (id == _ping_id) _attached = true; }
+ void on_response(int32_t id) { _attached = true; }
private:
enum Mode { CONNECT_REMOTE, LAUNCH_REMOTE, INTERNAL };
diff --git a/src/libs/gui/ControlPanel.cpp b/src/libs/gui/ControlPanel.cpp
index 84f1163a..032f5758 100644
--- a/src/libs/gui/ControlPanel.cpp
+++ b/src/libs/gui/ControlPanel.cpp
@@ -69,7 +69,7 @@ ControlPanel::init(SharedPtr<NodeModel> node, uint32_t poly)
_voice_control_box->hide();
}
- for (PortModelList::const_iterator i = node->ports().begin(); i != node->ports().end(); ++i) {
+ for (NodeModel::Ports::const_iterator i = node->ports().begin(); i != node->ports().end(); ++i) {
add_port(*i);
}
diff --git a/src/libs/gui/Makefile.am b/src/libs/gui/Makefile.am
index fa956fca..48063d35 100644
--- a/src/libs/gui/Makefile.am
+++ b/src/libs/gui/Makefile.am
@@ -23,7 +23,8 @@ libingen_gui_la_CXXFLAGS = \
@LIBLO_CFLAGS@ \
@REDLANDMM_CFLAGS@ \
@RAUL_CFLAGS@ \
- @SLV2_CFLAGS@
+ @SLV2_CFLAGS@ \
+ @SOUP_CFLAGS@
libingen_gui_la_LDFLAGS = -no-undefined -module -avoid-version
@@ -40,7 +41,8 @@ libingen_gui_la_LIBADD = \
@LIBLO_LIBS@ \
@REDLANDMM_LIBS@ \
@RAUL_LIBS@ \
- @SLV2_LIBS@
+ @SLV2_LIBS@ \
+ @SOUP_LIBS@
libingen_gui_la_SOURCES = \
gui.hpp \
diff --git a/src/libs/gui/NodeControlWindow.cpp b/src/libs/gui/NodeControlWindow.cpp
index 95a07b2b..293d28f5 100644
--- a/src/libs/gui/NodeControlWindow.cpp
+++ b/src/libs/gui/NodeControlWindow.cpp
@@ -114,7 +114,7 @@ NodeControlWindow::resize()
void
NodeControlWindow::on_show()
{
- for (PortModelList::const_iterator i = _node->ports().begin();
+ for (NodeModel::Ports::const_iterator i = _node->ports().begin();
i != _node->ports().end(); ++i)
if ((*i)->type().is_control() && (*i)->is_input())
App::instance().engine()->request_port_value((*i)->path());
diff --git a/src/libs/gui/NodeMenu.cpp b/src/libs/gui/NodeMenu.cpp
index 05139540..529eb52c 100644
--- a/src/libs/gui/NodeMenu.cpp
+++ b/src/libs/gui/NodeMenu.cpp
@@ -141,7 +141,7 @@ bool
NodeMenu::has_control_inputs()
{
const NodeModel* const nm = (NodeModel*)_object.get();
- for (PortModelList::const_iterator i = nm->ports().begin(); i != nm->ports().end(); ++i)
+ for (NodeModel::Ports::const_iterator i = nm->ports().begin(); i != nm->ports().end(); ++i)
if ((*i)->is_input() && (*i)->type().is_control())
return true;
diff --git a/src/libs/gui/NodeModule.cpp b/src/libs/gui/NodeModule.cpp
index 21415be9..b3898b94 100644
--- a/src/libs/gui/NodeModule.cpp
+++ b/src/libs/gui/NodeModule.cpp
@@ -90,7 +90,7 @@ NodeModule::create(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeModel> n
for (GraphObject::Variables::const_iterator m = node->variables().begin(); m != node->variables().end(); ++m)
ret->set_variable(m->first, m->second);
- for (PortModelList::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) {
+ for (NodeModel::Ports::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) {
ret->add_port(*p, false);
}
@@ -151,7 +151,7 @@ NodeModule::embed_gui(bool embed)
if (_gui_widget) {
_gui_widget->show_all();
- for (PortModelList::const_iterator p = _node->ports().begin();
+ for (NodeModel::Ports::const_iterator p = _node->ports().begin();
p != _node->ports().end(); ++p)
if ((*p)->type().is_control() && (*p)->is_output())
App::instance().engine()->set_property((*p)->path(), "ingen:broadcast", true);
@@ -162,7 +162,7 @@ NodeModule::embed_gui(bool embed)
FlowCanvas::Module::embed(NULL);
_plugin_ui.reset();
- for (PortModelList::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p)
+ for (NodeModel::Ports::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p)
if ((*p)->type().is_control() && (*p)->is_output())
App::instance().engine()->set_property((*p)->path(), "ingen:broadcast", false);
}
@@ -262,7 +262,7 @@ void
NodeModule::initialise_gui_values()
{
uint32_t index=0;
- for (PortModelList::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p) {
+ for (NodeModel::Ports::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p) {
if ((*p)->type().is_control())
value_changed(index, (*p)->value());
++index;
diff --git a/src/libs/gui/NodePropertiesWindow.cpp b/src/libs/gui/NodePropertiesWindow.cpp
index 9848d872..ae2c23b5 100644
--- a/src/libs/gui/NodePropertiesWindow.cpp
+++ b/src/libs/gui/NodePropertiesWindow.cpp
@@ -53,8 +53,6 @@ NodePropertiesWindow::set_node(SharedPtr<NodeModel> node_model)
_node_polyphonic_toggle->set_active(node_model->polyphonic());
const PluginModel* pm = dynamic_cast<const PluginModel*>(node_model->plugin());
- assert(pm);
-
if (pm) {
_plugin_type_label->set_text(pm->type_uri());
_plugin_uri_label->set_text(pm->uri());
diff --git a/src/libs/gui/PatchCanvas.cpp b/src/libs/gui/PatchCanvas.cpp
index f527041b..5d064124 100644
--- a/src/libs/gui/PatchCanvas.cpp
+++ b/src/libs/gui/PatchCanvas.cpp
@@ -269,7 +269,7 @@ PatchCanvas::build()
}
// Create pseudo modules for ports (ports on this canvas, not on our module)
- for (PortModelList::const_iterator i = _patch->ports().begin();
+ for (NodeModel::Ports::const_iterator i = _patch->ports().begin();
i != _patch->ports().end(); ++i) {
add_port(*i);
}
@@ -590,8 +590,7 @@ PatchCanvas::paste()
clipboard.new_patch("/", _patch->poly());
ClashAvoider avoider(*App::instance().store().get(), _patch->path(), clipboard, &clipboard);
- parser->parse_string(App::instance().world(), &avoider, str, "/",
- boost::optional<Glib::ustring>(), (Glib::ustring)_patch->path());
+ parser->parse_string(App::instance().world(), &avoider, str, "/", _patch->path());
for (Store::iterator i = clipboard.begin(); i != clipboard.end(); ++i) {
cout << "************ OBJECT: " << i->first << endl;
diff --git a/src/libs/gui/PatchTreeWindow.cpp b/src/libs/gui/PatchTreeWindow.cpp
index ee831cb3..87393cec 100644
--- a/src/libs/gui/PatchTreeWindow.cpp
+++ b/src/libs/gui/PatchTreeWindow.cpp
@@ -89,7 +89,7 @@ PatchTreeWindow::add_patch(SharedPtr<PatchModel> pm)
Gtk::TreeModel::Row row = *iter;
if (pm->path() == "/") {
SharedPtr<OSCEngineSender> osc_sender = PtrCast<OSCEngineSender>(App::instance().engine());
- string root_name = osc_sender ? osc_sender->engine_url() : "Internal";
+ string root_name = osc_sender ? osc_sender->uri() : "Internal";
// Hack off trailing '/' if it's there (ugly)
//if (root_name.substr(root_name.length()-1,1) == "/")
// root_name = root_name.substr(0, root_name.length()-1);
diff --git a/src/libs/gui/PatchWindow.cpp b/src/libs/gui/PatchWindow.cpp
index 125adeea..01f74436 100644
--- a/src/libs/gui/PatchWindow.cpp
+++ b/src/libs/gui/PatchWindow.cpp
@@ -210,7 +210,7 @@ PatchWindow::set_patch(SharedPtr<PatchModel> patch, SharedPtr<PatchView> view)
_menu_view_control_window->property_sensitive() = false;
- for (PortModelList::const_iterator p = patch->ports().begin();
+ for (NodeModel::Ports::const_iterator p = patch->ports().begin();
p != patch->ports().end(); ++p) {
if ((*p)->type().is_control() && (*p)->is_input()) {
_menu_view_control_window->property_sensitive() = true;
@@ -257,7 +257,7 @@ PatchWindow::patch_port_removed(SharedPtr<PortModel> port)
bool found_control = false;
- for (PortModelList::const_iterator i = _patch->ports().begin(); i != _patch->ports().end(); ++i) {
+ for (NodeModel::Ports::const_iterator i = _patch->ports().begin(); i != _patch->ports().end(); ++i) {
if ((*i)->type().is_control() && (*i)->is_input()) {
found_control = true;
break;
diff --git a/src/libs/serialisation/Parser.cpp b/src/libs/serialisation/Parser.cpp
index cc8b4e4b..79c69648 100644
--- a/src/libs/serialisation/Parser.cpp
+++ b/src/libs/serialisation/Parser.cpp
@@ -63,7 +63,7 @@ Parser::parse_document(
Ingen::Shared::CommonInterface* target,
const Glib::ustring& document_uri,
Glib::ustring object_uri,
- boost::optional<Glib::ustring> engine_base,
+ Glib::ustring engine_base,
boost::optional<Raul::Symbol> symbol,
boost::optional<GraphObject::Variables> data)
{
@@ -74,7 +74,7 @@ Parser::parse_document(
else
cout << "Parsing " << object_uri << " from " << document_uri << endl;
- return parse(world, target, model, document_uri, object_uri, engine_base, symbol, data);;
+ return parse(world, target, model, document_uri, engine_base, object_uri, symbol, data);;
}
@@ -84,8 +84,8 @@ Parser::parse_string(
Ingen::Shared::CommonInterface* target,
const Glib::ustring& str,
const Glib::ustring& base_uri,
+ Glib::ustring engine_base,
boost::optional<Glib::ustring> object_uri,
- boost::optional<Glib::ustring> engine_base,
boost::optional<Raul::Symbol> symbol,
boost::optional<GraphObject::Variables> data)
{
@@ -96,10 +96,11 @@ Parser::parse_string(
else
cout << "Parsing all objects found in string (base " << base_uri << ")" << endl;
- bool ret = parse(world, target, model, base_uri, object_uri, engine_base, symbol, data);
+ bool ret = parse(world, target, model, base_uri, engine_base, object_uri, symbol, data);
if (ret) {
const Glib::ustring subject = Glib::ustring("<") + base_uri + Glib::ustring(">");
- parse_connections(world, target, model, base_uri, subject, (engine_base ? (string)engine_base.get() : "/"));
+ parse_connections(world, target, model, base_uri, subject,
+ Path((engine_base == "") ? "/" : engine_base));
}
return ret;
@@ -112,13 +113,16 @@ Parser::parse(
Ingen::Shared::CommonInterface* target,
Redland::Model& model,
Glib::ustring base_uri,
+ Glib::ustring engine_base,
boost::optional<Glib::ustring> object_uri,
- boost::optional<Glib::ustring> engine_base,
boost::optional<Raul::Symbol> symbol,
boost::optional<GraphObject::Variables> data)
{
const Redland::Node::Type res = Redland::Node::RESOURCE;
Glib::ustring query_str;
+ if (object_uri && object_uri.get()[0] == '/')
+ object_uri = object_uri.get().substr(1);
+
if (object_uri)
query_str = Glib::ustring("SELECT DISTINCT ?class WHERE { <") + object_uri.get() + "> a ?class . }";
else
@@ -132,8 +136,13 @@ Parser::parse(
const Redland::Node in_port_class(*world->rdf_world, res, NS_INGEN "InputPort");
const Redland::Node out_port_class(*world->rdf_world, res, NS_INGEN "OutputPort");
- const Redland::Node subject_uri(*world->rdf_world, res,
- (object_uri ? object_uri.get() : "http://example.org"));
+ string subject_str = ((object_uri && object_uri.get() != "") ? object_uri.get() : base_uri);
+ if (subject_str[0] == '/')
+ subject_str = subject_str.substr(1);
+ if (subject_str == "")
+ subject_str = base_uri;
+
+ const Redland::Node subject_uri(*world->rdf_world, res, subject_str);
bool ret = false;
@@ -141,7 +150,9 @@ Parser::parse(
const Redland::Node subject = (object_uri ? subject_uri : (*i)["subject"]);
const Redland::Node rdf_class = (*i)["class"];
if (!object_uri) {
- std::string path_str = "/" + uri_relative_to_base(base_uri, subject.to_c_string());
+ std::string path_str = uri_relative_to_base(base_uri, subject.to_c_string());
+ if (path_str[0] != '/')
+ path_str = string("/").append(path_str);
if (Path(path_str).parent() != "/")
continue;
}
@@ -150,12 +161,13 @@ Parser::parse(
rdf_class == in_port_class || rdf_class == out_port_class) {
Raul::Path path("/");
if (base_uri != subject.to_c_string()) {
- string path_str = string("/") + (string)uri_relative_to_base(
- base_uri, subject.to_c_string());
+ string path_str = (string)uri_relative_to_base(base_uri, subject.to_c_string());
+ if (path_str[0] != '/')
+ path_str = string("/").append(path_str);
if (Path::is_valid(path_str)) {
path = path_str;
} else {
- cerr << "[Parser] ERROR: Invalid path " << path << endl;
+ cerr << "[Parser] ERROR: Invalid path '" << path << "'" << endl;
continue;
}
}
@@ -164,8 +176,8 @@ Parser::parse(
continue;
if (rdf_class == patch_class) {
- ret = parse_patch(world, target, model, base_uri, subject.to_c_string(),
- engine_base.get(), data);
+ ret = parse_patch(world, target, model, base_uri, engine_base,
+ subject.to_c_string(), data);
if (ret)
target->set_variable(path, "ingen:document", Atom(base_uri.c_str()));
} else if (rdf_class == node_class) {
@@ -193,8 +205,8 @@ Parser::parse_patch(
Ingen::Shared::CommonInterface* target,
Redland::Model& model,
const Glib::ustring& base_uri,
- const Glib::ustring& object_uri,
Glib::ustring engine_base,
+ const Glib::ustring& object_uri,
boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>())
{
std::set<Path> created;
@@ -222,6 +234,7 @@ Parser::parse_patch(
if (results.size() == 0) {
cerr << "[Parser] ERROR: No polyphony found!" << endl;
+ cerr << "Query was:" << endl << query.string() << endl;
return false;
}
@@ -237,10 +250,12 @@ Parser::parse_patch(
patch_path = "/";
else if (engine_base[engine_base.length()-1] == '/')
patch_path = Path(engine_base + symbol);
- else
+ else if (Path::is_valid(engine_base))
patch_path = (Path)engine_base;
+ else
+ cerr << "WARNING: Illegal engine base path '" << engine_base << "', loading patch to root" << endl;
- if (patch_path != "/")
+ //if (patch_path != "/")
target->new_patch(patch_path, patch_poly);
/* Plugin nodes */
diff --git a/src/libs/serialisation/Parser.hpp b/src/libs/serialisation/Parser.hpp
index 2e088f51..7b8a35eb 100644
--- a/src/libs/serialisation/Parser.hpp
+++ b/src/libs/serialisation/Parser.hpp
@@ -44,8 +44,8 @@ public:
Ingen::Shared::World* world,
Shared::CommonInterface* target,
const Glib::ustring& document_uri,
+ Glib::ustring engine_base,
Glib::ustring object_uri,
- boost::optional<Glib::ustring> engine_base=boost::optional<Glib::ustring>(),
boost::optional<Raul::Symbol> symbol=boost::optional<Raul::Symbol>(),
boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>());
@@ -54,8 +54,8 @@ public:
Shared::CommonInterface* target,
const Glib::ustring& str,
const Glib::ustring& base_uri,
+ Glib::ustring engine_base,
boost::optional<Glib::ustring> object_uri=boost::optional<Glib::ustring>(),
- boost::optional<Glib::ustring> engine_base=boost::optional<Glib::ustring>(),
boost::optional<Raul::Symbol> symbol=boost::optional<Raul::Symbol>(),
boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>());
@@ -68,8 +68,8 @@ private:
Shared::CommonInterface* target,
Redland::Model& model,
Glib::ustring base_uri,
+ Glib::ustring engine_base,
boost::optional<Glib::ustring> object_uri=boost::optional<Glib::ustring>(),
- boost::optional<Glib::ustring> engine_base=boost::optional<Glib::ustring>(),
boost::optional<Raul::Symbol> symbol=boost::optional<Raul::Symbol>(),
boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>());
@@ -78,8 +78,8 @@ private:
Ingen::Shared::CommonInterface* target,
Redland::Model& model,
const Glib::ustring& base_uri,
- const Glib::ustring& object_uri,
Glib::ustring engine_base,
+ const Glib::ustring& object_uri,
boost::optional<GraphObject::Variables> data);
bool parse_node(
diff --git a/src/libs/shared/OSCSender.cpp b/src/libs/shared/OSCSender.cpp
index 340786db..3936cf96 100644
--- a/src/libs/shared/OSCSender.cpp
+++ b/src/libs/shared/OSCSender.cpp
@@ -94,8 +94,8 @@ void
OSCSender::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;
+ // Don't want to exceed max UDP packet size (good default value?)
+ static const size_t MAX_BUNDLE_SIZE = 1024;
if (!_enabled)
return;
diff --git a/src/libs/shared/OSCSender.hpp b/src/libs/shared/OSCSender.hpp
index 16b6dd22..da91caed 100644
--- a/src/libs/shared/OSCSender.hpp
+++ b/src/libs/shared/OSCSender.hpp
@@ -27,7 +27,7 @@ namespace Shared {
class OSCSender {
public:
OSCSender();
- ~OSCSender();
+ virtual ~OSCSender() {}
lo_address address() const { return _address; }
diff --git a/src/progs/ingen/main.cpp b/src/progs/ingen/main.cpp
index d0efb113..c8adf207 100644
--- a/src/progs/ingen/main.cpp
+++ b/src/progs/ingen/main.cpp
@@ -133,14 +133,14 @@ main(int argc, char** argv)
cerr << "Unable to load client module." << endl;
}
- /* If we don't have a local engine interface (for GUI), use OSC */
+ /* If we don't have a local engine interface (for GUI), use network */
if (client_module && ! engine_interface) {
- SharedPtr<Shared::EngineInterface> (*new_osc_interface)(const std::string&) = NULL;
+ SharedPtr<Shared::EngineInterface> (*new_remote_interface)(const std::string&) = NULL;
- if (client_module->get_symbol("new_osc_interface", (void*&)new_osc_interface)) {
- engine_interface = new_osc_interface(args.connect_arg);
+ if (client_module->get_symbol("new_remote_interface", (void*&)new_remote_interface)) {
+ engine_interface = new_remote_interface(args.connect_arg);
} else {
- cerr << "Unable to find symbol 'new_osc_interface' in "
+ cerr << "Unable to find symbol 'new_remote_interface' in "
"ingen_client module, aborting." << endl;
return -1;
}
@@ -157,7 +157,7 @@ main(int argc, char** argv)
/* Load a patch */
if (args.load_given && engine_interface) {
- boost::optional<Glib::ustring> engine_base;
+ Glib::ustring engine_base = "/";
if (args.path_given)
engine_base = string(args.path_arg) + "/";
@@ -185,7 +185,7 @@ main(int argc, char** argv)
engine_interface->load_plugins();
- parser->parse_document(world, engine_interface.get(), uri, uri, engine_base);
+ parser->parse_document(world, engine_interface.get(), uri, engine_base, uri);
} else {
cerr << "Unable to load serialisation module, aborting." << endl;