From d5e8ce8127784fc67953ab3b6247e911be697cc2 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 9 Dec 2006 07:43:15 +0000 Subject: Preliminary patch loading (just loads nodes from RDF). git-svn-id: http://svn.drobilla.net/lad/ingen@214 a436a847-0d15-0410-975c-d299462d15a1 --- configure.ac | 5 +- src/libs/client/Loader.cpp | 57 +++++++++++++++ src/libs/client/Loader.h | 48 ++++++++++++ src/libs/client/Makefile.am | 8 +- src/libs/client/PluginModel.h | 8 +- src/libs/client/RDFQuery.cpp | 66 +++++++++++++++++ src/libs/client/RDFQuery.h | 60 +++++++++++++++ src/libs/client/RDFWriter.cpp | 4 +- src/libs/client/Serializer.cpp | 44 +++++++---- src/libs/client/Serializer.h | 24 +++--- src/progs/ingenuity/App.cpp | 4 +- src/progs/ingenuity/App.h | 8 +- src/progs/ingenuity/LoadPatchWindow.cpp | 6 +- src/progs/ingenuity/LoadSubpatchWindow.cpp | 8 +- src/progs/ingenuity/Loader.cpp | 106 --------------------------- src/progs/ingenuity/Loader.h | 92 ----------------------- src/progs/ingenuity/Makefile.am | 4 +- src/progs/ingenuity/PatchCanvas.cpp | 2 +- src/progs/ingenuity/PatchWindow.cpp | 6 +- src/progs/ingenuity/ThreadedLoader.cpp | 113 +++++++++++++++++++++++++++++ src/progs/ingenuity/ThreadedLoader.h | 95 ++++++++++++++++++++++++ src/progs/patch_loader/patch_loader.cpp | 4 +- 22 files changed, 518 insertions(+), 254 deletions(-) create mode 100644 src/libs/client/Loader.cpp create mode 100644 src/libs/client/Loader.h create mode 100644 src/libs/client/RDFQuery.cpp create mode 100644 src/libs/client/RDFQuery.h delete mode 100644 src/progs/ingenuity/Loader.cpp delete mode 100644 src/progs/ingenuity/Loader.h create mode 100644 src/progs/ingenuity/ThreadedLoader.cpp create mode 100644 src/progs/ingenuity/ThreadedLoader.h diff --git a/configure.ac b/configure.ac index a446201a..3e79663f 100644 --- a/configure.ac +++ b/configure.ac @@ -306,11 +306,14 @@ if test "$build_console_clients" = "yes"; then # Check for libxml2 # FIXME: deprecated, make optional PKG_CHECK_MODULES(LXML2, libxml-2.0 >= 2.6.0) + # Check for glibmm + PKG_CHECK_MODULES(GLIBMM, glibmm-2.4) + # Check for raptor (for RDF serialization) PKG_CHECK_MODULES(RAPTOR, raptor >= 0.21, build_raptor="yes", build_raptor="no") # Check for rasqal (for RDF querying) - #PKG_CHECK_MODULES(RASQAL, rasqal >= 0.9.11, build_rasqal="yes", build_rasqal="no") + PKG_CHECK_MODULES(RASQAL, rasqal >= 0.9.11, build_rasqal="yes", build_rasqal="no") # Check for sigc++ (FIXME: make this only necessary where.. uh.. necessary) PKG_CHECK_MODULES(LSIGCPP, sigc++-2.0) diff --git a/src/libs/client/Loader.cpp b/src/libs/client/Loader.cpp new file mode 100644 index 00000000..7816e88a --- /dev/null +++ b/src/libs/client/Loader.cpp @@ -0,0 +1,57 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * 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 +#include "Loader.h" +#include "RDFQuery.h" +#include "ModelEngineInterface.h" + +namespace Ingen { +namespace Client { + + +Loader::Loader(SharedPtr engine) + : _engine(engine) +{ +} + + +/** Load (create) all objects from an RDF into the engine. + * + * @param filename Filename to load objects from. + * @param parent Path of parent under which to load objects. + * @return whether or not load was successful. + */ +void +Loader::load(const Glib::ustring& filename, + const Path& parent) +{ + RDFQuery query(Glib::ustring("SELECT DISTINCT ?name ?plugin FROM <") + filename + "> WHERE {\n" + + "?patch ingen:node ?node .\n" + + "?node ingen:name ?name ;\n" + + " ingen:plugin ?plugin .\n" + + "}"); + + RDFQuery::Results nodes = query.run(filename); + + for (RDFQuery::Results::iterator i = nodes.begin(); i != nodes.end(); ++i) + _engine->create_node(parent.base() + (*i)["name"], (*i)["plugin"], false); +} + + +} // namespace Client +} // namespace Ingen + diff --git a/src/libs/client/Loader.h b/src/libs/client/Loader.h new file mode 100644 index 00000000..5fd31d52 --- /dev/null +++ b/src/libs/client/Loader.h @@ -0,0 +1,48 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * 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 LOADER_H +#define LOADER_H + +#include +#include "raul/SharedPtr.h" +#include "raul/Path.h" + +namespace Ingen { +namespace Client { + +class ModelEngineInterface; + + +/** Loads objects (patches, nodes, etc) into the engine from RDF. + */ +class Loader { +public: + Loader(SharedPtr engine); + + void load(const Glib::ustring& filename, + const Path& parent); + +private: + //string _patch_search_path; + SharedPtr _engine; +}; + + +} // namespace Client +} // namespace Ingen + +#endif // LOADER_H diff --git a/src/libs/client/Makefile.am b/src/libs/client/Makefile.am index cde46fbd..48811414 100644 --- a/src/libs/client/Makefile.am +++ b/src/libs/client/Makefile.am @@ -3,8 +3,8 @@ AM_CXXFLAGS = -I$(top_srcdir)/src/common if BUILD_CLIENT_LIB noinst_LTLIBRARIES = libingenclient.la -libingenclient_la_CXXFLAGS = -I$(top_srcdir)/src/common -DPKGDATADIR=\"$(pkgdatadir)\" @LXML2_CFLAGS@ @RAPTOR_CFLAGS@ @LSIGCPP_CFLAGS@ @RAUL_CFLAGS@ -libingenclient_la_LIBADD = @LXML2_LIBS@ @LOSC_LIBS@ @RAPTOR_LIBS@ @LSIGCPP_LIBS@ @RAUL_LIBS@ +libingenclient_la_CXXFLAGS = -I$(top_srcdir)/src/common -DPKGDATADIR=\"$(pkgdatadir)\" @LXML2_CFLAGS@ @RAPTOR_CFLAGS@ @LSIGCPP_CFLAGS@ @RAUL_CFLAGS@ @GLIBMM_CFLAGS@ +libingenclient_la_LIBADD = @LXML2_LIBS@ @LOSC_LIBS@ @RAPTOR_LIBS@ @LSIGCPP_LIBS@ @RAUL_LIBS@ @GLIBMM_LIBS@ libingenclient_la_SOURCES = \ OSCEngineSender.h \ @@ -30,8 +30,12 @@ libingenclient_la_SOURCES = \ PluginModel.h \ RDFWriter.h \ RDFWriter.cpp \ + RDFQuery.h \ + RDFQuery.cpp \ Serializer.h \ Serializer.cpp \ + Loader.h \ + Loader.cpp \ DeprecatedSerializer.h \ DeprecatedSerializer.cpp \ ConnectionModel.h \ diff --git a/src/libs/client/PluginModel.h b/src/libs/client/PluginModel.h index 76edc737..7af4f169 100644 --- a/src/libs/client/PluginModel.h +++ b/src/libs/client/PluginModel.h @@ -59,10 +59,10 @@ public: }*/ const char* const type_uri() const { - if (m_type == LV2) return "ingen:LV2"; - else if (m_type == LADSPA) return "ingen:LADSPA"; - else if (m_type == DSSI) return "ingen:DSSI"; - else if (m_type == Internal) return "ingen:Internal"; + if (m_type == LV2) return "ingen:LV2Plugin"; + else if (m_type == LADSPA) return "ingen:LADSPAPlugin"; + else if (m_type == DSSI) return "ingen:DSSIPlugin"; + else if (m_type == Internal) return "ingen:InternalPlugin"; else if (m_type == Patch) return "ingen:Patch"; else return ""; } diff --git a/src/libs/client/RDFQuery.cpp b/src/libs/client/RDFQuery.cpp new file mode 100644 index 00000000..8e08848a --- /dev/null +++ b/src/libs/client/RDFQuery.cpp @@ -0,0 +1,66 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * 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 +#include +#include +#include "RDFQuery.h" + +namespace Ingen { +namespace Client { + + +RDFQuery::Results +RDFQuery::run(const Glib::ustring filename) +{ + Results result; + + rasqal_init(); + + rasqal_query *rq = rasqal_new_query("sparql", NULL); + + rasqal_query_prepare(rq, (unsigned char*)_query.c_str(), NULL); + rasqal_query_results* results = rasqal_query_execute(rq); + assert(results); + + while (!rasqal_query_results_finished(results)) { + + Bindings bindings; + + for (int i=0; i < rasqal_query_results_get_bindings_count(results); i++) { + const unsigned char* rname = rasqal_query_results_get_binding_name(results, i); + rasqal_literal* rvalue = rasqal_query_results_get_binding_value(results, i); + + Glib::ustring name((const char*)rname); + Glib::ustring value((const char*)rasqal_literal_as_string(rvalue)); + + bindings.insert(std::make_pair(name, value)); + } + + result.push_back(bindings); + rasqal_query_results_next(results); + } + + rasqal_free_query_results(results); + rasqal_free_query(rq); + rasqal_finish(); + + return result; +} + + +} // namespace Client +} // namespace Ingen diff --git a/src/libs/client/RDFQuery.h b/src/libs/client/RDFQuery.h new file mode 100644 index 00000000..3e7a1521 --- /dev/null +++ b/src/libs/client/RDFQuery.h @@ -0,0 +1,60 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * 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 RDFQUERY_H +#define RDFQUERY_H + +#include +#include +#include + +namespace Ingen { +namespace Client { + + +/** Pretty wrapper for a SPARQL query. + * + * Automatically handles things like prepending prefixes, etc. Ingen specific. + */ +class RDFQuery { +public: + typedef std::map Bindings; + typedef std::list Results; + + RDFQuery(Glib::ustring query) + { + const char* const _prefix_header = + "PREFIX ingen: \n" + "PREFIX lv2: \n"; + + _query = _prefix_header + query; + } + + Results run(const Glib::ustring filename); + + Glib::ustring string() { return _query; } + +private: + + Glib::ustring _query; +}; + + +} // namespace Client +} // namespace Ingen + +#endif // RDFQUERY_H + diff --git a/src/libs/client/RDFWriter.cpp b/src/libs/client/RDFWriter.cpp index e1762ed2..649c8a1a 100644 --- a/src/libs/client/RDFWriter.cpp +++ b/src/libs/client/RDFWriter.cpp @@ -19,8 +19,8 @@ #define U(x) ((const unsigned char*)(x)) -static const char* const RDF_LANG = "rdfxml-abbrev"; -//static const char* const RDF_LANG = "turtle"; +//static const char* const RDF_LANG = "rdfxml-abbrev"; +static const char* const RDF_LANG = "turtle"; RDFWriter::RDFWriter() diff --git a/src/libs/client/Serializer.cpp b/src/libs/client/Serializer.cpp index 3984a49a..b8929546 100644 --- a/src/libs/client/Serializer.cpp +++ b/src/libs/client/Serializer.cpp @@ -47,18 +47,6 @@ namespace Ingen { namespace Client { -Serializer::Serializer(SharedPtr engine) - : _patch_search_path(".") - , _engine(engine) -{ -} - - -Serializer::~Serializer() -{ -} - - /** Begin a serialization to a file. * * This must be called before any serializing methods. @@ -111,7 +99,7 @@ Serializer::path_to_node_id(const Path& path) return RdfId(RdfId::ANONYMOUS, ret); } - +#if 0 /** Searches for the filename passed in the path, returning the full * path of the file, or the empty string if not found. * @@ -160,7 +148,7 @@ Serializer::find_file(const string& filename, const string& additional_path) return ""; } - +#endif void Serializer::serialize(SharedPtr object) throw (std::logic_error) @@ -235,8 +223,18 @@ Serializer::serialize_patch(SharedPtr patch, unsigned depth) for (ConnectionList::const_iterator c = patch->connections().begin(); c != patch->connections().end(); ++c) { serialize_connection(*c); } - - //_engine->set_metadata(patch->path(), "uri", uri); +} + + +void +Serializer::serialize_plugin(SharedPtr plugin) +{ + const RdfId plugin_id = RdfId(RdfId::RESOURCE, plugin->uri()); + + _writer.write( + plugin_id, + NS_RDF("type"), + RdfId(RdfId::RESOURCE, plugin->type_uri())); } @@ -249,11 +247,25 @@ Serializer::serialize_node(SharedPtr node, unsigned depth) ? 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( node_id, NS_RDF("type"), NS_INGEN("Node")); + _writer.write( + node_id, + NS_INGEN("name"), + node->path().name()); + + _writer.write( + node_id, + NS_INGEN("plugin"), + plugin_id); + + //serialize_plugin(node->plugin()); + /*_writer.write(_serializer, node_uri_ref.c_str(), NS_INGEN("name"), diff --git a/src/libs/client/Serializer.h b/src/libs/client/Serializer.h index 5fe00199..8ae18313 100644 --- a/src/libs/client/Serializer.h +++ b/src/libs/client/Serializer.h @@ -14,8 +14,8 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef PATCHLIBRARIAN_H -#define PATCHLIBRARIAN_H +#ifndef SERIALIZER_H +#define SERIALIZER_H #include #include @@ -36,6 +36,7 @@ using boost::optional; namespace Ingen { namespace Client { +class PluginModel; class PatchModel; class NodeModel; class PortModel; @@ -49,20 +50,17 @@ class ModelEngineInterface; #define NS_INGEN(x) RdfId(RdfId::RESOURCE, "http://codeson.net/ns/ingen#" x) -/** Handles all patch saving and loading. +/** Serializes Ingen objects (patches, nodes, etc) to RDF. * * \ingroup IngenClient */ class Serializer { public: - Serializer(SharedPtr engine); - ~Serializer(); - - void path(const string& path) { _patch_search_path = path; } - const string& path() { return _patch_search_path; } + //void path(const string& path) { _patch_search_path = path; } + //const string& path() { return _patch_search_path; } - string find_file(const string& filename, const string& additional_path = ""); + //string find_file(const string& filename, const string& additional_path = ""); bool load_patch(bool merge, const string& data_base_uri, @@ -81,19 +79,19 @@ public: private: + void serialize_plugin(SharedPtr p); + void serialize_patch(SharedPtr p, unsigned depth); void serialize_node(SharedPtr n, unsigned depth); void serialize_port(SharedPtr p, unsigned depth); RdfId path_to_node_id(const Path& path); - RDFWriter _writer; - string _patch_search_path; - SharedPtr _engine; + RDFWriter _writer; }; } // namespace Client } // namespace Ingen -#endif // PATCHLIBRARIAN_H +#endif // SERIALIZER_H diff --git a/src/progs/ingenuity/App.cpp b/src/progs/ingenuity/App.cpp index 4e58a9dd..6470a807 100644 --- a/src/progs/ingenuity/App.cpp +++ b/src/progs/ingenuity/App.cpp @@ -37,7 +37,7 @@ #include "Configuration.h" #include "ConnectWindow.h" #include "Store.h" -#include "Loader.h" +#include "ThreadedLoader.h" #include "WindowFactory.h" #ifdef HAVE_LASH #include "LashController.h" @@ -100,7 +100,7 @@ App::attach(const SharedPtr& engine, const SharedPtrinit(*_store); } diff --git a/src/progs/ingenuity/App.h b/src/progs/ingenuity/App.h index 282958b9..213b572d 100644 --- a/src/progs/ingenuity/App.h +++ b/src/progs/ingenuity/App.h @@ -54,7 +54,7 @@ class PatchTreeView; class PatchTreeWindow; class ConnectWindow; class Configuration; -class Loader; +class ThreadedLoader; class WindowFactory; @@ -90,7 +90,7 @@ public: PatchTreeWindow* patch_tree() const { return _patch_tree_window; } Configuration* configuration() const { return _configuration; } Store* store() const { return _store; } - Loader* loader() const { return _loader; } + ThreadedLoader* loader() const { return _loader; } WindowFactory* window_factory() const { return _window_factory; } const SharedPtr& engine() const { return _engine; } @@ -106,8 +106,8 @@ protected: SharedPtr _engine; SharedPtr _client; - Store* _store; - Loader* _loader; + Store* _store; + ThreadedLoader* _loader; Configuration* _configuration; diff --git a/src/progs/ingenuity/LoadPatchWindow.cpp b/src/progs/ingenuity/LoadPatchWindow.cpp index b3e3068b..0588c6b1 100644 --- a/src/progs/ingenuity/LoadPatchWindow.cpp +++ b/src/progs/ingenuity/LoadPatchWindow.cpp @@ -22,7 +22,7 @@ #include "Configuration.h" #include "PatchModel.h" #include "ModelEngineInterface.h" -#include "Loader.h" +#include "ThreadedLoader.h" using boost::optional; @@ -50,7 +50,9 @@ LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr #include #include +#include #include "App.h" #include "PatchView.h" #include "NodeModel.h" #include "PatchModel.h" #include "Configuration.h" #include "ModelEngineInterface.h" -#include "Loader.h" +#include "ThreadedLoader.h" +using boost::optional; namespace Ingenuity { @@ -52,7 +54,9 @@ LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefP Gtk::FileFilter filt; filt.add_pattern("*.om"); - filt.set_name("Om patch files (*.om)"); + filt.set_name("Om patch files (DEPRECATED) (*.om)"); + filt.add_pattern("*.ingen.ttl"); + filt.set_name("Ingen patch files (*.ingen.ttl)"); set_filter(filt); // Add global examples directory to "shortcut folders" (bookmarks) diff --git a/src/progs/ingenuity/Loader.cpp b/src/progs/ingenuity/Loader.cpp deleted file mode 100644 index 89245dff..00000000 --- a/src/progs/ingenuity/Loader.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. - * - * 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 "Loader.h" -#include -#include -#include -#include "Serializer.h" -#include "PatchModel.h" -using std::cout; using std::endl; - -namespace Ingenuity { - - -Loader::Loader(SharedPtr engine) -: _serializer(new Serializer(engine)) -{ - assert(_serializer != NULL); - - // FIXME: rework this so the thread is only present when it's doing something (save mem) - start(); -} - - -Loader::~Loader() -{ - delete _serializer; -} - - -void -Loader::_whipped() -{ - _mutex.lock(); - - while ( ! _events.empty() ) { - _events.front()(); - _events.pop_front(); - } - - _mutex.unlock(); -} - -void -Loader::load_patch(bool merge, - const string& data_base_uri, - const Path& data_path, - MetadataMap engine_data, - optional engine_parent, - optional engine_name, - optional engine_poly) -{ - _mutex.lock(); - - _events.push_back(sigc::hide_return(sigc::bind( - sigc::mem_fun(_serializer, &Serializer::load_patch), - merge, data_base_uri, data_path, - engine_data, engine_parent, engine_name, engine_poly))); - - _mutex.unlock(); - - whip(); -} - - -void -Loader::save_patch(SharedPtr model, const string& filename, bool recursive) -{ - _mutex.lock(); - - _events.push_back(sigc::hide_return(sigc::bind( - sigc::mem_fun(this, &Loader::save_patch_event), - model, filename, recursive))); - - _mutex.unlock(); - - whip(); -} - - -void -Loader::save_patch_event(SharedPtr model, const string& filename, bool recursive) -{ - if (recursive) - cerr << "FIXME: Recursive save." << endl; - - _serializer->start_to_filename(filename); - _serializer->serialize(model); - _serializer->finish(); -} - - -} // namespace Ingenuity diff --git a/src/progs/ingenuity/Loader.h b/src/progs/ingenuity/Loader.h deleted file mode 100644 index 05f97dbb..00000000 --- a/src/progs/ingenuity/Loader.h +++ /dev/null @@ -1,92 +0,0 @@ -/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. - * - * 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 LOADERTHREAD_H -#define LOADERTHREAD_H - -#include -#include -#include -#include -#include "raul/Thread.h" -#include "raul/Slave.h" -#include "raul/Mutex.h" -#include "raul/Condition.h" -#include "ModelEngineInterface.h" -#include "ObjectModel.h" -using std::string; -using std::list; -using boost::optional; - -namespace Ingen { namespace Client { - class Serializer; - class PatchModel; -} } -using namespace Ingen::Client; - -namespace Ingenuity { - - -/** Thread for loading patch files. - * - * This is a seperate thread so it can send all the loading message without - * blocking everything else, so the app can respond to the incoming events - * caused as a result of the patch loading, while the patch loads. - * - * Implemented as a slave with a list of closures (events) which processes - * all events in the (mutex protected) list each time it's whipped. - * - * \ingroup Ingenuity - */ -class Loader : public Slave -{ -public: - Loader(SharedPtr engine); - ~Loader(); - - Serializer& serializer() const { return *_serializer; } - - // FIXME: there's a pattern here.... - // (same core interface as Serializer) - - void load_patch(bool merge, - const string& data_base_uri, - const Path& data_path, - MetadataMap engine_data, - optional engine_parent = optional(), - optional engine_name = optional(), - optional engine_poly = optional()); - - void save_patch(SharedPtr model, const string& filename, bool recursive); - -private: - - void save_patch_event(SharedPtr model, const string& filename, bool recursive); - - /** Returns nothing and takes no parameters (because they have all been bound) */ - typedef sigc::slot Closure; - - void _whipped(); - - Serializer* const _serializer; - Mutex _mutex; - list _events; -}; - - -} // namespace Ingenuity - -#endif // LOADERRTHREAD_H diff --git a/src/progs/ingenuity/Makefile.am b/src/progs/ingenuity/Makefile.am index a54f00c8..898a8b83 100644 --- a/src/progs/ingenuity/Makefile.am +++ b/src/progs/ingenuity/Makefile.am @@ -82,8 +82,8 @@ ingenuity_SOURCES = \ ConfigWindow.cpp \ PatchPropertiesWindow.h \ PatchPropertiesWindow.cpp \ - Loader.h \ - Loader.cpp \ + ThreadedLoader.h \ + ThreadedLoader.cpp \ RenameWindow.h \ RenameWindow.cpp \ NodePropertiesWindow.h \ diff --git a/src/progs/ingenuity/PatchCanvas.cpp b/src/progs/ingenuity/PatchCanvas.cpp index b1de8d60..84ec274c 100644 --- a/src/progs/ingenuity/PatchCanvas.cpp +++ b/src/progs/ingenuity/PatchCanvas.cpp @@ -311,7 +311,7 @@ PatchCanvas::destroy_selection() void PatchCanvas::copy_selection() { - Serializer serializer(App::instance().engine()); + Serializer serializer; serializer.start_to_string(); for (list >::iterator m = m_selected_modules.begin(); m != m_selected_modules.end(); ++m) { diff --git a/src/progs/ingenuity/PatchWindow.cpp b/src/progs/ingenuity/PatchWindow.cpp index ef7de264..ccadb9ed 100644 --- a/src/progs/ingenuity/PatchWindow.cpp +++ b/src/progs/ingenuity/PatchWindow.cpp @@ -34,7 +34,7 @@ #include "BreadCrumbBox.h" #include "Store.h" #include "ConnectWindow.h" -#include "Loader.h" +#include "ThreadedLoader.h" #include "WindowFactory.h" #include "PatchView.h" @@ -283,8 +283,8 @@ PatchWindow::event_save_as() if (result == Gtk::RESPONSE_OK) { string filename = dialog.get_filename(); - if (filename.length() < 4 || filename.substr(filename.length()-3) != ".om") - filename += ".om"; + if (filename.length() < 11 || filename.substr(filename.length()-10) != ".ingen.ttl") + filename += ".ingen.ttl"; bool confirm = false; std::fstream fin; diff --git a/src/progs/ingenuity/ThreadedLoader.cpp b/src/progs/ingenuity/ThreadedLoader.cpp new file mode 100644 index 00000000..fbd64d3d --- /dev/null +++ b/src/progs/ingenuity/ThreadedLoader.cpp @@ -0,0 +1,113 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * 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 "ThreadedLoader.h" +#include +#include +#include +#include "Loader.h" +#include "PatchModel.h" +using std::cout; using std::endl; + +namespace Ingenuity { + + +ThreadedLoader::ThreadedLoader(SharedPtr engine) +: _loader(new Loader(engine)) +, _serializer(new Serializer()) +{ + assert(_loader != NULL); + + // FIXME: rework this so the thread is only present when it's doing something (save mem) + start(); +} + + +ThreadedLoader::~ThreadedLoader() +{ + delete _loader; +} + + +void +ThreadedLoader::_whipped() +{ + _mutex.lock(); + + while ( ! _events.empty() ) { + _events.front()(); + _events.pop_front(); + } + + _mutex.unlock(); +} + +void +ThreadedLoader::load_patch(bool merge, + const string& data_base_uri, + const Path& data_path, + MetadataMap engine_data, + optional engine_parent, + optional engine_name, + optional engine_poly) +{ + _mutex.lock(); + + /*_events.push_back(sigc::hide_return(sigc::bind( + sigc::mem_fun(_loader, &Loader::load_patch), + merge, data_base_uri, data_path, + engine_data, engine_parent, engine_name, engine_poly)));*/ + + cerr << "FIXME: load under root only\n"; + + _events.push_back(sigc::bind( + sigc::mem_fun(_loader, &Loader::load), + data_base_uri, "/")); + + _mutex.unlock(); + + whip(); +} + + +void +ThreadedLoader::save_patch(SharedPtr model, const string& filename, bool recursive) +{ + _mutex.lock(); + + _events.push_back(sigc::hide_return(sigc::bind( + sigc::mem_fun(this, &ThreadedLoader::save_patch_event), + model, filename, recursive))); + + _mutex.unlock(); + + whip(); +} + + +void +ThreadedLoader::save_patch_event(SharedPtr model, const string& filename, bool recursive) +{ + if (recursive) + cerr << "FIXME: Recursive save." << endl; + + _serializer->start_to_filename(filename); + _serializer->serialize(model); + _serializer->finish(); +} + + +} // namespace Ingenuity diff --git a/src/progs/ingenuity/ThreadedLoader.h b/src/progs/ingenuity/ThreadedLoader.h new file mode 100644 index 00000000..9212c9c7 --- /dev/null +++ b/src/progs/ingenuity/ThreadedLoader.h @@ -0,0 +1,95 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * 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 THREADEDLOADER_H +#define THREADEDLOADER_H + +#include +#include +#include +#include +#include "raul/Thread.h" +#include "raul/Slave.h" +#include "raul/Mutex.h" +#include "raul/Condition.h" +#include "ModelEngineInterface.h" +#include "ObjectModel.h" +#include "Serializer.h" +using std::string; +using std::list; +using boost::optional; + +namespace Ingen { namespace Client { + class Loader; + class PatchModel; +} } +using namespace Ingen::Client; + +namespace Ingenuity { + + +/** Thread for loading patch files. + * + * This is a seperate thread so it can send all the loading message without + * blocking everything else, so the app can respond to the incoming events + * caused as a result of the patch loading, while the patch loads. + * + * Implemented as a slave with a list of closures (events) which processes + * all events in the (mutex protected) list each time it's whipped. + * + * \ingroup Ingenuity + */ +class ThreadedLoader : public Slave +{ +public: + ThreadedLoader(SharedPtr engine); + ~ThreadedLoader(); + + Loader& loader() const { return *_loader; } + Serializer& serializer() const { return *_serializer; } + + // FIXME: there's a pattern here.... + // (same core interface as Loader/Serializer) + + void load_patch(bool merge, + const string& data_base_uri, + const Path& data_path, + MetadataMap engine_data, + optional engine_parent = optional(), + optional engine_name = optional(), + optional engine_poly = optional()); + + void save_patch(SharedPtr model, const string& filename, bool recursive); + +private: + + void save_patch_event(SharedPtr model, const string& filename, bool recursive); + + /** Returns nothing and takes no parameters (because they have all been bound) */ + typedef sigc::slot Closure; + + void _whipped(); + + Loader* const _loader; + Serializer* const _serializer; + Mutex _mutex; + list _events; +}; + + +} // namespace Ingenuity + +#endif // LOADERRTHREAD_H diff --git a/src/progs/patch_loader/patch_loader.cpp b/src/progs/patch_loader/patch_loader.cpp index 25fd626f..eb222c33 100644 --- a/src/progs/patch_loader/patch_loader.cpp +++ b/src/progs/patch_loader/patch_loader.cpp @@ -16,7 +16,7 @@ #include "OSCModelEngineInterface.h" -#include "Serializer.h" +//#include "Serializer.h" #include "PatchModel.h" #include "raul/Path.h" #include @@ -53,7 +53,7 @@ int main(int argc, char** argv) SharedPtr engine(new OSCModelEngineInterface(engine_url)); - Serializer serializer(engine); + //Serializer serializer(engine); /* Connect to engine */ engine->attach(-1, client_port); -- cgit v1.2.1