summaryrefslogtreecommitdiffstats
path: root/src/server/QueuedEngineInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/QueuedEngineInterface.cpp')
-rw-r--r--src/server/QueuedEngineInterface.cpp223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/server/QueuedEngineInterface.cpp b/src/server/QueuedEngineInterface.cpp
new file mode 100644
index 00000000..5ef9335f
--- /dev/null
+++ b/src/server/QueuedEngineInterface.cpp
@@ -0,0 +1,223 @@
+/* This file is part of Ingen.
+ * Copyright 2007-2011 David 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/log.hpp"
+
+#include "Driver.hpp"
+#include "Engine.hpp"
+#include "EventSource.hpp"
+#include "QueuedEngineInterface.hpp"
+#include "events.hpp"
+
+#define LOG(s) s << "[QueuedEngineInterface] "
+
+using namespace std;
+using namespace Raul;
+
+namespace Ingen {
+namespace Server {
+
+QueuedEngineInterface::QueuedEngineInterface(Engine& engine, size_t queue_size)
+ : EventSource(queue_size)
+ , _request(new Request(this, NULL, 0))
+ , _engine(engine)
+ , _in_bundle(false)
+{
+ start();
+}
+
+
+QueuedEngineInterface::~QueuedEngineInterface()
+{
+ stop();
+}
+
+SampleCount
+QueuedEngineInterface::now() const
+{
+ // Exactly one cycle latency (some could run ASAP if we get lucky, but not always, and a slight
+ // constant latency is far better than jittery lower (average) latency
+ if (_engine.driver())
+ return _engine.driver()->frame_time() + _engine.driver()->block_length();
+ else
+ return 0;
+}
+
+void
+QueuedEngineInterface::set_next_response_id(int32_t id)
+{
+ if (_request)
+ _request->set_id(id);
+}
+
+void
+QueuedEngineInterface::disable_responses()
+{
+ _request->set_client(NULL);
+ _request->set_id(0);
+}
+
+/* *** ServerInterface implementation below here *** */
+
+void
+QueuedEngineInterface::register_client(ClientInterface* client)
+{
+ push_queued(new Events::RegisterClient(_engine, _request, now(), client->uri(), client));
+ if (!_request) {
+ _request = SharedPtr<Request>(new Request(this, client, 1));
+ } else {
+ _request->set_id(1);
+ _request->set_client(client);
+ }
+}
+
+void
+QueuedEngineInterface::unregister_client(const URI& uri)
+{
+ push_queued(new Events::UnregisterClient(_engine, _request, now(), uri));
+ if (_request && _request->client() && _request->client()->uri() == uri) {
+ _request->set_id(0);
+ _request->set_client(NULL);
+ }
+}
+
+// Bundle commands
+
+void
+QueuedEngineInterface::bundle_begin()
+{
+ _in_bundle = true;
+}
+
+void
+QueuedEngineInterface::bundle_end()
+{
+ _in_bundle = false;
+}
+
+// Object commands
+
+void
+QueuedEngineInterface::put(const URI& uri,
+ const Resource::Properties& properties,
+ const Resource::Graph ctx)
+{
+ push_queued(new Events::SetMetadata(_engine, _request, now(), true, ctx, uri, properties));
+}
+
+void
+QueuedEngineInterface::delta(const URI& uri,
+ const Resource::Properties& remove,
+ const Resource::Properties& add)
+{
+ push_queued(new Events::SetMetadata(_engine, _request, now(), false, Resource::DEFAULT, uri, add, remove));
+}
+
+void
+QueuedEngineInterface::move(const Path& old_path,
+ const Path& new_path)
+{
+ push_queued(new Events::Move(_engine, _request, now(), old_path, new_path));
+}
+
+void
+QueuedEngineInterface::del(const URI& uri)
+{
+ if (uri == "ingen:engine") {
+ _request->respond_ok();
+ _engine.quit();
+ } else {
+ push_queued(new Events::Delete(_engine, _request, now(), uri));
+ }
+}
+
+void
+QueuedEngineInterface::connect(const Path& src_port_path,
+ const Path& dst_port_path)
+{
+ push_queued(new Events::Connect(_engine, _request, now(), src_port_path, dst_port_path));
+
+}
+
+void
+QueuedEngineInterface::disconnect(const URI& src,
+ const URI& dst)
+{
+ if (!Path::is_path(src) && !Path::is_path(dst)) {
+ std::cerr << "Bad disconnect request " << src << " => " << dst << std::endl;
+ return;
+ }
+
+ push_queued(new Events::Disconnect(_engine, _request, now(),
+ Path(src.str()), Path(dst.str())));
+}
+
+void
+QueuedEngineInterface::disconnect_all(const Path& patch_path,
+ const Path& path)
+{
+ push_queued(new Events::DisconnectAll(_engine, _request, now(), patch_path, path));
+}
+
+void
+QueuedEngineInterface::set_property(const URI& uri,
+ const URI& predicate,
+ const Atom& value)
+{
+ if (uri == "ingen:engine" && predicate == "ingen:enabled"
+ && value.type() == Atom::BOOL) {
+ if (value.get_bool()) {
+ _engine.activate();
+ push_queued(new Events::Ping(_engine, _request, now()));
+ } else {
+ push_queued(new Events::Deactivate(_engine, _request, now()));
+ }
+ } else {
+ Resource::Properties remove;
+ remove.insert(make_pair(predicate, _engine.world()->uris()->wildcard));
+ Resource::Properties add;
+ add.insert(make_pair(predicate, value));
+ push_queued(new Events::SetMetadata(
+ _engine, _request, now(), false, Resource::DEFAULT,
+ uri, add, remove));
+ }
+}
+
+// Requests //
+
+void
+QueuedEngineInterface::ping()
+{
+ push_queued(new Events::Ping(_engine, _request, now()));
+}
+
+void
+QueuedEngineInterface::get(const URI& uri)
+{
+ push_queued(new Events::Get(_engine, _request, now(), uri));
+}
+
+void
+QueuedEngineInterface::request_property(const URI& uri, const URI& key)
+{
+ push_queued(new Events::RequestMetadata(_engine, _request, now(), Resource::DEFAULT, uri, key));
+}
+
+} // namespace Server
+} // namespace Ingen