summaryrefslogtreecommitdiffstats
path: root/ingen
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2015-02-08 07:02:59 +0000
committerDavid Robillard <d@drobilla.net>2015-02-08 07:02:59 +0000
commit0f9c8151d5b42b243a499bb31a1e1f0b2e8c5f6f (patch)
tree1ed4df4df4c3f160120544d92c681f1b4519e1aa /ingen
parent8733afb7ae9a04f46ac6318667182da16eca9fe5 (diff)
downloadingen-0f9c8151d5b42b243a499bb31a1e1f0b2e8c5f6f.tar.gz
ingen-0f9c8151d5b42b243a499bb31a1e1f0b2e8c5f6f.tar.bz2
ingen-0f9c8151d5b42b243a499bb31a1e1f0b2e8c5f6f.zip
Server-side copy paste with LV2 state support.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5541 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'ingen')
-rw-r--r--ingen/AtomWriter.hpp3
-rw-r--r--ingen/ClashAvoider.hpp75
-rw-r--r--ingen/Interface.hpp6
-rw-r--r--ingen/Node.hpp7
-rw-r--r--ingen/Status.hpp8
-rw-r--r--ingen/Store.hpp2
-rw-r--r--ingen/URIs.hpp1
-rw-r--r--ingen/client/ClientStore.hpp5
-rw-r--r--ingen/client/SigClientInterface.hpp4
-rw-r--r--ingen/client/ThreadedSigClientInterface.hpp5
-rw-r--r--ingen/serialisation/Parser.hpp10
-rw-r--r--ingen/serialisation/Serialiser.hpp38
12 files changed, 80 insertions, 84 deletions
diff --git a/ingen/AtomWriter.hpp b/ingen/AtomWriter.hpp
index c7ac3cc6..4f10cd45 100644
--- a/ingen/AtomWriter.hpp
+++ b/ingen/AtomWriter.hpp
@@ -52,6 +52,9 @@ public:
const Resource::Properties& remove,
const Resource::Properties& add);
+ void copy(const Raul::Path& old_path,
+ const Raul::URI& new_uri);
+
void move(const Raul::Path& old_path,
const Raul::Path& new_path);
diff --git a/ingen/ClashAvoider.hpp b/ingen/ClashAvoider.hpp
index 98d508d4..c07273f0 100644
--- a/ingen/ClashAvoider.hpp
+++ b/ingen/ClashAvoider.hpp
@@ -20,86 +20,35 @@
#include <inttypes.h>
#include <map>
-#include <string>
-#include "ingen/Interface.hpp"
-
-namespace Raul {
-class Atom;
-class Path;
-}
+#include "raul/Path.hpp"
+#include "raul/URI.hpp"
namespace Ingen {
class Store;
-/** A wrapper for an Interface that creates objects but possibly maps
- * symbol names to avoid clashes with the existing objects in a store.
+/** Maps paths so they do not clash with an existing object in a store.
*
- * @ingroup IngenShared
+ * @ingroup ingen
*/
-class ClashAvoider : public Interface
+class ClashAvoider
{
public:
- ClashAvoider(Store& store, Interface& target, Store* also_avoid=NULL)
- : _store(store), _target(target), _also_avoid(also_avoid) {}
-
- Raul::URI uri() const { return Raul::URI("ingen:/clients/clash_avoider"); }
-
- void set_target(Interface& target) { _target = target; }
-
- // Bundles
- void bundle_begin() { _target.bundle_begin(); }
- void bundle_end() { _target.bundle_end(); }
-
- // Object commands
-
- virtual void put(const Raul::URI& path,
- const Resource::Properties& properties,
- Resource::Graph ctx=Resource::Graph::DEFAULT);
-
- virtual void delta(const Raul::URI& path,
- const Resource::Properties& remove,
- const Resource::Properties& add);
-
- virtual void move(const Raul::Path& old_path,
- const Raul::Path& new_path);
-
- virtual void connect(const Raul::Path& tail,
- const Raul::Path& head);
-
- virtual void disconnect(const Raul::Path& tail,
- const Raul::Path& head);
+ ClashAvoider(const Store& store);
- virtual void disconnect_all(const Raul::Path& graph,
- const Raul::Path& path);
-
- virtual void set_property(const Raul::URI& subject_path,
- const Raul::URI& predicate,
- const Atom& value);
-
- virtual void del(const Raul::URI& uri);
-
- virtual void set_response_id(int32_t id) {}
- virtual void get(const Raul::URI& uri) {}
- virtual void response(int32_t id, Status status, const std::string& subject) {}
- virtual void error(const std::string& msg) {}
-
-private:
const Raul::URI map_uri(const Raul::URI& in);
const Raul::Path map_path(const Raul::Path& in);
- Store& _store;
- Interface& _target;
-
- Store* _also_avoid;
bool exists(const Raul::Path& path) const;
- typedef std::map<Raul::Path, unsigned> Offsets;
- Offsets _offsets;
-
+private:
+ typedef std::map<Raul::Path, unsigned> Offsets;
typedef std::map<Raul::Path, Raul::Path> SymbolMap;
- SymbolMap _symbol_map;
+
+ const Store& _store;
+ Offsets _offsets;
+ SymbolMap _symbol_map;
};
} // namespace Ingen
diff --git a/ingen/Interface.hpp b/ingen/Interface.hpp
index d5fe0b97..042bd3f7 100644
--- a/ingen/Interface.hpp
+++ b/ingen/Interface.hpp
@@ -21,6 +21,7 @@
#ifndef INGEN_INTERFACE_HPP
#define INGEN_INTERFACE_HPP
+#include <list>
#include <string>
#include "ingen/Resource.hpp"
@@ -67,6 +68,9 @@ public:
const Resource::Properties& remove,
const Resource::Properties& add) = 0;
+ virtual void copy(const Raul::Path& old_path,
+ const Raul::URI& new_uri) = 0;
+
virtual void move(const Raul::Path& old_path,
const Raul::Path& new_path) = 0;
@@ -86,7 +90,7 @@ public:
const Atom& value) = 0;
/** Set the ID to use to respond to the next message.
- * Setting the ID to -1 will disable responses.
+ * Setting the ID to 0 will disable responses.
*/
virtual void set_response_id(int32_t id) = 0;
diff --git a/ingen/Node.hpp b/ingen/Node.hpp
index 2cbce01c..293ac058 100644
--- a/ingen/Node.hpp
+++ b/ingen/Node.hpp
@@ -72,6 +72,13 @@ public:
virtual const Raul::Symbol& symbol() const = 0;
virtual Node* graph_parent() const = 0;
+ Raul::URI base_uri() const {
+ if (uri()[uri().size() - 1] == '/') {
+ return uri();
+ }
+ return Raul::URI(uri() + '/');
+ }
+
static Raul::URI root_uri() { return Raul::URI("ingen:/root"); }
static bool uri_is_path(const Raul::URI& uri) {
diff --git a/ingen/Status.hpp b/ingen/Status.hpp
index b754702a..ed388ccf 100644
--- a/ingen/Status.hpp
+++ b/ingen/Status.hpp
@@ -33,7 +33,7 @@ enum class Status {
DIRECTION_MISMATCH,
EXISTS,
INTERNAL_ERROR,
- INVALID_PARENT_PATH,
+ INVALID_PARENT,
INVALID_POLY,
NOT_DELETABLE,
NOT_FOUND,
@@ -42,7 +42,7 @@ enum class Status {
NO_SPACE,
PARENT_DIFFERS,
PARENT_NOT_FOUND,
- PLUGIN_NOT_FOUND,
+ PROTOTYPE_NOT_FOUND,
PORT_NOT_FOUND,
TYPE_MISMATCH,
UNKNOWN_TYPE
@@ -65,7 +65,7 @@ ingen_status_string(Status st)
case Status::DIRECTION_MISMATCH: return "Direction mismatch";
case Status::EXISTS: return "Object exists";
case Status::INTERNAL_ERROR: return "Internal error";
- case Status::INVALID_PARENT_PATH: return "Invalid parent path";
+ case Status::INVALID_PARENT: return "Invalid parent";
case Status::INVALID_POLY: return "Invalid polyphony";
case Status::NOT_DELETABLE: return "Object not deletable";
case Status::NOT_FOUND: return "Object not found";
@@ -74,7 +74,7 @@ ingen_status_string(Status st)
case Status::NO_SPACE: return "Insufficient space";
case Status::PARENT_DIFFERS: return "Parent differs";
case Status::PARENT_NOT_FOUND: return "Parent not found";
- case Status::PLUGIN_NOT_FOUND: return "Plugin not found";
+ case Status::PROTOTYPE_NOT_FOUND: return "Prototype not found";
case Status::PORT_NOT_FOUND: return "Port not found";
case Status::TYPE_MISMATCH: return "Type mismatch";
case Status::UNKNOWN_TYPE: return "Unknown type";
diff --git a/ingen/Store.hpp b/ingen/Store.hpp
index 4856ff4e..77af3d66 100644
--- a/ingen/Store.hpp
+++ b/ingen/Store.hpp
@@ -68,7 +68,7 @@ public:
unsigned child_name_offset(const Raul::Path& parent,
const Raul::Symbol& symbol,
- bool allow_zero=true);
+ bool allow_zero=true) const;
std::mutex& mutex() { return _mutex; }
diff --git a/ingen/URIs.hpp b/ingen/URIs.hpp
index 4c31ccdc..6cb7ea15 100644
--- a/ingen/URIs.hpp
+++ b/ingen/URIs.hpp
@@ -130,6 +130,7 @@ public:
const Quark midi_noteNumber;
const Quark morph_currentType;
const Quark param_sampleRate;
+ const Quark patch_Copy;
const Quark patch_Delete;
const Quark patch_Get;
const Quark patch_Move;
diff --git a/ingen/client/ClientStore.hpp b/ingen/client/ClientStore.hpp
index f53217b4..1871fca2 100644
--- a/ingen/client/ClientStore.hpp
+++ b/ingen/client/ClientStore.hpp
@@ -55,7 +55,6 @@ public:
ClientStore(
URIs& uris,
Log& log,
- SPtr<Interface> engine = SPtr<Interface>(),
SPtr<SigClientInterface> emitter = SPtr<SigClientInterface>());
Raul::URI uri() const { return Raul::URI("ingen:/clients/store"); }
@@ -81,6 +80,9 @@ public:
const Resource::Properties& remove,
const Resource::Properties& add);
+ void copy(const Raul::Path& old_path,
+ const Raul::URI& new_uri);
+
void move(const Raul::Path& old_path,
const Raul::Path& new_path);
@@ -129,7 +131,6 @@ private:
URIs& _uris;
Log& _log;
- SPtr<Interface> _engine;
SPtr<SigClientInterface> _emitter;
SPtr<Plugins> _plugins; ///< Map, keyed by plugin URI
diff --git a/ingen/client/SigClientInterface.hpp b/ingen/client/SigClientInterface.hpp
index 07e6e333..39fff895 100644
--- a/ingen/client/SigClientInterface.hpp
+++ b/ingen/client/SigClientInterface.hpp
@@ -53,6 +53,7 @@ public:
INGEN_SIGNAL(error, void, std::string)
INGEN_SIGNAL(put, void, Raul::URI, Resource::Properties, Resource::Graph)
INGEN_SIGNAL(delta, void, Raul::URI, Resource::Properties, Resource::Properties)
+ INGEN_SIGNAL(object_copied, void, Raul::Path, Raul::URI)
INGEN_SIGNAL(object_moved, void, Raul::Path, Raul::Path)
INGEN_SIGNAL(object_deleted, void, Raul::URI)
INGEN_SIGNAL(connection, void, Raul::Path, Raul::Path)
@@ -97,6 +98,9 @@ protected:
void del(const Raul::URI& uri)
{ EMIT(object_deleted, uri); }
+ void copy(const Raul::Path& old_path, const Raul::URI& new_uri)
+ { EMIT(object_copied, old_path, new_uri); }
+
void move(const Raul::Path& old_path, const Raul::Path& new_path)
{ EMIT(object_moved, old_path, new_path); }
diff --git a/ingen/client/ThreadedSigClientInterface.hpp b/ingen/client/ThreadedSigClientInterface.hpp
index ab9a7ee9..0d5d5e57 100644
--- a/ingen/client/ThreadedSigClientInterface.hpp
+++ b/ingen/client/ThreadedSigClientInterface.hpp
@@ -59,6 +59,7 @@ public:
, connection_slot(_signal_connection.make_slot())
, object_deleted_slot(_signal_object_deleted.make_slot())
, object_moved_slot(_signal_object_moved.make_slot())
+ , object_copied_slot(_signal_object_copied.make_slot())
, disconnection_slot(_signal_disconnection.make_slot())
, disconnect_all_slot(_signal_disconnect_all.make_slot())
, property_change_slot(_signal_property_change.make_slot())
@@ -97,6 +98,9 @@ public:
void move(const Raul::Path& old_path, const Raul::Path& new_path)
{ push_sig(sigc::bind(object_moved_slot, old_path, new_path)); }
+ void copy(const Raul::Path& old_path, const Raul::URI& new_uri)
+ { push_sig(sigc::bind(object_copied_slot, old_path, new_uri)); }
+
void disconnect(const Raul::Path& tail, const Raul::Path& head)
{ push_sig(sigc::bind(disconnection_slot, tail, head)); }
@@ -157,6 +161,7 @@ private:
sigc::slot<void, Raul::Path, Raul::Path> connection_slot;
sigc::slot<void, Raul::URI> object_deleted_slot;
sigc::slot<void, Raul::Path, Raul::Path> object_moved_slot;
+ sigc::slot<void, Raul::Path, Raul::URI> object_copied_slot;
sigc::slot<void, Raul::Path, Raul::Path> disconnection_slot;
sigc::slot<void, Raul::Path, Raul::Path> disconnect_all_slot;
sigc::slot<void, Raul::URI, Raul::URI, Atom> property_change_slot;
diff --git a/ingen/serialisation/Parser.hpp b/ingen/serialisation/Parser.hpp
index 6ece6965..446b3988 100644
--- a/ingen/serialisation/Parser.hpp
+++ b/ingen/serialisation/Parser.hpp
@@ -25,10 +25,10 @@
#include <list>
#include <boost/optional.hpp>
-#include <glibmm/ustring.h>
#include "ingen/Node.hpp"
#include "raul/Path.hpp"
+#include "raul/URI.hpp"
namespace Ingen {
@@ -53,16 +53,16 @@ public:
virtual bool parse_file(
World* world,
Interface* target,
- Glib::ustring path,
+ const std::string& path,
boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(),
boost::optional<Properties> data = boost::optional<Properties>());
- virtual bool parse_string(
+ virtual boost::optional<Raul::URI> parse_string(
World* world,
Interface* target,
- const Glib::ustring& str,
- const Glib::ustring& base_uri,
+ const std::string& str,
+ const std::string& base_uri,
boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(),
boost::optional<Properties> data = boost::optional<Properties>());
diff --git a/ingen/serialisation/Serialiser.hpp b/ingen/serialisation/Serialiser.hpp
index d0b65893..80a01b89 100644
--- a/ingen/serialisation/Serialiser.hpp
+++ b/ingen/serialisation/Serialiser.hpp
@@ -46,27 +46,49 @@ public:
explicit Serialiser(World& world);
virtual ~Serialiser();
- typedef Node::Properties Properties;
-
- virtual void to_file(SPtr<const Node> object,
- const std::string& filename);
-
+ /** Write a graph and all its contents as a complete bundle. */
virtual void write_bundle(SPtr<const Node> graph,
const std::string& path);
- virtual std::string to_string(SPtr<const Node> object,
- const std::string& base_uri);
-
+ /** Begin a serialization to a string.
+ *
+ * This must be called before any serializing methods.
+ *
+ * The results of the serialization will be returned by the finish() method after
+ * the desired objects have been serialised.
+ *
+ * All serialized paths will have the root path chopped from their prefix
+ * (therefore all serialized paths must be descendants of the root)
+ */
virtual void start_to_string(const Raul::Path& root,
const std::string& base_uri);
+ /** Begin a serialization to a file.
+ *
+ * This must be called before any serializing methods.
+ *
+ * All serialized paths will have the root path chopped from their prefix
+ * (therefore all serialized paths must be descendants of the root)
+ */
+ virtual void start_to_file(const Raul::Path& root,
+ const std::string& filename);
+
+ /** Serialize an object (graph, block, or port). */
virtual void serialise(SPtr<const Node> object)
throw (std::logic_error);
+ /** Serialize an arc. */
virtual void serialise_arc(const Sord::Node& parent,
SPtr<const Arc> arc)
throw (std::logic_error);
+ /** Finish serialization.
+ *
+ * If this is a file serialization, this must be called to finish and close
+ * the output file, and the empty string is returned.
+ *
+ * If this is a string serialization, the serialized result is returned.
+ */
virtual std::string finish();
private: