summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-08-15 05:15:31 +0000
committerDavid Robillard <d@drobilla.net>2008-08-15 05:15:31 +0000
commit79887329f008ba184aac8d7c606859986a9ef20e (patch)
treece7f0308ad6d7b5fcbf9a4e1d03d98ee648b8d24
parent2b189b5979fed3f52a1bea082201a892d00aa38c (diff)
downloadingen-79887329f008ba184aac8d7c606859986a9ef20e.tar.gz
ingen-79887329f008ba184aac8d7c606859986a9ef20e.tar.bz2
ingen-79887329f008ba184aac8d7c606859986a9ef20e.zip
Add primitive read-only HTTP interface (point browser to http://localhost:16180/).
git-svn-id: http://svn.drobilla.net/lad/ingen@1390 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/libs/engine/Engine.cpp20
-rw-r--r--src/libs/engine/Engine.hpp4
-rw-r--r--src/libs/engine/HTTPEngineReceiver.cpp125
-rw-r--r--src/libs/engine/HTTPEngineReceiver.hpp59
-rw-r--r--src/libs/engine/JackAudioDriver.cpp3
-rw-r--r--src/libs/engine/Makefile.am14
-rw-r--r--src/libs/engine/OSCEngineReceiver.hpp2
-rw-r--r--src/progs/ingen/main.cpp4
8 files changed, 226 insertions, 5 deletions
diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp
index 0decdf25..0a6d048a 100644
--- a/src/libs/engine/Engine.cpp
+++ b/src/libs/engine/Engine.cpp
@@ -39,6 +39,7 @@
#include "CreatePatchEvent.hpp"
#include "EnablePatchEvent.hpp"
#include "OSCEngineReceiver.hpp"
+#include "HTTPEngineReceiver.hpp"
#include "PostProcessor.hpp"
#include "ProcessSlave.hpp"
#include "ThreadManager.hpp"
@@ -164,6 +165,17 @@ Engine::start_osc_driver(int port)
_event_source = SharedPtr<EventSource>(new OSCEngineReceiver(
*this, pre_processor_queue_size, port));
}
+
+
+void
+Engine::start_http_driver(int port)
+{
+#ifdef HAVE_SOUP
+ // FIXE: leak
+ HTTPEngineReceiver* server = new HTTPEngineReceiver(*this, port);
+ server->activate();
+#endif
+}
SharedPtr<QueuedEngineInterface>
@@ -276,6 +288,14 @@ Engine::deactivate()
_activated = false;
}
+
+
+void
+Engine::process_events(ProcessContext& context)
+{
+ if (_event_source)
+ _event_source->process(*_post_processor, context);
+}
} // namespace Ingen
diff --git a/src/libs/engine/Engine.hpp b/src/libs/engine/Engine.hpp
index be7a3ee7..c2a59f3e 100644
--- a/src/libs/engine/Engine.hpp
+++ b/src/libs/engine/Engine.hpp
@@ -46,6 +46,7 @@ class QueuedEvent;
class QueuedEngineInterface;
class Driver;
class ProcessSlave;
+class ProcessContext;
/** The main class for the Engine.
@@ -71,12 +72,15 @@ public:
virtual void start_jack_driver();
virtual void start_osc_driver(int port);
+ virtual void start_http_driver(int port);
virtual SharedPtr<QueuedEngineInterface> new_queued_interface();
virtual bool activate(size_t parallelism);
virtual void deactivate();
+ void process_events(ProcessContext& context);
+
virtual bool activated() { return _activated; }
Raul::Maid* maid() const { return _maid; }
diff --git a/src/libs/engine/HTTPEngineReceiver.cpp b/src/libs/engine/HTTPEngineReceiver.cpp
new file mode 100644
index 00000000..baa522ba
--- /dev/null
+++ b/src/libs/engine/HTTPEngineReceiver.cpp
@@ -0,0 +1,125 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2007 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 <cstdlib>
+#include <string>
+#include "types.hpp"
+#include <raul/SharedPtr.hpp>
+#include <raul/AtomLiblo.hpp>
+#include "interface/ClientInterface.hpp"
+#include "engine/ThreadManager.hpp"
+#include "HTTPEngineReceiver.hpp"
+#include "QueuedEventSource.hpp"
+#include "ClientBroadcaster.hpp"
+#include "ObjectStore.hpp"
+
+using namespace std;
+
+namespace Ingen {
+
+
+HTTPEngineReceiver::HTTPEngineReceiver(Engine& engine, uint16_t port)
+ : QueuedEngineInterface(engine, 2, 2)
+ , _server(soup_server_new(SOUP_SERVER_PORT, port, NULL))
+{
+ _receive_thread = new ReceiveThread(*this);
+
+ soup_server_add_handler(_server, NULL, message_callback, this, NULL);
+
+ cout << "Started HTTP server on port " << soup_server_get_port(_server) << endl;
+ Thread::set_name("HTTP receiver");
+}
+
+
+HTTPEngineReceiver::~HTTPEngineReceiver()
+{
+ deactivate();
+
+ if (_server != NULL) {
+ soup_server_quit(_server);
+ _server = NULL;
+ }
+}
+
+
+void
+HTTPEngineReceiver::activate()
+{
+ QueuedEventSource::activate();
+ _receive_thread->set_name("HTTP Receiver");
+ _receive_thread->start();
+}
+
+
+void
+HTTPEngineReceiver::deactivate()
+{
+ cout << "[HTTPEngineReceiver] Stopped HTTP listening thread" << endl;
+ _receive_thread->stop();
+ QueuedEventSource::deactivate();
+}
+
+
+void
+HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const char* path,
+ GHashTable *query, SoupClientContext* client, void* data)
+{
+ HTTPEngineReceiver* me = (HTTPEngineReceiver*)data;
+
+ if (msg->method != SOUP_METHOD_GET) {
+ soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ return;
+ }
+
+ // FIXME: not thread safe!
+
+ ObjectStore* store = me->_engine.object_store();
+ if (!Path::is_valid(path)) {
+ soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
+ return;
+ }
+
+ ObjectStore::Objects::iterator start = store->find(path);
+ if (start == store->objects().end()) {
+ soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
+ return;
+ }
+
+ ObjectStore::Objects::iterator end = store->objects().find_descendants_end(start);
+
+ string response;
+ for (ObjectStore::Objects::iterator i = start; i != end; ++i)
+ response.append(i->first).append("\n");
+
+ soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY,
+ response.c_str(), response.length());
+}
+
+
+/** Override the semaphore driven _run method of QueuedEngineInterface
+ * to wait on HTTP requests and process them immediately in this thread.
+ */
+void
+HTTPEngineReceiver::ReceiveThread::_run()
+{
+ soup_server_run(_receiver._server);
+}
+
+
+} // namespace Ingen
diff --git a/src/libs/engine/HTTPEngineReceiver.hpp b/src/libs/engine/HTTPEngineReceiver.hpp
new file mode 100644
index 00000000..34c425b2
--- /dev/null
+++ b/src/libs/engine/HTTPEngineReceiver.hpp
@@ -0,0 +1,59 @@
+/* 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 HTTPENGINERECEIVER_H
+#define HTTPENGINERECEIVER_H
+
+#include CONFIG_H_PATH
+#include <string>
+#include <stdint.h>
+#include <libsoup/soup.h>
+#include <raul/SharedPtr.hpp>
+#include "QueuedEngineInterface.hpp"
+
+namespace Ingen {
+
+class HTTPEngineReceiver : public QueuedEngineInterface
+{
+public:
+ HTTPEngineReceiver(Engine& engine, uint16_t port);
+ ~HTTPEngineReceiver();
+
+ void activate();
+ void deactivate();
+
+private:
+ struct ReceiveThread : public Raul::Thread {
+ ReceiveThread(HTTPEngineReceiver& receiver) : _receiver(receiver) {}
+ virtual void _run();
+ private:
+ HTTPEngineReceiver& _receiver;
+ };
+
+ friend class ReceiveThread;
+
+ static void message_callback(SoupServer* server, SoupMessage* msg, const char* path,
+ GHashTable *query, SoupClientContext* client, void* data);
+
+ ReceiveThread* _receive_thread;
+ SoupServer* _server;
+};
+
+
+} // namespace Ingen
+
+#endif // HTTPENGINERECEIVER_H
diff --git a/src/libs/engine/JackAudioDriver.cpp b/src/libs/engine/JackAudioDriver.cpp
index ea49e492..eff04653 100644
--- a/src/libs/engine/JackAudioDriver.cpp
+++ b/src/libs/engine/JackAudioDriver.cpp
@@ -314,8 +314,7 @@ JackAudioDriver::_process_cb(jack_nframes_t nframes)
// Process events that came in during the last cycle
// (Aiming for jitter-free 1 block event latency, ideally)
- if (_engine.event_source())
- _engine.event_source()->process(*_engine.post_processor(), _process_context);
+ _engine.process_events(_process_context);
// Set buffers of patch ports to Jack port buffers (zero-copy processing)
for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) {
diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am
index 3ce73124..0f069e10 100644
--- a/src/libs/engine/Makefile.am
+++ b/src/libs/engine/Makefile.am
@@ -11,10 +11,11 @@ libingen_engine_la_CXXFLAGS = \
@JACK_CFLAGS@ \
@LASH_CFLAGS@ \
@LIBLO_CFLAGS@ \
+ @LV2_OSC_CFLAGS@ \
@RAUL_CFLAGS@ \
@REDLANDMM_CFLAGS@ \
@SLV2_CFLAGS@ \
- @LV2_OSC_CFLAGS@
+ @SOUP_CFLAGS@
libingen_engine_la_LDFLAGS = -no-undefined -module -avoid-version
libingen_engine_la_LIBADD = \
@@ -23,10 +24,11 @@ libingen_engine_la_LIBADD = \
@JACK_LIBS@ \
@LASH_LIBS@ \
@LIBLO_LIBS@ \
+ @LV2_OSC_LIBS@ \
@RAUL_LIBS@ \
@REDLANDMM_LIBS@ \
@SLV2_LIBS@ \
- @LV2_OSC_LIBS@
+ @SOUP_LIBS@
AM_CFLAGS=-std=c99
@@ -196,3 +198,11 @@ libingen_engine_la_SOURCES += \
LV2Node.cpp
endif
+if WITH_SOUP
+libingen_engine_la_SOURCES += \
+ HTTPEngineReceiver.cpp \
+ HTTPEngineReceiver.hpp
+endif
+
+
+
diff --git a/src/libs/engine/OSCEngineReceiver.hpp b/src/libs/engine/OSCEngineReceiver.hpp
index 0f9d4685..a998054f 100644
--- a/src/libs/engine/OSCEngineReceiver.hpp
+++ b/src/libs/engine/OSCEngineReceiver.hpp
@@ -73,7 +73,7 @@ private:
ReceiveThread(OSCEngineReceiver& receiver) : _receiver(receiver) {}
virtual void _run();
private:
- OSCEngineReceiver& _receiver;
+ OSCEngineReceiver& _receiver;
};
friend class ReceiveThread;
diff --git a/src/progs/ingen/main.cpp b/src/progs/ingen/main.cpp
index 299a6595..fe78468f 100644
--- a/src/progs/ingen/main.cpp
+++ b/src/progs/ingen/main.cpp
@@ -86,6 +86,9 @@ main(int argc, char** argv)
SharedPtr<Shared::EngineInterface> engine_interface;
Glib::thread_init();
+#if HAVE_SOUP
+ g_type_init();
+#endif
Ingen::Shared::World* world = Ingen::Shared::get_world();
@@ -112,6 +115,7 @@ main(int argc, char** argv)
world->engine = engine_interface;
} else {
engine->start_osc_driver(args.engine_port_arg);
+ engine->start_http_driver(args.engine_port_arg);
}
} else {
engine_module.reset();