aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/ClientModel.cpp63
-rw-r--r--src/client/ClientModel.hpp57
-rw-r--r--src/client/ClientObject.cpp55
-rw-r--r--src/client/ClientObject.hpp69
-rw-r--r--src/client/wscript18
-rw-r--r--src/engine/Controller.cpp187
-rw-r--r--src/engine/URIs.cpp24
-rw-r--r--src/engine/Updates.cpp143
-rw-r--r--src/engine/machina/Controller.hpp78
-rw-r--r--src/engine/machina/URIs.hpp74
-rw-r--r--src/engine/machina/Updates.hpp48
11 files changed, 816 insertions, 0 deletions
diff --git a/src/client/ClientModel.cpp b/src/client/ClientModel.cpp
new file mode 100644
index 0000000..f26d853
--- /dev/null
+++ b/src/client/ClientModel.cpp
@@ -0,0 +1,63 @@
+/* This file is part of Machina.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ClientModel.hpp"
+
+namespace Machina {
+namespace Client {
+
+SharedPtr<ClientObject>
+ClientModel::find(uint64_t id)
+{
+ SharedPtr<ClientObject> key(new ClientObjectKey(id));
+ Objects::iterator i = _objects.find(key);
+ if (i != _objects.end())
+ return *i;
+ else
+ return SharedPtr<ClientObject>();
+}
+
+void
+ClientModel::new_object(SharedPtr<ClientObject> object)
+{
+ _objects.insert(object);
+ signal_new_object.emit(object);
+}
+
+void
+ClientModel::erase_object(uint64_t id)
+{
+ SharedPtr<ClientObject> key(new ClientObjectKey(id));
+ Objects::iterator i = _objects.find(key);
+ if (i == _objects.end())
+ return;
+
+ signal_erase_object.emit(*i);
+ (*i)->set_view(SharedPtr<ClientObject::View>());
+ _objects.erase(i);
+}
+
+void
+ClientModel::property(uint64_t id, URIInt key, const Raul::Atom& value)
+{
+ SharedPtr<ClientObject> object = find(id);
+ if (object)
+ object->set(key, value);
+}
+
+}
+}
diff --git a/src/client/ClientModel.hpp b/src/client/ClientModel.hpp
new file mode 100644
index 0000000..49f14a5
--- /dev/null
+++ b/src/client/ClientModel.hpp
@@ -0,0 +1,57 @@
+/* This file is part of Machina.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MACHINA_CLIENTMODEL_HPP
+#define MACHINA_CLIENTMODEL_HPP
+
+#include <set>
+
+#include <sigc++/sigc++.h>
+
+#include "ClientObject.hpp"
+
+namespace Raul { class Atom; }
+
+namespace Machina {
+namespace Client {
+
+class ClientModel {
+public:
+ void new_object(SharedPtr<ClientObject> object);
+ void erase_object(uint64_t id);
+ void property(uint64_t id, URIInt key, const Raul::Atom& value);
+
+ SharedPtr<ClientObject> find(uint64_t id);
+
+ sigc::signal< void, SharedPtr<ClientObject> > signal_new_object;
+ sigc::signal< void, SharedPtr<ClientObject> > signal_erase_object;
+
+private:
+ struct ClientObjectComparator {
+ inline bool operator()(SharedPtr<ClientObject> lhs, SharedPtr<ClientObject> rhs) const {
+ return lhs->id() < rhs->id();
+ }
+ };
+
+ typedef std::set<SharedPtr<ClientObject>, ClientObjectComparator> Objects;
+ Objects _objects;
+};
+
+}
+}
+
+#endif // MACHINA_CLIENTMODEL_HPP
diff --git a/src/client/ClientObject.cpp b/src/client/ClientObject.cpp
new file mode 100644
index 0000000..41f8080
--- /dev/null
+++ b/src/client/ClientObject.cpp
@@ -0,0 +1,55 @@
+/* This file is part of Machina.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <iostream>
+
+#include "ClientObject.hpp"
+
+namespace Machina {
+namespace Client {
+
+ClientObject::ClientObject(uint64_t id)
+ : _id(id)
+{
+}
+
+ClientObject::ClientObject(const ClientObject& copy, uint64_t id)
+ : _id(id)
+ , _properties(copy._properties)
+{
+}
+
+void
+ClientObject::set(URIInt key, const Raul::Atom& value)
+{
+ _properties[key] = value;
+ signal_property.emit(key, value);
+}
+
+const Raul::Atom&
+ClientObject::get(URIInt key) const
+{
+ static const Raul::Atom null_atom;
+ Properties::const_iterator i = _properties.find(key);
+ if (i != _properties.end())
+ return i->second;
+ else
+ return null_atom;
+}
+
+}
+}
diff --git a/src/client/ClientObject.hpp b/src/client/ClientObject.hpp
new file mode 100644
index 0000000..9b8403c
--- /dev/null
+++ b/src/client/ClientObject.hpp
@@ -0,0 +1,69 @@
+/* This file is part of Machina.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MACHINA_CLIENTOBJECT_HPP
+#define MACHINA_CLIENTOBJECT_HPP
+
+#include <map>
+
+#include <sigc++/sigc++.h>
+
+#include "raul/Atom.hpp"
+#include "raul/SharedPtr.hpp"
+
+#include "machina/types.hpp"
+
+namespace Machina {
+namespace Client {
+
+class ClientObject {
+public:
+ ClientObject(uint64_t id);
+ ClientObject(const ClientObject& copy, uint64_t id);
+
+ inline uint64_t id() const { return _id; }
+
+ void set(URIInt key, const Raul::Atom& value);
+ const Raul::Atom& get(URIInt key) const;
+
+ sigc::signal<void, URIInt, Raul::Atom> signal_property;
+
+ class View {
+ public:
+ virtual ~View() {}
+ };
+
+ SharedPtr<View> view() const { return _view; }
+ void set_view(SharedPtr<View> view) { _view = view; }
+
+private:
+ uint64_t _id;
+ SharedPtr<View> _view;
+
+ typedef std::map<URIInt, Raul::Atom> Properties;
+ Properties _properties;
+};
+
+class ClientObjectKey : public ClientObject {
+public:
+ ClientObjectKey(uint64_t id) : ClientObject(id) {}
+};
+
+}
+}
+
+#endif // MACHINA_CLIENTOBJECT_HPP
diff --git a/src/client/wscript b/src/client/wscript
new file mode 100644
index 0000000..03082cc
--- /dev/null
+++ b/src/client/wscript
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+import autowaf
+
+def build(bld):
+ obj = bld(features = 'cxx cxxshlib')
+ obj.source = '''
+ ClientModel.cpp
+ ClientObject.cpp
+ '''
+ obj.export_includes = ['.']
+ obj.includes = ['.', '..', '../..']
+ obj.name = 'libmachina_client'
+ obj.target = 'machina_client'
+ obj.use = 'libmachina_engine'
+ autowaf.use_lib(bld, obj, 'RAUL')
+
+ bld.add_post_fun(autowaf.run_ldconfig)
+
diff --git a/src/engine/Controller.cpp b/src/engine/Controller.cpp
new file mode 100644
index 0000000..9c39711
--- /dev/null
+++ b/src/engine/Controller.cpp
@@ -0,0 +1,187 @@
+/* This file is part of Machina.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "client/ClientModel.hpp"
+#include "client/ClientObject.hpp"
+#include "machina/Controller.hpp"
+#include "machina/Engine.hpp"
+#include "machina/Machine.hpp"
+#include "machina/Updates.hpp"
+#include "machina/Machine.hpp"
+
+#include "Edge.hpp"
+
+namespace Machina {
+
+Controller::Controller(SharedPtr<Engine> engine, Client::ClientModel& client_model)
+ : _engine(engine)
+ , _client_model(client_model)
+ , _updates(new UpdateBuffer(4096))
+{
+ _engine->driver()->set_update_sink(_updates);
+}
+
+uint64_t
+Controller::create(const Client::ClientObject& properties)
+{
+ TimeDuration dur(_engine->machine()->time().unit(),
+ properties.get(URIs::instance().machina_duration).get_float());
+ SharedPtr<Machina::Node> node(new Machina::Node(dur));
+ SharedPtr<Client::ClientObject> obj(new Client::ClientObject(properties, node->id()));
+ _objects.insert(node);
+ _client_model.new_object(obj);
+ _engine->machine()->add_node(node);
+ return node->id();
+}
+
+void
+Controller::announce(SharedPtr<Machine> machine)
+{
+ for (Machina::Machine::Nodes::const_iterator n = machine->nodes().begin();
+ n != machine->nodes().end(); ++n) {
+
+ SharedPtr<Machina::Client::ClientObject> obj(new Machina::Client::ClientObject((*n)->id()));
+ obj->set(URIs::instance().rdf_type, "machina:Node");
+ obj->set(URIs::instance().machina_duration, Raul::Atom(float((*n)->duration().to_double())));
+ obj->set(URIs::instance().machina_canvas_x, 0.0f);
+ obj->set(URIs::instance().machina_canvas_y, 0.0f);
+
+ _objects.insert(*n);
+ _client_model.new_object(obj);
+ }
+
+ for (Machina::Machine::Nodes::const_iterator n = machine->nodes().begin();
+ n != machine->nodes().end(); ++n) {
+ for (Machina::Node::Edges::const_iterator e = (*n)->edges().begin();
+ e != (*n)->edges().end(); ++e) {
+ _objects.insert(*e);
+
+ SharedPtr<Client::ClientObject> eobj(new Client::ClientObject((*e)->id()));
+ eobj->set(URIs::instance().rdf_type, "machina:Edge");
+ eobj->set(URIs::instance().machina_probability, (*e)->probability());
+ eobj->set(URIs::instance().machina_tail_id, (int32_t)(*n)->id());
+ eobj->set(URIs::instance().machina_head_id, (int32_t)(*e)->head()->id());
+
+ _client_model.new_object(eobj);
+ }
+ }
+}
+
+SharedPtr<Stateful>
+Controller::find(uint64_t id)
+{
+ SharedPtr<StatefulKey> key(new StatefulKey(id));
+ Objects::iterator i = _objects.find(key);
+ if (i != _objects.end())
+ return *i;
+ return SharedPtr<Stateful>();
+}
+
+void
+Controller::learn(SharedPtr<Raul::Maid> maid, uint64_t node_id)
+{
+ SharedPtr<Machina::Node> node = PtrCast<Machina::Node>(find(node_id));
+ if (node)
+ _engine->machine()->learn(maid, node);
+ else
+ std::cerr << "Failed to find node " << node_id << " for learn" << std::endl;
+}
+
+void
+Controller::set_property(uint64_t object_id, URIInt key, const Raul::Atom& value)
+{
+ SharedPtr<Stateful> object = find(object_id);
+ if (object) {
+ object->set(key, value);
+ _client_model.property(object_id, key, value);
+ }
+}
+
+uint64_t
+Controller::connect(uint64_t tail_id, uint64_t head_id)
+{
+ SharedPtr<Machina::Node> tail = PtrCast<Machina::Node>(find(tail_id));
+ SharedPtr<Machina::Node> head = PtrCast<Machina::Node>(find(head_id));
+
+ SharedPtr<Machina::Edge> edge(new Machina::Edge(tail, head));
+ tail->add_edge(edge);
+ _objects.insert(edge);
+
+ SharedPtr<Client::ClientObject> obj(new Client::ClientObject(/**this,*/ edge->id()));
+ obj->set(URIs::instance().rdf_type, "machina:Edge");
+ obj->set(URIs::instance().machina_probability, 1.0f);
+ obj->set(URIs::instance().machina_tail_id, (int32_t)tail->id());
+ obj->set(URIs::instance().machina_head_id, (int32_t)head->id());
+
+ _client_model.new_object(obj);
+
+ return edge->id();
+}
+
+void
+Controller::disconnect(uint64_t tail_id, uint64_t head_id)
+{
+ SharedPtr<Machina::Node> tail = PtrCast<Machina::Node>(find(tail_id));
+ SharedPtr<Machina::Node> head = PtrCast<Machina::Node>(find(head_id));
+
+ SharedPtr<Edge> edge = tail->remove_edge_to(head);
+ if (edge)
+ _client_model.erase_object(edge->id());
+ else
+ Raul::error << "Edge not found" << std::endl;
+}
+
+void
+Controller::erase(uint64_t id)
+{
+ SharedPtr<StatefulKey> key(new StatefulKey(id));
+ Objects::iterator i = _objects.find(key);
+ if (i == _objects.end()) {
+ return;
+ }
+
+ SharedPtr<Node> node = PtrCast<Node>(*i);
+ if (node) {
+ _engine->machine()->remove_node(node);
+ }
+
+ _client_model.erase_object((*i)->id());
+ _objects.erase(i);
+}
+
+void
+Controller::process_updates()
+{
+ const uint32_t read_space = _updates->read_space();
+
+ uint64_t subject;
+ URIInt key;
+ Raul::Atom value;
+ for (uint32_t i = 0; i < read_space;) {
+ i += read_set(_updates, &subject, &key, &value);
+ SharedPtr<Machina::Client::ClientObject> obj = _client_model.find(subject);
+ if (obj) {
+ obj->set(key, value);
+ } else {
+ SharedPtr<Client::ClientObject> obj(new Client::ClientObject(subject));
+ obj->set(key, value);
+ _client_model.new_object(obj);
+ }
+ }
+}
+
+}
diff --git a/src/engine/URIs.cpp b/src/engine/URIs.cpp
new file mode 100644
index 0000000..ccaf90c
--- /dev/null
+++ b/src/engine/URIs.cpp
@@ -0,0 +1,24 @@
+/* This file is part of Machina.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "machina/URIs.hpp"
+
+namespace Machina {
+
+URIs* URIs::_instance = NULL;
+
+} // namespace Machina
diff --git a/src/engine/Updates.cpp b/src/engine/Updates.cpp
new file mode 100644
index 0000000..3d1c0f3
--- /dev/null
+++ b/src/engine/Updates.cpp
@@ -0,0 +1,143 @@
+/* This file is part of Machina.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "raul/Atom.hpp"
+#include "raul/SharedPtr.hpp"
+
+#include "machina/types.hpp"
+#include "machina/Updates.hpp"
+
+namespace Machina {
+
+static inline void
+write_atom(SharedPtr<UpdateBuffer> buf,
+ const Raul::Atom& value)
+{
+ const Raul::Atom::Type type = value.type();
+ buf->write(sizeof(type), &type);
+ int32_t ival;
+ float fval;
+ size_t szval;
+ switch (value.type()) {
+ case Raul::Atom::INT:
+ ival = value.get_int32();
+ buf->write(sizeof(ival), &ival);
+ break;
+ case Raul::Atom::FLOAT:
+ ival = value.get_float();
+ buf->write(sizeof(fval), &fval);
+ break;
+ case Raul::Atom::BOOL:
+ ival = value.get_bool() ? 1 : 0;
+ buf->write(sizeof(ival), &ival);
+ break;
+ case Raul::Atom::STRING:
+ szval = value.data_size();
+ buf->write(sizeof(size_t), &szval);
+ buf->write(value.data_size(), value.get_string());
+ break;
+ case Raul::Atom::URI:
+ szval = value.data_size();
+ buf->write(sizeof(size_t), &szval);
+ buf->write(value.data_size(), value.get_uri());
+ break;
+ default:
+ assert(false);
+ }
+}
+
+uint32_t
+read_atom(SharedPtr<UpdateBuffer> buf,
+ Raul::Atom* value)
+{
+ Raul::Atom::Type type;
+ buf->read(sizeof(type), &type);
+
+ int32_t ival;
+ float fval;
+ char* sval;
+ size_t val_size;
+ switch (type) {
+ case Raul::Atom::INT:
+ val_size = sizeof(ival);
+ buf->read(val_size, &ival);
+ *value = Raul::Atom(ival);
+ break;
+ case Raul::Atom::FLOAT:
+ val_size = sizeof(fval);
+ buf->read(val_size, &fval);
+ *value = Raul::Atom(fval);
+ break;
+ case Raul::Atom::BOOL:
+ val_size = sizeof(ival);
+ buf->read(val_size, &ival);
+ assert(ival == 0 || ival == 1);
+ *value = Raul::Atom(bool(ival));
+ break;
+ case Raul::Atom::STRING:
+ buf->read(sizeof(val_size), &val_size);
+ sval = (char*)malloc(val_size);
+ buf->read(val_size, sval);
+ val_size += sizeof(val_size);
+ *value = Raul::Atom(sval);
+ free(sval);
+ break;
+ case Raul::Atom::URI:
+ buf->read(sizeof(val_size), &val_size);
+ sval = (char*)malloc(val_size);
+ buf->read(val_size, sval);
+ val_size += sizeof(val_size);
+ *value = Raul::Atom(Raul::Atom::URI, sval);
+ free(sval);
+ break;
+ default:
+ assert(false);
+ }
+
+ return sizeof(type) + val_size;
+}
+
+void
+write_set(SharedPtr<UpdateBuffer> buf,
+ uint64_t subject,
+ URIInt key,
+ const Raul::Atom& value)
+{
+ const uint32_t update_type = UPDATE_SET;
+ buf->write(sizeof(update_type), &update_type);
+ buf->write(sizeof(subject), &subject);
+ buf->write(sizeof(key), &key);
+ write_atom(buf, value);
+}
+
+uint32_t
+read_set(SharedPtr<UpdateBuffer> buf,
+ uint64_t* subject,
+ URIInt* key,
+ Raul::Atom* value)
+{
+ uint32_t update_type;
+ buf->read(sizeof(update_type), &update_type);
+ assert(update_type == UPDATE_SET);
+ buf->read(sizeof(*subject), subject);
+ buf->read(sizeof(*key), key);
+
+ const uint32_t value_size = read_atom(buf, value);
+ return sizeof(update_type) + sizeof(*subject) + sizeof(*key) + value_size;
+}
+
+}
diff --git a/src/engine/machina/Controller.hpp b/src/engine/machina/Controller.hpp
new file mode 100644
index 0000000..000fcad
--- /dev/null
+++ b/src/engine/machina/Controller.hpp
@@ -0,0 +1,78 @@
+/* This file is part of Machina.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MACHINA_CONTROLLER_HPP
+#define MACHINA_CONTROLLER_HPP
+
+#include <stdint.h>
+
+#include <set>
+
+#include "raul/SharedPtr.hpp"
+#include "raul/RingBuffer.hpp"
+
+#include "machina/types.hpp"
+#include "machina/URIs.hpp"
+
+#include "Stateful.hpp"
+
+namespace Raul { class Atom; class Maid; }
+
+namespace Machina {
+
+class Engine;
+class Machine;
+class Stateful;
+
+namespace Client { class ClientModel; class ClientObject; }
+
+class Controller {
+public:
+ Controller(SharedPtr<Engine> engine, Client::ClientModel& client_model);
+
+ uint64_t create(const Client::ClientObject& obj);
+ uint64_t connect(uint64_t tail_id, uint64_t head_id);
+ void set_property(uint64_t object_id, URIInt key, const Raul::Atom& value);
+ void learn(SharedPtr<Raul::Maid> maid, uint64_t node_id);
+ void disconnect(uint64_t tail_id, uint64_t head_id);
+ void erase(uint64_t id);
+
+ void announce(SharedPtr<Machine> machine);
+
+ void process_updates();
+
+private:
+ SharedPtr<Stateful> find(uint64_t id);
+
+ struct StatefulComparator {
+ inline bool operator()(SharedPtr<Stateful> lhs, SharedPtr<Stateful> rhs) const {
+ return lhs->id() < rhs->id();
+ }
+ };
+
+ typedef std::set<SharedPtr<Stateful>, StatefulComparator> Objects;
+ Objects _objects;
+
+ SharedPtr<Engine> _engine;
+ Client::ClientModel& _client_model;
+
+ SharedPtr<UpdateBuffer> _updates;
+};
+
+}
+
+#endif // MACHINA_CONTROLLER_HPP
diff --git a/src/engine/machina/URIs.hpp b/src/engine/machina/URIs.hpp
new file mode 100644
index 0000000..74e5451
--- /dev/null
+++ b/src/engine/machina/URIs.hpp
@@ -0,0 +1,74 @@
+/* This file is part of Machina.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MACHINA_URIS_HPP
+#define MACHINA_URIS_HPP
+
+#include <stdint.h>
+
+#include "raul/Atom.hpp"
+
+#include "machina/types.hpp"
+
+namespace Machina {
+
+class URIs {
+public:
+ static void init() { _instance = new URIs(); }
+
+ static inline const URIs& instance() { assert(_instance); return *_instance; }
+
+ Raul::Atom machina_MidiAction_atom;
+
+ URIInt machina_active;
+ URIInt machina_canvas_x;
+ URIInt machina_canvas_y;
+ URIInt machina_duration;
+ URIInt machina_enter_action;
+ URIInt machina_exit_action;
+ URIInt machina_head_id;
+ URIInt machina_initial;
+ URIInt machina_note_number;
+ URIInt machina_probability;
+ URIInt machina_selector;
+ URIInt machina_tail_id;
+ URIInt rdf_type;
+
+private:
+ URIs()
+ : machina_MidiAction_atom(Raul::Atom::URI, "machina:MidiAction")
+ , machina_active(1)
+ , machina_canvas_x(2)
+ , machina_canvas_y(3)
+ , machina_duration(4)
+ , machina_enter_action(11)
+ , machina_exit_action(12)
+ , machina_head_id(5)
+ , machina_initial(6)
+ , machina_note_number(13)
+ , machina_probability(7)
+ , machina_selector(8)
+ , machina_tail_id(9)
+ , rdf_type(10)
+ {}
+
+ static URIs* _instance;
+};
+
+} // namespace Machina
+
+#endif // MACHINA_URIS_HPP
diff --git a/src/engine/machina/Updates.hpp b/src/engine/machina/Updates.hpp
new file mode 100644
index 0000000..31c7e2b
--- /dev/null
+++ b/src/engine/machina/Updates.hpp
@@ -0,0 +1,48 @@
+/* This file is part of Machina.
+ * Copyright (C) 2010 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MACHINA_UPDATES_HPP
+#define MACHINA_UPDATES_HPP
+
+#include <stdint.h>
+
+#include "raul/Atom.hpp"
+#include "raul/SharedPtr.hpp"
+
+#include "machina/types.hpp"
+
+namespace Machina {
+
+enum UpdateType {
+ UPDATE_SET = 1
+};
+
+void
+write_set(SharedPtr<UpdateBuffer> buf,
+ uint64_t subject,
+ URIInt key,
+ const Raul::Atom& value);
+
+uint32_t
+read_set(SharedPtr<UpdateBuffer> buf,
+ uint64_t* subject,
+ URIInt* key,
+ Raul::Atom* value);
+
+} // namespace Machina
+
+#endif // MACHINA_UPDATES_HPP