summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/HTTPClientSender.cpp191
-rw-r--r--src/engine/HTTPClientSender.hpp138
-rw-r--r--src/engine/HTTPEngineReceiver.cpp10
-rw-r--r--src/engine/HTTPEngineReceiver.hpp2
-rw-r--r--src/engine/wscript14
5 files changed, 352 insertions, 3 deletions
diff --git a/src/engine/HTTPClientSender.cpp b/src/engine/HTTPClientSender.cpp
new file mode 100644
index 00000000..ae97e1ca
--- /dev/null
+++ b/src/engine/HTTPClientSender.cpp
@@ -0,0 +1,191 @@
+/* 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 <string>
+#include "raul/Atom.hpp"
+#include "HTTPClientSender.hpp"
+
+using namespace std;
+using namespace Raul;
+
+namespace Ingen {
+
+void
+HTTPClientSender::response_ok(int32_t id)
+{
+ cout << "HTTP OK" << endl;
+}
+
+
+void
+HTTPClientSender::response_error(int32_t id, const std::string& msg)
+{
+ cout << "HTTP ERROR" << endl;
+}
+
+
+void
+HTTPClientSender::error(const std::string& msg)
+{
+ //send("/ingen/error", "s", msg.c_str(), LO_ARGS_END);
+}
+
+
+void HTTPClientSender::new_node(const std::string& node_path,
+ const std::string& plugin_uri)
+{
+ //send("/ingen/new_node", "ss", node_path.c_str(), plugin_uri.c_str(), LO_ARGS_END);
+}
+
+
+void
+HTTPClientSender::new_port(const std::string& path,
+ const std::string& type,
+ uint32_t index,
+ bool is_output)
+{
+ //send("/ingen/new_port", "sisi", path.c_str(), index, type.c_str(), is_output, LO_ARGS_END);
+}
+
+
+void
+HTTPClientSender::destroy(const std::string& path)
+{
+ assert(path != "/");
+
+ //send("/ingen/destroyed", "s", path.c_str(), LO_ARGS_END);
+}
+
+
+void
+HTTPClientSender::patch_cleared(const std::string& patch_path)
+{
+ //send("/ingen/patch_cleared", "s", patch_path.c_str(), LO_ARGS_END);
+}
+
+
+void
+HTTPClientSender::connect(const std::string& src_path, const std::string& dst_path)
+{
+ //send("/ingen/new_connection", "ss", src_path.c_str(), dst_path.c_str(), LO_ARGS_END);
+}
+
+
+void
+HTTPClientSender::disconnect(const std::string& src_path, const std::string& dst_path)
+{
+ //send("/ingen/disconnection", "ss", src_path.c_str(), dst_path.c_str(), LO_ARGS_END);
+}
+
+
+void
+HTTPClientSender::set_variable(const std::string& path, const std::string& key, const Atom& value)
+{
+ /*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);
+ send_message("/ingen/set_variable", m);*/
+}
+
+
+void
+HTTPClientSender::set_property(const std::string& path, const std::string& key, const Atom& value)
+{
+ /*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);
+ send_message("/ingen/set_property", m);*/
+}
+
+
+void
+HTTPClientSender::set_port_value(const std::string& port_path, const Raul::Atom& value)
+{
+ /*lo_message m = lo_message_new();
+ lo_message_add_string(m, port_path.c_str());
+ Raul::AtomLiblo::lo_message_add_atom(m, value);
+ send_message("/ingen/set_port_value", m);*/
+}
+
+
+void
+HTTPClientSender::set_voice_value(const std::string& port_path, uint32_t voice, const Raul::Atom& value)
+{
+ /*lo_message m = lo_message_new();
+ lo_message_add_string(m, port_path.c_str());
+ Raul::AtomLiblo::lo_message_add_atom(m, value);
+ send_message("/ingen/set_port_value", m);*/
+}
+
+
+void
+HTTPClientSender::port_activity(const std::string& port_path)
+{
+ //lo_send(_address, "/ingen/port_activity", "s", port_path.c_str(), LO_ARGS_END);
+}
+
+
+void
+HTTPClientSender::new_plugin(const std::string& uri,
+ const std::string& type_uri,
+ const std::string& symbol,
+ const std::string& name)
+{
+ /*lo_message m = lo_message_new();
+ lo_message_add_string(m, uri.c_str());
+ lo_message_add_string(m, type_uri.c_str());
+ lo_message_add_string(m, symbol.c_str());
+ lo_message_add_string(m, name.c_str());
+ send_message("/ingen/plugin", m);*/
+}
+
+
+void
+HTTPClientSender::new_patch(const std::string& path, uint32_t poly)
+{
+ cout << "HTTP NEW PATCH" << endl;
+ send_chunk(string("<").append(path).append("> a ingen:Patch"));
+ //send("/ingen/new_patch", "si", path.c_str(), poly, LO_ARGS_END);
+}
+
+
+void
+HTTPClientSender::object_renamed(const std::string& old_path, const std::string& new_path)
+{
+ //send("/ingen/object_renamed", "ss", old_path.c_str(), new_path.c_str(), LO_ARGS_END);
+}
+
+
+void
+HTTPClientSender::program_add(const std::string& node_path, uint32_t bank, uint32_t program, const std::string& name)
+{
+ /*send("/ingen/program_add", "siis",
+ node_path.c_str(), bank, program, name.c_str(), LO_ARGS_END);*/
+}
+
+
+void
+HTTPClientSender::program_remove(const std::string& node_path, uint32_t bank, uint32_t program)
+{
+ /*send("/ingen/program_remove", "sii",
+ node_path.c_str(), bank, program, LO_ARGS_END);*/
+}
+
+
+} // namespace Ingen
diff --git a/src/engine/HTTPClientSender.hpp b/src/engine/HTTPClientSender.hpp
new file mode 100644
index 00000000..8e4f3d33
--- /dev/null
+++ b/src/engine/HTTPClientSender.hpp
@@ -0,0 +1,138 @@
+/* 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 HTTPCLIENTSENDER_H
+#define HTTPCLIENTSENDER_H
+
+#include <cassert>
+#include <string>
+#include <iostream>
+#include <lo/lo.h>
+#include <pthread.h>
+#include "types.hpp"
+#include "raul/Thread.hpp"
+#include "interface/ClientInterface.hpp"
+#include "shared/HTTPSender.hpp"
+
+namespace Ingen {
+
+namespace Shared { class EngineInterface; }
+
+
+/** Implements ClientInterface for HTTP clients.
+ * Sends changes as RDF deltas over an HTTP stream
+ * (a single message with chunked encoding response).
+ *
+ * \ingroup engine
+ */
+class HTTPClientSender
+ : public Shared::ClientInterface
+ , public Raul::Thread
+ , public Shared::HTTPSender
+{
+public:
+ HTTPClientSender(SoupServer* s, SoupMessage* m)
+ : Shared::HTTPSender(s, m)
+ {}
+
+ bool enabled() const { return _enabled; }
+
+ void enable() { _enabled = true; }
+ void disable() { _enabled = false; }
+
+ void bundle_begin() { HTTPSender::bundle_begin(); }
+ void bundle_end() { HTTPSender::bundle_end(); }
+ void transfer_begin() { HTTPSender::transfer_begin(); }
+ void transfer_end() { HTTPSender::transfer_end(); }
+
+ std::string uri() const { return "http://example.org/"; }
+
+ void subscribe(Shared::EngineInterface* engine) { }
+
+ /* *** ClientInterface Implementation Below *** */
+
+ //void client_registration(const std::string& url, int client_id);
+
+ void response_ok(int32_t id);
+ void response_error(int32_t id, const std::string& msg);
+
+ void error(const std::string& msg);
+
+ virtual void new_plugin(const std::string& uri,
+ const std::string& type_uri,
+ const std::string& symbol,
+ const std::string& name);
+
+ virtual void new_patch(const std::string& path, uint32_t poly);
+
+ virtual void new_node(const std::string& path,
+ const std::string& plugin_uri);
+
+ virtual void new_port(const std::string& path,
+ const std::string& type,
+ uint32_t index,
+ bool is_output);
+
+ virtual void patch_cleared(const std::string& path);
+
+ virtual void destroy(const std::string& path);
+
+ virtual void object_renamed(const std::string& old_path,
+ const std::string& new_path);
+
+ virtual void connect(const std::string& src_port_path,
+ const std::string& dst_port_path);
+
+ virtual void disconnect(const std::string& src_port_path,
+ const std::string& dst_port_path);
+
+ virtual void set_variable(const std::string& subject_path,
+ const std::string& predicate,
+ const Raul::Atom& value);
+
+ virtual void set_property(const std::string& subject_path,
+ const std::string& predicate,
+ const Raul::Atom& value);
+
+ virtual void set_port_value(const std::string& port_path,
+ const Raul::Atom& value);
+
+ virtual void set_voice_value(const std::string& port_path,
+ uint32_t voice,
+ const Raul::Atom& value);
+
+ virtual void port_activity(const std::string& port_path);
+
+ virtual void program_add(const std::string& node_path,
+ uint32_t bank,
+ uint32_t program,
+ const std::string& program_name);
+
+ virtual void program_remove(const std::string& node_path,
+ uint32_t bank,
+ uint32_t program);
+
+private:
+ std::string _url;
+ bool _enabled;
+};
+
+
+} // namespace Ingen
+
+#endif // HTTPCLIENTSENDER_H
+
diff --git a/src/engine/HTTPEngineReceiver.cpp b/src/engine/HTTPEngineReceiver.cpp
index 8a035175..9b6b6fb9 100644
--- a/src/engine/HTTPEngineReceiver.cpp
+++ b/src/engine/HTTPEngineReceiver.cpp
@@ -32,6 +32,7 @@
#include "QueuedEventSource.hpp"
#include "ClientBroadcaster.hpp"
#include "EngineStore.hpp"
+#include "HTTPClientSender.hpp"
using namespace std;
using namespace Ingen::Shared;
@@ -126,6 +127,7 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const
if (path == "/" || path == "") {
const string r = string("@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n")
.append("\n<> rdfs:seeAlso <plugins> ;")
+ .append("\n rdfs:seeAlso <stream> ;")
.append("\n rdfs:seeAlso <patch> .");
soup_message_set_status(msg, SOUP_STATUS_OK);
soup_message_set_response(msg, mime_type, SOUP_MEMORY_COPY, r.c_str(), r.length());
@@ -146,6 +148,14 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const
return;
} else if (path.substr(0, 6) == "/patch") {
path = '/' + path.substr(6);
+ } else if (path.substr(0, 7) == "/stream") {
+ cout << "REGISTERING CLIENT" << endl;
+ // FIXME: memory leak
+ ClientInterface* client = new HTTPClientSender(me->_server, msg);
+ soup_message_headers_set_encoding(msg->response_headers, SOUP_ENCODING_CHUNKED);
+ me->register_client(client);
+ return;
+
} else {
cout << "UNKNOWN PATH: " << path << endl;
soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND);
diff --git a/src/engine/HTTPEngineReceiver.hpp b/src/engine/HTTPEngineReceiver.hpp
index 07b730b0..a6ed8825 100644
--- a/src/engine/HTTPEngineReceiver.hpp
+++ b/src/engine/HTTPEngineReceiver.hpp
@@ -54,7 +54,7 @@ private:
GHashTable *query, SoupClientContext* client, void* data);
ReceiveThread* _receive_thread;
- SoupServer* _server;
+ SoupServer* _server;
};
diff --git a/src/engine/wscript b/src/engine/wscript
index face717a..1fa05b23 100644
--- a/src/engine/wscript
+++ b/src/engine/wscript
@@ -92,7 +92,12 @@ def build(bld):
if bld.env()['HAVE_SOUP'] == 1:
obj = bld.create_obj('cpp', 'shlib')
- obj.source = 'QueuedEventSource.cpp QueuedEngineInterface.cpp HTTPEngineReceiver.cpp'
+ obj.source = '''
+ QueuedEventSource.cpp
+ QueuedEngineInterface.cpp
+ HTTPClientSender.cpp
+ HTTPEngineReceiver.cpp
+ '''
obj.includes = ['.', '..', '../common', './events', '../engine']
obj.name = 'libingen_engine_http'
obj.target = 'ingen_engine_http'
@@ -101,7 +106,12 @@ def build(bld):
if bld.env()['HAVE_LIBLO'] == 1:
obj = bld.create_obj('cpp', 'shlib')
- obj.source = 'QueuedEventSource.cpp QueuedEngineInterface.cpp OSCClientSender.cpp OSCEngineReceiver.cpp'
+ obj.source = '''
+ QueuedEventSource.cpp
+ QueuedEngineInterface.cpp
+ OSCClientSender.cpp
+ OSCEngineReceiver.cpp
+ '''
obj.includes = ['.', '..', '../common', './events', '../engine']
obj.name = 'libingen_engine_osc'
obj.target = 'ingen_engine_osc'