summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-04-11 03:46:40 +0000
committerDavid Robillard <d@drobilla.net>2007-04-11 03:46:40 +0000
commit72a21b5dbe82ac726f4d7a4308601d802001d9c0 (patch)
tree2d10c530c7dd278898db65a56e0a56754d73660d
parentfa10838af240f0457097051eb2e4153772a44386 (diff)
downloadingen-72a21b5dbe82ac726f4d7a4308601d802001d9c0.tar.gz
ingen-72a21b5dbe82ac726f4d7a4308601d802001d9c0.tar.bz2
ingen-72a21b5dbe82ac726f4d7a4308601d802001d9c0.zip
Serialization (both saving and restoring) of nested patches.
Serialization of patch (float) metadata. Removed useless cruft from Save dialog. Remember filename on save to avoid save as next time. git-svn-id: http://svn.drobilla.net/lad/ingen@437 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/libs/client/Loader.cpp150
-rw-r--r--src/libs/client/PatchModel.h2
-rw-r--r--src/libs/client/Serializer.cpp83
-rw-r--r--src/libs/client/Serializer.h14
-rw-r--r--src/libs/engine/events/ConnectionEvent.cpp14
-rw-r--r--src/libs/engine/events/ConnectionEvent.h1
-rw-r--r--src/progs/ingenuity/PatchWindow.cpp13
7 files changed, 198 insertions, 79 deletions
diff --git a/src/libs/client/Loader.cpp b/src/libs/client/Loader.cpp
index 70ef0820..09724d6c 100644
--- a/src/libs/client/Loader.cpp
+++ b/src/libs/client/Loader.cpp
@@ -16,6 +16,7 @@
*/
#include <iostream>
+#include <glibmm/ustring.h>
#include <raptor.h>
#include "raul/RDFQuery.h"
#include "Loader.h"
@@ -63,11 +64,10 @@ Loader::load(const Glib::ustring& filename,
Glib::ustring document_uri = (const char*)document_uri_str;
//Glib::ustring document_uri = "file:///home/dave/code/drobillanet/ingen/src/progs/ingenuity/test2.ingen.ttl";
- if (patch_uri == "")
- patch_uri = "<>"; // FIXME: Will load every patch in the file?
+ patch_uri = string("<") + patch_uri + ">";
cerr << "[Loader] Loading " << patch_uri << " from " << document_uri
- << " under " << parent << endl;
+ << " under " << (string)(parent ? (string)parent.get() : "no parent") << endl;
/* Get polyphony (mandatory) */
@@ -106,11 +106,12 @@ Loader::load(const Glib::ustring& filename,
}
Path patch_path = ( parent ? (parent.get().base() + patch_name) : Path("/") );
- cerr << "************ PATCH: " << patch_path << ", poly = " << patch_poly << endl;
+ cerr << "************ PATCH: name=" << patch_name << ", path=" << patch_path
+ << ", poly = " << patch_poly << endl;
_engine->create_patch(patch_path, patch_poly);
- /* Load nodes */
+ /* Load (plugin) nodes */
query = RDFQuery(*_namespaces, Glib::ustring(
"SELECT DISTINCT ?name ?plugin ?floatkey ?floatval FROM <") + document_uri + "> WHERE {\n" +
@@ -135,8 +136,8 @@ Loader::load(const Glib::ustring& filename,
created[node_path] = true;
}
- Glib::ustring floatkey = _namespaces->qualify((*i)["floatkey"]);
- Glib::ustring floatval = (*i)["floatval"];
+ const Glib::ustring& floatkey = _namespaces->qualify((*i)["floatkey"]);
+ const Glib::ustring& floatval = (*i)["floatval"];
if (floatkey != "" && floatval != "") {
const float val = atof(floatval.c_str());
@@ -144,6 +145,31 @@ Loader::load(const Glib::ustring& filename,
}
}
+
+ /* Load subpatches */
+
+ query = RDFQuery(*_namespaces, Glib::ustring(
+ "SELECT DISTINCT ?patch ?name FROM <") + document_uri + "> WHERE {\n" +
+ patch_uri + " ingen:node ?patch .\n"
+ "?patch a ingen:Patch ;\n"
+ " ingen:name ?name .\n"
+ "}");
+
+ results = query.run(document_uri);
+
+ for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) {
+
+ const Glib::ustring& name = (*i)["name"];
+ const Glib::ustring& patch = (*i)["patch"];
+
+ const Path subpatch_path = patch_path.base() + (string)name;
+
+ if (created.find(subpatch_path) == created.end()) {
+ load(filename, patch_path, name, patch);
+ created[subpatch_path] = true;
+ }
+ }
+
created.clear();
@@ -225,39 +251,111 @@ Loader::load(const Glib::ustring& filename,
created.clear();
- /* Load connections */
+ /* Node -> Node connections */
+
+ query = RDFQuery(*_namespaces, Glib::ustring(
+ "SELECT DISTINCT ?srcnodename ?srcname ?dstnodename ?dstname FROM <") + document_uri + "> WHERE {\n" +
+ patch_uri + " ingen:node ?srcnode ;\n"
+ " ingen:node ?dstnode .\n"
+ "?srcnode ingen:port ?src ;\n"
+ " ingen:name ?srcnodename .\n" +
+ "?dstnode ingen:port ?dst ;\n"
+ " ingen:name ?dstnodename .\n"
+ "?src ingen:name ?srcname .\n"
+ "?dst ingen:connectedTo ?src ;\n"
+ " ingen:name ?dstname .\n"
+ "}\n");
+
+ results = query.run(document_uri);
+
+ for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ Path src_node = patch_path.base() + string((*i)["srcnodename"]);
+ Path src_port = src_node.base() + string((*i)["srcname"]);
+ Path dst_node = patch_path.base() + string((*i)["dstnodename"]);
+ Path dst_port = dst_node.base() + string((*i)["dstname"]);
+
+ cerr << patch_path << " 1 CONNECTION: " << src_port << " -> " << dst_port << endl;
+
+ _engine->connect(src_port, dst_port);
+ }
+
+
+ /* This Patch -> Node connections */
+
+ query = RDFQuery(*_namespaces, Glib::ustring(
+ "SELECT DISTINCT ?srcname ?dstnodename ?dstname FROM <") + document_uri + "> WHERE {\n" +
+ patch_uri + " ingen:port ?src ;\n" +
+ " ingen:node ?dstnode .\n"
+ "?dstnode ingen:port ?dst ;\n"
+ " ingen:name ?dstnodename .\n"
+ "?dst ingen:connectedTo ?src ;\n"
+ " ingen:name ?dstname .\n"
+ "?src ingen:name ?srcname .\n"
+ "}\n");
+
+ results = query.run(document_uri);
+
+ for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ Path src_port = patch_path.base() + string((*i)["srcname"]);
+
+ Path dst_node = patch_path.base() + string((*i)["dstnodename"]);
+ Path dst_port = dst_node.base() + string((*i)["dstname"]);
+
+ cerr << patch_path << " 2 CONNECTION: " << src_port << " -> " << dst_port << endl;
+
+ _engine->connect(src_port, dst_port);
+ }
+
+
+ /* Node -> This Patch connections */
- // FIXME: path?
query = RDFQuery(*_namespaces, Glib::ustring(
- "SELECT DISTINCT ?srcnode ?src ?dstnode ?dst FROM <") + document_uri + "> WHERE {\n" +
- "?srcnoderef ingen:port ?srcref .\n"
- "?dstnoderef ingen:port ?dstref .\n"
- "?dstref ingen:connectedTo ?srcref .\n"
- "?srcref ingen:name ?src .\n"
- "?dstref ingen:name ?dst .\n"
- "OPTIONAL { ?srcnoderef ingen:name ?srcnode } .\n"
- "OPTIONAL { ?dstnoderef ingen:name ?dstnode }\n"
+ "SELECT DISTINCT ?srcnodename ?srcname ?dstname FROM <") + document_uri + "> WHERE {\n" +
+ patch_uri + " ingen:port ?dst ;\n" +
+ " ingen:node ?srcnode .\n"
+ "?srcnode ingen:port ?src ;\n"
+ " ingen:name ?srcnodename .\n"
+ "?dst ingen:connectedTo ?src ;\n"
+ " ingen:name ?dstname .\n"
+ "?src ingen:name ?srcname .\n"
"}\n");
results = query.run(document_uri);
for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) {
- Path src_node = patch_path;
- if ((*i).find("srcnode") != (*i).end())
- src_node = patch_path.base() + string((*i)["srcnode"]);
- Path src_port = src_node.base() + string((*i)["src"]);
+ Path dst_port = patch_path.base() + string((*i)["dstname"]);
- Path dst_node = patch_path;
- if ((*i).find("dstnode") != (*i).end())
- dst_node = patch_path.base() + string((*i)["dstnode"]);
- Path dst_port = dst_node.base() + string((*i)["dst"]);
+ Path src_node = patch_path.base() + string((*i)["srcnodename"]);
+ Path src_port = src_node.base() + string((*i)["srcname"]);
- //cerr << "CONNECTION: " << src_port << " -> " << dst_port << endl;
+ cerr << patch_path << " 3 CONNECTION: " << src_port << " -> " << dst_port << endl;
_engine->connect(src_port, dst_port);
}
+ /* Load metadata */
+
+ query = RDFQuery(*_namespaces, Glib::ustring(
+ "SELECT DISTINCT ?floatkey ?floatval FROM <") + document_uri + "> WHERE {\n" +
+ patch_uri + " ?floatkey ?floatval . \n"
+ " FILTER ( datatype(?floatval) = xsd:decimal ) \n"
+ "}");
+
+ results = query.run(document_uri);
+
+ for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) {
+
+ const Glib::ustring& floatkey = _namespaces->qualify((*i)["floatkey"]);
+ const Glib::ustring& floatval = (*i)["floatval"];
+
+ if (floatkey != "" && floatval != "") {
+ const float val = atof(floatval.c_str());
+ _engine->set_metadata(patch_path, floatkey, Atom(val));
+ }
+ }
+
+
// Set passed metadata last to override any loaded values
for (MetadataMap::const_iterator i = data.begin(); i != data.end(); ++i)
_engine->set_metadata(patch_path, i->first, i->second);
diff --git a/src/libs/client/PatchModel.h b/src/libs/client/PatchModel.h
index c38d83a5..c55bce89 100644
--- a/src/libs/client/PatchModel.h
+++ b/src/libs/client/PatchModel.h
@@ -48,6 +48,8 @@ public:
SharedPtr<ConnectionModel> get_connection(const string& src_port_path, const string& dst_port_path) const;
SharedPtr<NodeModel> get_node(const string& node_name) const;
+ void set_filename(const string& filename) { _filename = filename; }
+
size_t poly() const { return _poly; }
const string& filename() const { return _filename; }
bool enabled() const { return _enabled; }
diff --git a/src/libs/client/Serializer.cpp b/src/libs/client/Serializer.cpp
index 767d86d9..1374ab12 100644
--- a/src/libs/client/Serializer.cpp
+++ b/src/libs/client/Serializer.cpp
@@ -64,6 +64,7 @@ Serializer::Serializer()
void
Serializer::start_to_filename(const string& filename) throw (std::logic_error)
{
+ _base_uri = "file://" + filename;
_writer.start_to_filename(filename);
}
@@ -78,6 +79,7 @@ Serializer::start_to_filename(const string& filename) throw (std::logic_error)
void
Serializer::start_to_string() throw (std::logic_error)
{
+ _base_uri = "";
_writer.start_to_string();
}
@@ -91,6 +93,7 @@ string
Serializer::finish() throw(std::logic_error)
{
return _writer.finish();
+ _id_map.clear();
}
@@ -99,7 +102,7 @@ Serializer::finish() throw(std::logic_error)
RdfId
Serializer::path_to_node_id(const Path& path)
{
- string ret = path.substr(1);
+ /*string ret = path.substr(1);
for (size_t i=0; i < ret.length(); ++i) {
if (ret[i] == '/')
@@ -107,8 +110,19 @@ Serializer::path_to_node_id(const Path& path)
}
return RdfId(RdfId::ANONYMOUS, ret);
+ */
+
+ IDMap::iterator i = _id_map.find(path);
+ if (i != _id_map.end()) {
+ return i->second;
+ } else {
+ const RdfId id = _writer.blank_id();
+ _id_map[path] = id;
+ return id;
+ }
}
+
#if 0
/** Searches for the filename passed in the path, returning the full
* path of the file, or the empty string if not found.
@@ -166,23 +180,21 @@ Serializer::serialize(SharedPtr<ObjectModel> object) throw (std::logic_error)
if (!_writer.serialization_in_progress())
throw std::logic_error("serialize called without serialization in progress");
- // FIXME: depth
-
SharedPtr<PatchModel> patch = PtrCast<PatchModel>(object);
if (patch) {
- serialize_patch(patch, 0);
+ serialize_patch(patch, RdfId(RdfId::RESOURCE, _base_uri));
return;
}
SharedPtr<NodeModel> node = PtrCast<NodeModel>(object);
if (node) {
- serialize_node(node, 0);
+ serialize_node(node, path_to_node_id(node->path()));
return;
}
SharedPtr<PortModel> port = PtrCast<PortModel>(object);
if (port) {
- serialize_port(port, 0);
+ serialize_port(port, path_to_node_id(port->path()));
return;
}
@@ -192,15 +204,8 @@ Serializer::serialize(SharedPtr<ObjectModel> object) throw (std::logic_error)
void
-Serializer::serialize_patch(SharedPtr<PatchModel> patch, unsigned depth)
+Serializer::serialize_patch(SharedPtr<PatchModel> patch, const RdfId& patch_id)
{
- RdfId patch_id = path_to_node_id(patch->path()); // anonymous
-
- if (patch->path().length() < 2)
- patch_id = RdfId(RdfId::RESOURCE, string(""));
- else if (depth == 0)
- patch_id = RdfId(RdfId::RESOURCE, string("#") + patch->path().substr(1));
-
_writer.write(
patch_id,
NS_RDF("type"),
@@ -218,23 +223,37 @@ Serializer::serialize_patch(SharedPtr<PatchModel> patch, unsigned depth)
Atom((int)patch->poly()));
for (NodeModelMap::const_iterator n = patch->nodes().begin(); n != patch->nodes().end(); ++n) {
- _writer.write(patch_id, NS_INGEN("node"), path_to_node_id(n->second->path()));
SharedPtr<PatchModel> patch = PtrCast<PatchModel>(n->second);
- if (patch)
- serialize_patch(patch, depth+1);
- else
- serialize_node(n->second, depth+1);
+ if (patch) {
+ const RdfId subpatch_id = RdfId(RdfId::RESOURCE,
+ patch_id.to_string() + "#" + patch->path().substr(1));
+ _writer.write(patch_id, NS_INGEN("node"), subpatch_id);
+ serialize_patch(patch, subpatch_id);
+ } else {
+ const RdfId node_id = path_to_node_id(n->second->path());
+ _writer.write(patch_id, NS_INGEN("node"), node_id);
+ serialize_node(n->second, node_id);
+ }
}
for (PortModelList::const_iterator p = patch->ports().begin(); p != patch->ports().end(); ++p) {
- _writer.write(patch_id, NS_INGEN("port"), path_to_node_id((*p)->path()));
- serialize_port(*p, depth+1);
-
+ const RdfId port_id = path_to_node_id((*p)->path());
+ _writer.write(patch_id, NS_INGEN("port"), port_id);
+ serialize_port(*p, port_id);
}
for (ConnectionList::const_iterator c = patch->connections().begin(); c != patch->connections().end(); ++c) {
serialize_connection(*c);
}
+
+ for (MetadataMap::const_iterator m = patch->metadata().begin(); m != patch->metadata().end(); ++m) {
+ if (_writer.expand_uri(m->first) != "") {
+ _writer.write(
+ patch_id,
+ RdfId(RdfId::RESOURCE, _writer.expand_uri(m->first.c_str()).c_str()),
+ m->second);
+ }
+ }
}
@@ -251,12 +270,8 @@ Serializer::serialize_plugin(SharedPtr<PluginModel> plugin)
void
-Serializer::serialize_node(SharedPtr<NodeModel> node, unsigned depth)
+Serializer::serialize_node(SharedPtr<NodeModel> node, const RdfId& node_id)
{
- const RdfId node_id = (depth == 0)
- ? RdfId(RdfId::RESOURCE, string("#") + node->path().substr(1))
- : path_to_node_id(node->path()); // anonymous
-
const RdfId plugin_id = RdfId(RdfId::RESOURCE, node->plugin()->uri());
_writer.write(
@@ -282,8 +297,9 @@ Serializer::serialize_node(SharedPtr<NodeModel> node, unsigned depth)
Atom(node->path().name()));*/
for (PortModelList::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) {
- serialize_port(*p, depth+1);
- _writer.write(node_id, NS_INGEN("port"), path_to_node_id((*p)->path()));
+ const RdfId port_id = path_to_node_id((*p)->path());
+ serialize_port(*p, port_id);
+ _writer.write(node_id, NS_INGEN("port"), port_id);
}
for (MetadataMap::const_iterator m = node->metadata().begin(); m != node->metadata().end(); ++m) {
@@ -301,12 +317,8 @@ Serializer::serialize_node(SharedPtr<NodeModel> node, unsigned depth)
* Audio output ports with no metadata will not be written, for example.
*/
void
-Serializer::serialize_port(SharedPtr<PortModel> port, unsigned depth)
+Serializer::serialize_port(SharedPtr<PortModel> port, const RdfId& port_id)
{
- const RdfId port_id = (depth == 0)
- ? RdfId(RdfId::RESOURCE, string("#") + port->path().substr(1))
- : path_to_node_id(port->path()); // anonymous
-
if (port->is_input())
_writer.write(port_id, NS_RDF("type"), NS_INGEN("InputPort"));
else
@@ -355,7 +367,7 @@ Serializer::serialize_connection(SharedPtr<ConnectionModel> connection) throw (s
*/
}
-
+#if 0
/** Load a patch into the engine (e.g. from a patch file).
*
* @param base_uri Base URI (e.g. URI of the file to load from).
@@ -522,6 +534,7 @@ Serializer::load_patch(bool merge,
#endif
return "/FIXME";
}
+#endif
} // namespace Client
} // namespace Ingen
diff --git a/src/libs/client/Serializer.h b/src/libs/client/Serializer.h
index 8d81b149..45407e52 100644
--- a/src/libs/client/Serializer.h
+++ b/src/libs/client/Serializer.h
@@ -33,6 +33,7 @@
using std::string;
using boost::optional;
+using Raul::RdfId;
namespace Ingen {
namespace Client {
@@ -65,14 +66,14 @@ public:
//string find_file(const string& filename, const string& additional_path = "");
- bool load_patch(bool merge,
+ /*bool load_patch(bool merge,
const string& data_base_uri,
const Path& data_path,
MetadataMap engine_data,
optional<const Path&> engine_parent = optional<const Path&>(),
optional<const string&> engine_name = optional<const string&>(),
optional<size_t> engine_poly = optional<size_t>());
-
+ */
void start_to_filename(const string& filename) throw (std::logic_error);
void start_to_string() throw (std::logic_error);
@@ -84,12 +85,15 @@ private:
void serialize_plugin(SharedPtr<PluginModel> p);
- void serialize_patch(SharedPtr<PatchModel> p, unsigned depth);
- void serialize_node(SharedPtr<NodeModel> n, unsigned depth);
- void serialize_port(SharedPtr<PortModel> p, unsigned depth);
+ void serialize_patch(SharedPtr<PatchModel> p, const Raul::RdfId& id);
+ void serialize_node(SharedPtr<NodeModel> n, const Raul::RdfId& id);
+ void serialize_port(SharedPtr<PortModel> p, const Raul::RdfId& id);
Raul::RdfId path_to_node_id(const Path& path);
+ typedef std::map<Path, RdfId> IDMap;
+ IDMap _id_map;
+ string _base_uri;
Raul::RDFWriter _writer;
};
diff --git a/src/libs/engine/events/ConnectionEvent.cpp b/src/libs/engine/events/ConnectionEvent.cpp
index af35265b..7c4b4422 100644
--- a/src/libs/engine/events/ConnectionEvent.cpp
+++ b/src/libs/engine/events/ConnectionEvent.cpp
@@ -84,16 +84,14 @@ ConnectionEvent::pre_process()
return;
}
- /*if ( !( _src_port->is_output() && _dst_port->is_input() ) ) {
- _error = TYPE_MISMATCH;
- QueuedEvent::pre_process();
- return;
- }*/
-
_dst_input_port = dynamic_cast<InputPort*>(_dst_port);
_src_output_port = dynamic_cast<OutputPort*>(_src_port);
- assert(_src_output_port);
- assert(_dst_input_port);
+
+ if (!_dst_input_port || !_src_output_port) {
+ _error = DIRECTION_MISMATCH;
+ QueuedEvent::pre_process();
+ return;
+ }
if (_dst_input_port->is_connected_to(_src_output_port)) {
_error = ALREADY_CONNECTED;
diff --git a/src/libs/engine/events/ConnectionEvent.h b/src/libs/engine/events/ConnectionEvent.h
index 8f5e1cc2..bebb6cfd 100644
--- a/src/libs/engine/events/ConnectionEvent.h
+++ b/src/libs/engine/events/ConnectionEvent.h
@@ -61,6 +61,7 @@ private:
PARENT_PATCH_DIFFERENT,
PORT_NOT_FOUND,
TYPE_MISMATCH,
+ DIRECTION_MISMATCH,
ALREADY_CONNECTED,
PARENTS_NOT_FOUND
};
diff --git a/src/progs/ingenuity/PatchWindow.cpp b/src/progs/ingenuity/PatchWindow.cpp
index 22305247..ddcccf10 100644
--- a/src/progs/ingenuity/PatchWindow.cpp
+++ b/src/progs/ingenuity/PatchWindow.cpp
@@ -267,16 +267,18 @@ PatchWindow::event_save_as()
{
Gtk::FileChooserDialog dialog(*this, "Save Patch", Gtk::FILE_CHOOSER_ACTION_SAVE);
- Gtk::VBox* box = dialog.get_vbox();
+ /*Gtk::VBox* box = dialog.get_vbox();
Gtk::Label warning("Warning: Recursively saving will overwrite any subpatch files \
without confirmation.");
box->pack_start(warning, false, false, 2);
Gtk::CheckButton recursive_checkbutton("Recursively save all subpatches");
box->pack_start(recursive_checkbutton, false, false, 0);
recursive_checkbutton.show();
+ */
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
- dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
+ Gtk::Button* save_button = dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
+ save_button->property_has_default() = true;
// Set current folder to most sensible default
const string& current_filename = _patch->filename();
@@ -286,7 +288,7 @@ PatchWindow::event_save_as()
dialog.set_current_folder(App::instance().configuration()->patch_folder());
int result = dialog.run();
- bool recursive = recursive_checkbutton.get_active();
+ //bool recursive = recursive_checkbutton.get_active();
assert(result == Gtk::RESPONSE_OK || result == Gtk::RESPONSE_CANCEL || result == Gtk::RESPONSE_NONE);
@@ -313,8 +315,9 @@ PatchWindow::event_save_as()
fin.close();
if (confirm) {
- App::instance().loader()->save_patch(_patch, filename, recursive);
- //m_patch->set_metadata("filename", Atom(filename.c_str()));
+ App::instance().loader()->save_patch(_patch, filename, true);
+ _patch->set_filename(filename);
+ //_patch->set_metadata("filename", Atom(filename.c_str()));
}
}
App::instance().configuration()->set_patch_folder(dialog.get_current_folder());