summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/ingen/client/ClientStore.hpp143
-rw-r--r--include/ingen/client/ConnectionModel.hpp68
-rw-r--r--include/ingen/client/NodeModel.hpp114
-rw-r--r--include/ingen/client/ObjectModel.hpp101
-rw-r--r--include/ingen/client/PatchModel.hpp96
-rw-r--r--include/ingen/client/PluginModel.hpp112
-rw-r--r--include/ingen/client/PluginUI.hpp78
-rw-r--r--include/ingen/client/PortModel.hpp121
-rw-r--r--include/ingen/client/SigClientInterface.hpp125
-rw-r--r--include/ingen/client/ThreadedSigClientInterface.hpp155
-rw-r--r--include/ingen/client/signal.hpp32
11 files changed, 1145 insertions, 0 deletions
diff --git a/include/ingen/client/ClientStore.hpp b/include/ingen/client/ClientStore.hpp
new file mode 100644
index 00000000..75f12ec1
--- /dev/null
+++ b/include/ingen/client/ClientStore.hpp
@@ -0,0 +1,143 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_CLIENTSTORE_HPP
+#define INGEN_CLIENT_CLIENTSTORE_HPP
+
+#include <cassert>
+#include <list>
+#include <string>
+
+#include "raul/Path.hpp"
+#include "raul/PathTable.hpp"
+#include "raul/SharedPtr.hpp"
+#include "raul/TableImpl.hpp"
+
+#include "ingen/ServerInterface.hpp"
+#include "ingen/client/signal.hpp"
+#include "shared/LV2URIMap.hpp"
+#include "shared/Store.hpp"
+
+namespace Raul { class Atom; }
+
+namespace Ingen {
+
+class GraphObject;
+
+namespace Client {
+
+class NodeModel;
+class ObjectModel;
+class PatchModel;
+class PluginModel;
+class PortModel;
+class SigClientInterface;
+
+/** Automatically manages models of objects in the engine.
+ *
+ * \ingroup IngenClient
+ */
+class ClientStore : public Shared::Store
+ , public CommonInterface
+ , public INGEN_TRACKABLE {
+public:
+ ClientStore(
+ SharedPtr<Shared::LV2URIMap> uris,
+ SharedPtr<ServerInterface> engine=SharedPtr<ServerInterface>(),
+ SharedPtr<SigClientInterface> emitter=SharedPtr<SigClientInterface>());
+
+ SharedPtr<const ObjectModel> object(const Raul::Path& path) const;
+ SharedPtr<const PluginModel> plugin(const Raul::URI& uri) const;
+ SharedPtr<const Resource> resource(const Raul::URI& uri) const;
+
+ void clear();
+
+ typedef Raul::Table<Raul::URI, SharedPtr<PluginModel> > Plugins;
+ SharedPtr<const Plugins> plugins() const { return _plugins; }
+ SharedPtr<Plugins> plugins() { return _plugins; }
+ void set_plugins(SharedPtr<Plugins> p) { _plugins = p; }
+
+ Shared::LV2URIMap& uris() { return *_uris.get(); }
+
+ // CommonInterface
+ bool new_object(const GraphObject* object);
+
+ void put(const Raul::URI& uri,
+ const Resource::Properties& properties,
+ Resource::Graph ctx=Resource::DEFAULT);
+
+ void delta(const Raul::URI& uri,
+ const Resource::Properties& remove,
+ const Resource::Properties& add);
+
+ void move(const Raul::Path& old_path,
+ const Raul::Path& new_path);
+
+ void set_property(const Raul::URI& subject_path,
+ const Raul::URI& predicate,
+ const Raul::Atom& value);
+
+ void connect(const Raul::Path& src_port_path,
+ const Raul::Path& dst_port_path);
+
+ void disconnect(const Raul::URI& src,
+ const Raul::URI& dst);
+
+ void disconnect_all(const Raul::Path& parent_patch_path,
+ const Raul::Path& path);
+
+ void del(const Raul::URI& uri);
+
+ INGEN_SIGNAL(new_object, void, SharedPtr<ObjectModel>);
+ INGEN_SIGNAL(new_plugin, void, SharedPtr<PluginModel>);
+
+private:
+ void add(GraphObject* o) { throw; }
+
+ SharedPtr<ObjectModel> _object(const Raul::Path& path);
+ SharedPtr<PluginModel> _plugin(const Raul::URI& uri);
+ SharedPtr<Resource> _resource(const Raul::URI& uri);
+
+ void add_object(SharedPtr<ObjectModel> object);
+ SharedPtr<ObjectModel> remove_object(const Raul::Path& path);
+
+ void add_plugin(SharedPtr<PluginModel> plugin);
+
+ SharedPtr<PatchModel> connection_patch(const Raul::Path& src_port_path,
+ const Raul::Path& dst_port_path);
+
+ void bundle_begin() {}
+ void bundle_end() {}
+
+ // Slots for SigClientInterface signals
+ void object_moved(const Raul::Path& old_path, const Raul::Path& new_path);
+ void activity(const Raul::Path& path);
+
+ bool attempt_connection(const Raul::Path& src_port_path,
+ const Raul::Path& dst_port_path);
+
+ SharedPtr<Shared::LV2URIMap> _uris;
+ SharedPtr<ServerInterface> _engine;
+ SharedPtr<SigClientInterface> _emitter;
+
+ SharedPtr<Plugins> _plugins; ///< Map, keyed by plugin URI
+};
+
+} // namespace Client
+} // namespace Ingen
+
+#endif // INGEN_CLIENT_CLIENTSTORE_HPP
diff --git a/include/ingen/client/ConnectionModel.hpp b/include/ingen/client/ConnectionModel.hpp
new file mode 100644
index 00000000..1c719914
--- /dev/null
+++ b/include/ingen/client/ConnectionModel.hpp
@@ -0,0 +1,68 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_CONNECTIONMODEL_HPP
+#define INGEN_CLIENT_CONNECTIONMODEL_HPP
+
+#include <cassert>
+
+#include "raul/Path.hpp"
+#include "raul/SharedPtr.hpp"
+
+#include "ingen/Connection.hpp"
+#include "ingen/client/PortModel.hpp"
+
+namespace Ingen {
+namespace Client {
+
+class ClientStore;
+
+/** Class to represent a port->port connections in the engine.
+ *
+ * \ingroup IngenClient
+ */
+class ConnectionModel : public Connection
+{
+public:
+ SharedPtr<PortModel> src_port() const { return _src_port; }
+ SharedPtr<PortModel> dst_port() const { return _dst_port; }
+
+ const Raul::Path& src_port_path() const { return _src_port->path(); }
+ const Raul::Path& dst_port_path() const { return _dst_port->path(); }
+
+private:
+ friend class ClientStore;
+
+ ConnectionModel(SharedPtr<PortModel> src, SharedPtr<PortModel> dst)
+ : _src_port(src)
+ , _dst_port(dst)
+ {
+ assert(_src_port);
+ assert(_dst_port);
+ assert(_src_port->parent());
+ assert(_dst_port->parent());
+ assert(_src_port->path() != _dst_port->path());
+ }
+
+ const SharedPtr<PortModel> _src_port;
+ const SharedPtr<PortModel> _dst_port;
+};
+
+} // namespace Client
+} // namespace Ingen
+
+#endif // INGEN_CLIENT_CONNECTIONMODEL_HPP
diff --git a/include/ingen/client/NodeModel.hpp b/include/ingen/client/NodeModel.hpp
new file mode 100644
index 00000000..efc8514a
--- /dev/null
+++ b/include/ingen/client/NodeModel.hpp
@@ -0,0 +1,114 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_NODEMODEL_HPP
+#define INGEN_CLIENT_NODEMODEL_HPP
+
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include "raul/SharedPtr.hpp"
+
+#include "ingen/Node.hpp"
+#include "ingen/Port.hpp"
+#include "ingen/client/ObjectModel.hpp"
+#include "ingen/client/PortModel.hpp"
+#include "ingen/client/PluginModel.hpp"
+
+namespace Raul { class Path; }
+
+namespace Ingen {
+
+namespace Shared { class LV2URIMap; }
+
+namespace Client {
+
+class PluginModel;
+class ClientStore;
+
+/** Node model class, used by the client to store engine's state.
+ *
+ * \ingroup IngenClient
+ */
+class NodeModel : public ObjectModel,
+ virtual public Ingen::Node
+{
+public:
+ NodeModel(const NodeModel& copy);
+ virtual ~NodeModel();
+
+ typedef std::vector< SharedPtr<const PortModel> > Ports;
+
+ SharedPtr<const PortModel> get_port(const Raul::Symbol& symbol) const;
+
+ Port* port(uint32_t index) const;
+
+ const Raul::URI& plugin_uri() const { return _plugin_uri; }
+ const Plugin* plugin() const { return _plugin.get(); }
+ Plugin* plugin() { return _plugin.get(); }
+ SharedPtr<PluginModel> plugin_model() const { return _plugin; }
+ uint32_t num_ports() const { return _ports.size(); }
+ const Ports& ports() const { return _ports; }
+
+ void default_port_value_range(SharedPtr<const PortModel> port,
+ float& min, float& max) const;
+ void port_value_range(SharedPtr<const PortModel> port,
+ float& min, float& max) const;
+
+ std::string port_label(SharedPtr<const PortModel> port) const;
+
+ // Signals
+ INGEN_SIGNAL(new_port, void, SharedPtr<const PortModel>);
+ INGEN_SIGNAL(removed_port, void, SharedPtr<const PortModel>);
+
+protected:
+ friend class ClientStore;
+
+ NodeModel(Shared::LV2URIMap& uris,
+ const Raul::URI& plugin_uri,
+ const Raul::Path& path);
+ NodeModel(Shared::LV2URIMap& uris,
+ SharedPtr<PluginModel> plugin,
+ const Raul::Path& path);
+ NodeModel(const Raul::Path& path);
+
+ void add_child(SharedPtr<ObjectModel> c);
+ bool remove_child(SharedPtr<ObjectModel> c);
+ void add_port(SharedPtr<PortModel> pm);
+ void remove_port(SharedPtr<PortModel> pm);
+ void remove_port(const Raul::Path& port_path);
+ void add_program(int bank, int program, const std::string& name);
+ void remove_program(int bank, int program);
+ void set(SharedPtr<ObjectModel> model);
+
+ virtual void clear();
+
+ Ports _ports; ///< Vector of ports (not a Table to preserve order)
+ Raul::URI _plugin_uri; ///< Plugin URI (if PluginModel is unknown)
+ SharedPtr<PluginModel> _plugin; ///< The plugin this node is an instance of
+
+private:
+ mutable uint32_t _num_values; ///< Size of _min_values and _max_values
+ mutable float* _min_values; ///< Port min values (cached for LV2)
+ mutable float* _max_values; ///< Port max values (cached for LV2)
+};
+
+} // namespace Client
+} // namespace Ingen
+
+#endif // INGEN_CLIENT_NODEMODEL_HPP
diff --git a/include/ingen/client/ObjectModel.hpp b/include/ingen/client/ObjectModel.hpp
new file mode 100644
index 00000000..7a975637
--- /dev/null
+++ b/include/ingen/client/ObjectModel.hpp
@@ -0,0 +1,101 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_OBJECTMODEL_HPP
+#define INGEN_CLIENT_OBJECTMODEL_HPP
+
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+
+#include "raul/Path.hpp"
+#include "raul/SharedPtr.hpp"
+#include "raul/URI.hpp"
+
+#include "ingen/GraphObject.hpp"
+#include "ingen/client/signal.hpp"
+#include "shared/ResourceImpl.hpp"
+
+namespace Ingen {
+
+namespace Shared { class LV2URIMap; }
+
+namespace Client {
+
+class ClientStore;
+
+/** Base class for all GraphObject models (NodeModel, PatchModel, PortModel).
+ *
+ * There are no non-const public methods intentionally, models are not allowed
+ * to be manipulated directly by anything (but the Store) because of the
+ * asynchronous nature of engine control. To change something, use the
+ * controller (which the model probably shouldn't have a reference to but oh
+ * well, it reduces Collection Hell) and wait for the result (as a signal
+ * from this Model).
+ *
+ * \ingroup IngenClient
+ */
+class ObjectModel : virtual public GraphObject
+ , public Ingen::Shared::ResourceImpl
+{
+public:
+ virtual ~ObjectModel();
+
+ const Raul::Atom& get_property(const Raul::URI& key) const;
+
+ Raul::Atom& set_property(const Raul::URI& key, const Raul::Atom& value);
+ void add_property(const Raul::URI& key, const Raul::Atom& value);
+
+ const Raul::Path& path() const { return _path; }
+ const Raul::Symbol& symbol() const { return _symbol; }
+ SharedPtr<ObjectModel> parent() const { return _parent; }
+ bool polyphonic() const;
+
+ GraphObject* graph_parent() const { return _parent.get(); }
+
+ // Signals
+ INGEN_SIGNAL(new_child, void, SharedPtr<ObjectModel>);
+ INGEN_SIGNAL(removed_child, void, SharedPtr<ObjectModel>);
+ INGEN_SIGNAL(property, void, const Raul::URI&, const Raul::Atom&);
+ INGEN_SIGNAL(destroyed, void);
+ INGEN_SIGNAL(moved, void);
+
+protected:
+ friend class ClientStore;
+
+ ObjectModel(Shared::LV2URIMap& uris, const Raul::Path& path);
+ ObjectModel(const ObjectModel& copy);
+
+ virtual void set_path(const Raul::Path& p);
+ virtual void set_parent(SharedPtr<ObjectModel> p);
+ virtual void add_child(SharedPtr<ObjectModel> c) {}
+ virtual bool remove_child(SharedPtr<ObjectModel> c) { return true; }
+
+ virtual void set(SharedPtr<ObjectModel> model);
+
+ ResourceImpl _meta;
+ SharedPtr<ObjectModel> _parent;
+
+private:
+ Raul::Path _path;
+ Raul::Symbol _symbol;
+};
+
+} // namespace Client
+} // namespace Ingen
+
+#endif // INGEN_CLIENT_OBJECTMODEL_HPP
diff --git a/include/ingen/client/PatchModel.hpp b/include/ingen/client/PatchModel.hpp
new file mode 100644
index 00000000..3e873cfc
--- /dev/null
+++ b/include/ingen/client/PatchModel.hpp
@@ -0,0 +1,96 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_PATCHMODEL_HPP
+#define INGEN_CLIENT_PATCHMODEL_HPP
+
+#include "raul/SharedPtr.hpp"
+
+#include "ingen/Patch.hpp"
+#include "ingen/client/NodeModel.hpp"
+
+namespace Ingen {
+
+class Port;
+
+namespace Client {
+
+class ClientStore;
+class ConnectionModel;
+
+/** Client's model of a patch.
+ *
+ * \ingroup IngenClient
+ */
+class PatchModel : public NodeModel, public Ingen::Patch
+{
+public:
+ /* WARNING: Copy constructor creates a shallow copy WRT connections */
+
+ const Connections& connections() const { return *_connections.get(); }
+
+ SharedPtr<ConnectionModel> get_connection(const Ingen::Port* src_port,
+ const Ingen::Port* dst_port);
+
+ bool enabled() const;
+ bool polyphonic() const;
+ uint32_t internal_poly() const;
+
+ /** "editable" = arranging,connecting,adding,deleting,etc
+ * not editable (control mode) you can just change controllers (performing)
+ */
+ bool get_editable() const { return _editable; }
+ void set_editable(bool e) const {
+ if (_editable != e) {
+ _editable = e;
+ const_cast<PatchModel*>(this)->signal_editable().emit(e);
+ }
+ }
+
+ // Signals
+ INGEN_SIGNAL(new_node, void, SharedPtr<NodeModel>);
+ INGEN_SIGNAL(removed_node, void, SharedPtr<NodeModel>);
+ INGEN_SIGNAL(new_connection, void, SharedPtr<ConnectionModel>);
+ INGEN_SIGNAL(removed_connection, void, SharedPtr<ConnectionModel>);
+ INGEN_SIGNAL(editable, void, bool);
+
+private:
+ friend class ClientStore;
+
+ PatchModel(Shared::LV2URIMap& uris, const Raul::Path& patch_path)
+ : NodeModel(uris, "http://drobilla.net/ns/ingen#Patch", patch_path)
+ , _connections(new Connections())
+ , _editable(true)
+ {
+ }
+
+ void clear();
+ void add_child(SharedPtr<ObjectModel> c);
+ bool remove_child(SharedPtr<ObjectModel> c);
+
+ void add_connection(SharedPtr<ConnectionModel> cm);
+ void remove_connection(const Ingen::Port* src_port,
+ const Ingen::Port* dst_port);
+
+ SharedPtr<Connections> _connections;
+ mutable bool _editable;
+};
+
+} // namespace Client
+} // namespace Ingen
+
+#endif // INGEN_CLIENT_PATCHMODEL_HPP
diff --git a/include/ingen/client/PluginModel.hpp b/include/ingen/client/PluginModel.hpp
new file mode 100644
index 00000000..99657fbc
--- /dev/null
+++ b/include/ingen/client/PluginModel.hpp
@@ -0,0 +1,112 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_PLUGINMODEL_HPP
+#define INGEN_CLIENT_PLUGINMODEL_HPP
+
+#include "lilv/lilv.h"
+#include "raul/SharedPtr.hpp"
+#include "raul/Symbol.hpp"
+#include "sord/sordmm.hpp"
+
+#include "ingen/Plugin.hpp"
+#include "ingen/ServerInterface.hpp"
+#include "ingen/client/signal.hpp"
+#include "shared/ResourceImpl.hpp"
+#include "shared/World.hpp"
+
+namespace Ingen {
+
+namespace Shared { class LV2URIMap; }
+
+namespace Client {
+
+class PatchModel;
+class NodeModel;
+class PluginUI;
+
+/** Model for a plugin available for loading.
+ *
+ * \ingroup IngenClient
+ */
+class PluginModel : public Ingen::Plugin
+ , public Ingen::Shared::ResourceImpl
+{
+public:
+ PluginModel(
+ Shared::LV2URIMap& uris,
+ const Raul::URI& uri,
+ const Raul::URI& type_uri,
+ const Ingen::Resource::Properties& properties);
+
+ Type type() const { return _type; }
+
+ virtual const Raul::Atom& get_property(const Raul::URI& key) const;
+
+ Raul::Symbol default_node_symbol() const;
+ std::string human_name() const;
+ std::string port_human_name(uint32_t index) const;
+
+ static LilvWorld* lilv_world() { return _lilv_world; }
+ const LilvPlugin* lilv_plugin() const { return _lilv_plugin; }
+
+ const LilvPort* lilv_port(uint32_t index) const;
+
+ static void set_lilv_world(LilvWorld* world);
+
+ bool has_ui() const;
+
+ SharedPtr<PluginUI> ui(Ingen::Shared::World* world,
+ SharedPtr<const NodeModel> node) const;
+
+ const std::string& icon_path() const;
+ static std::string get_lv2_icon_path(const LilvPlugin* plugin);
+
+ std::string documentation() const;
+ std::string port_documentation(uint32_t index) const;
+
+ static void set_rdf_world(Sord::World& world) {
+ _rdf_world = &world;
+ }
+
+ static Sord::World* rdf_world() { return _rdf_world; }
+
+ // Signals
+ INGEN_SIGNAL(changed, void);
+ INGEN_SIGNAL(property, void, const Raul::URI&, const Raul::Atom&);
+
+protected:
+ friend class ClientStore;
+ void set(SharedPtr<PluginModel> p);
+
+private:
+ Type _type;
+
+ static LilvWorld* _lilv_world;
+ static const LilvPlugins* _lilv_plugins;
+
+ const LilvPlugin* _lilv_plugin;
+ mutable std::string _icon_path;
+
+ static Sord::World* _rdf_world;
+};
+
+} // namespace Client
+} // namespace Ingen
+
+#endif // INGEN_CLIENT_PLUGINMODEL_HPP
+
diff --git a/include/ingen/client/PluginUI.hpp b/include/ingen/client/PluginUI.hpp
new file mode 100644
index 00000000..bf0094e7
--- /dev/null
+++ b/include/ingen/client/PluginUI.hpp
@@ -0,0 +1,78 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_PLUGINUI_HPP
+#define INGEN_CLIENT_PLUGINUI_HPP
+
+#include "raul/SharedPtr.hpp"
+
+#include "lilv/lilv.h"
+
+#include "suil/suil.h"
+
+#include "shared/LV2Features.hpp"
+
+namespace Ingen {
+
+class ServerInterface;
+
+namespace Shared { class World; }
+
+namespace Client {
+
+class NodeModel;
+
+/** Model for a plugin available for loading.
+ *
+ * \ingroup IngenClient
+ */
+class PluginUI {
+public:
+ ~PluginUI();
+
+ static SharedPtr<PluginUI> create(Ingen::Shared::World* world,
+ SharedPtr<const NodeModel> node,
+ const LilvPlugin* plugin);
+
+ SuilWidget get_widget();
+
+ void port_event(uint32_t port_index,
+ uint32_t buffer_size,
+ uint32_t format,
+ const void* buffer);
+
+ Ingen::Shared::World* world() const { return _world; }
+ SharedPtr<const NodeModel> node() const { return _node; }
+
+private:
+ PluginUI(Ingen::Shared::World* world,
+ SharedPtr<const NodeModel> node);
+
+ Ingen::Shared::World* _world;
+ SharedPtr<const NodeModel> _node;
+ SuilInstance* _instance;
+
+ static SuilHost* ui_host;
+
+ SharedPtr<Shared::LV2Features::FeatureArray> _features;
+};
+
+} // namespace Client
+} // namespace Ingen
+
+#endif // INGEN_CLIENT_PLUGINUI_HPP
+
diff --git a/include/ingen/client/PortModel.hpp b/include/ingen/client/PortModel.hpp
new file mode 100644
index 00000000..e8e74f8a
--- /dev/null
+++ b/include/ingen/client/PortModel.hpp
@@ -0,0 +1,121 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_PORTMODEL_HPP
+#define INGEN_CLIENT_PORTMODEL_HPP
+
+#include <cstdlib>
+#include <string>
+
+#include "raul/SharedPtr.hpp"
+#include "raul/log.hpp"
+
+#include "ingen/Port.hpp"
+#include "ingen/client/ObjectModel.hpp"
+
+namespace Raul { class Path; }
+
+namespace Ingen {
+namespace Client {
+
+/** Model of a port.
+ *
+ * \ingroup IngenClient
+ */
+class PortModel : public ObjectModel, public Ingen::Port
+{
+public:
+ enum Direction { INPUT, OUTPUT };
+
+ const PortTypes& types() const { return _types; }
+
+ bool supports(const Raul::URI& value_type) const;
+
+ inline uint32_t index() const { return _index; }
+ inline const Raul::Atom& value() const { return _current_val; }
+ inline bool connected() const { return (_connections > 0); }
+ inline bool is_input() const { return (_direction == INPUT); }
+ inline bool is_output() const { return (_direction == OUTPUT); }
+
+ bool port_property(const std::string& uri) const;
+
+ bool is_numeric() const { return is_a(PortType::CONTROL); }
+ bool is_logarithmic() const { return port_property("http://drobilla.net/ns/ingen#logarithmic"); }
+ bool is_integer() const { return port_property("http://lv2plug.in/ns/lv2core#integer"); }
+ bool is_toggle() const { return port_property("http://lv2plug.in/ns/lv2core#toggled"); }
+
+ bool has_context(const Raul::URI& context) const;
+
+
+ inline bool operator==(const PortModel& pm) const { return (path() == pm.path()); }
+
+ Raul::Atom& set_property(const Raul::URI& uri, const Raul::Atom& value);
+
+ inline void value(const Raul::Atom& val) {
+ if (val != _current_val) {
+ _current_val = val;
+ _signal_value_changed.emit(val);
+ }
+ }
+
+ inline void value(uint32_t voice, const Raul::Atom& val) {
+ // FIXME: implement properly
+ _signal_voice_changed.emit(voice, val);
+ }
+
+ // Signals
+ INGEN_SIGNAL(value_changed, void, const Raul::Atom&);
+ INGEN_SIGNAL(voice_changed, void, uint32_t, const Raul::Atom&);
+ INGEN_SIGNAL(activity, void);
+ INGEN_SIGNAL(connection, void, SharedPtr<PortModel>);
+ INGEN_SIGNAL(disconnection, void, SharedPtr<PortModel>);
+
+private:
+ friend class ClientStore;
+
+ PortModel(Shared::LV2URIMap& uris,
+ const Raul::Path& path, uint32_t index, PortType type, Direction dir)
+ : ObjectModel(uris, path)
+ , _index(index)
+ , _direction(dir)
+ , _current_val(0.0f)
+ , _connections(0)
+ {
+ _types.insert(type);
+ if (type == PortType::UNKNOWN)
+ Raul::warn << "[PortModel] Unknown port type" << std::endl;
+ }
+
+ void add_child(SharedPtr<ObjectModel> c) { throw; }
+ bool remove_child(SharedPtr<ObjectModel> c) { throw; }
+
+ void connected_to(SharedPtr<PortModel> p) { ++_connections; _signal_connection.emit(p); }
+ void disconnected_from(SharedPtr<PortModel> p) { --_connections; _signal_disconnection.emit(p); }
+
+ void set(SharedPtr<ObjectModel> model);
+
+ uint32_t _index;
+ std::set<PortType> _types;
+ Direction _direction;
+ Raul::Atom _current_val;
+ size_t _connections;
+};
+
+} // namespace Client
+} // namespace Ingen
+
+#endif // INGEN_CLIENT_PORTMODEL_HPP
diff --git a/include/ingen/client/SigClientInterface.hpp b/include/ingen/client/SigClientInterface.hpp
new file mode 100644
index 00000000..2241425b
--- /dev/null
+++ b/include/ingen/client/SigClientInterface.hpp
@@ -0,0 +1,125 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_SIGCLIENTINTERFACE_HPP
+#define INGEN_CLIENT_SIGCLIENTINTERFACE_HPP
+
+#include <stdint.h>
+
+#include "raul/Path.hpp"
+
+#include "ingen/ClientInterface.hpp"
+#include "ingen/client/signal.hpp"
+
+namespace Ingen {
+namespace Client {
+
+/** A LibSigC++ signal emitting interface for clients to use.
+ *
+ * This simply emits a signal for every event that comes from the engine.
+ * For a higher level model based view of the engine, use ClientStore.
+ *
+ * The signals here match the calls to ClientInterface exactly. See the
+ * documentation for ClientInterface for meanings of signal parameters.
+ */
+class SigClientInterface : public Ingen::ClientInterface,
+ public INGEN_TRACKABLE
+{
+public:
+ SigClientInterface() {}
+
+ Raul::URI uri() const { return "http://drobilla.net/ns/ingen#internal"; }
+
+ INGEN_SIGNAL(response_ok, void, int32_t)
+ INGEN_SIGNAL(response_error, void, int32_t, std::string)
+ INGEN_SIGNAL(bundle_begin, void)
+ INGEN_SIGNAL(bundle_end, void)
+ INGEN_SIGNAL(error, void, std::string)
+ INGEN_SIGNAL(new_patch, void, Raul::Path, uint32_t)
+ INGEN_SIGNAL(new_port, void, Raul::Path, Raul::URI, uint32_t, bool)
+ INGEN_SIGNAL(put, void, Raul::URI, Resource::Properties, Resource::Graph)
+ INGEN_SIGNAL(delta, void, Raul::URI, Resource::Properties, Resource::Properties)
+ INGEN_SIGNAL(object_moved, void, Raul::Path, Raul::Path)
+ INGEN_SIGNAL(object_deleted, void, Raul::URI)
+ INGEN_SIGNAL(connection, void, Raul::Path, Raul::Path)
+ INGEN_SIGNAL(disconnection, void, Raul::URI, Raul::URI)
+ INGEN_SIGNAL(disconnect_all, void, Raul::Path, Raul::Path)
+ INGEN_SIGNAL(variable_change, void, Raul::URI, Raul::URI, Raul::Atom)
+ INGEN_SIGNAL(property_change, void, Raul::URI, Raul::URI, Raul::Atom)
+ INGEN_SIGNAL(port_value, void, Raul::Path, Raul::Atom)
+ INGEN_SIGNAL(activity, void, Raul::Path)
+
+ /** Fire pending signals. Only does anything on derived classes (that may queue) */
+ virtual bool emit_signals() { return false; }
+
+protected:
+
+ // ClientInterface hooks that fire the above signals
+
+#define EMIT(name, ...) { _signal_ ## name (__VA_ARGS__); }
+
+ void bundle_begin()
+ { EMIT(bundle_begin); }
+
+ void bundle_end()
+ { EMIT(bundle_end); }
+
+ void response_ok(int32_t id)
+ { EMIT(response_ok, id); }
+
+ void response_error(int32_t id, const std::string& msg)
+ { EMIT(response_error, id, msg); }
+
+ void error(const std::string& msg)
+ { EMIT(error, msg); }
+
+ void put(const Raul::URI& uri,
+ const Resource::Properties& properties,
+ Resource::Graph ctx=Resource::DEFAULT)
+ { EMIT(put, uri, properties, ctx); }
+
+ void delta(const Raul::URI& uri,
+ const Resource::Properties& remove,
+ const Resource::Properties& add)
+ { EMIT(delta, uri, remove, add); }
+
+ void connect(const Raul::Path& src_port_path, const Raul::Path& dst_port_path)
+ { EMIT(connection, src_port_path, dst_port_path); }
+
+ void del(const Raul::URI& uri)
+ { EMIT(object_deleted, uri); }
+
+ void move(const Raul::Path& old_path, const Raul::Path& new_path)
+ { EMIT(object_moved, old_path, new_path); }
+
+ void disconnect(const Raul::URI& src, const Raul::URI& dst)
+ { EMIT(disconnection, src, dst); }
+
+ void disconnect_all(const Raul::Path& parent_patch_path, const Raul::Path& path)
+ { EMIT(disconnect_all, parent_patch_path, path); }
+
+ void set_property(const Raul::URI& subject, const Raul::URI& key, const Raul::Atom& value)
+ { EMIT(property_change, subject, key, value); }
+
+ void activity(const Raul::Path& port_path)
+ { EMIT(activity, port_path); }
+};
+
+} // namespace Client
+} // namespace Ingen
+
+#endif
diff --git a/include/ingen/client/ThreadedSigClientInterface.hpp b/include/ingen/client/ThreadedSigClientInterface.hpp
new file mode 100644
index 00000000..c30b62da
--- /dev/null
+++ b/include/ingen/client/ThreadedSigClientInterface.hpp
@@ -0,0 +1,155 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_THREADEDSIGCLIENTINTERFACE_HPP
+#define INGEN_CLIENT_THREADEDSIGCLIENTINTERFACE_HPP
+
+#include <stdint.h>
+
+#include <string>
+
+#include <sigc++/sigc++.h>
+#include <glibmm/thread.h>
+
+#include "raul/Atom.hpp"
+#include "raul/SRSWQueue.hpp"
+
+#include "ingen/ClientInterface.hpp"
+#include "ingen/client/SigClientInterface.hpp"
+
+/** Returns nothing and takes no parameters (because they have all been bound) */
+typedef sigc::slot<void> Closure;
+
+namespace Ingen {
+
+class ServerInterface;
+
+namespace Client {
+
+/** A LibSigC++ signal emitting interface for clients to use.
+ *
+ * This emits signals (possibly) in a different thread than the ClientInterface
+ * functions are called. It must be explicitly driven with the emit_signals()
+ * function, which fires all enqueued signals up until the present. You can
+ * use this in a GTK idle callback for receiving thread safe engine signals.
+ */
+class ThreadedSigClientInterface : public SigClientInterface
+{
+public:
+ ThreadedSigClientInterface(uint32_t queue_size)
+ : _sigs(queue_size)
+ , response_ok_slot(_signal_response_ok.make_slot())
+ , response_error_slot(_signal_response_error.make_slot())
+ , error_slot(_signal_error.make_slot())
+ , new_port_slot(_signal_new_port.make_slot())
+ , put_slot(_signal_put.make_slot())
+ , connection_slot(_signal_connection.make_slot())
+ , object_deleted_slot(_signal_object_deleted.make_slot())
+ , object_moved_slot(_signal_object_moved.make_slot())
+ , disconnection_slot(_signal_disconnection.make_slot())
+ , disconnect_all_slot(_signal_disconnect_all.make_slot())
+ , variable_change_slot(_signal_variable_change.make_slot())
+ , property_change_slot(_signal_property_change.make_slot())
+ , port_value_slot(_signal_port_value.make_slot())
+ , activity_slot(_signal_activity.make_slot())
+ {}
+
+ virtual Raul::URI uri() const { return "http://drobilla.net/ns/ingen#internal"; }
+
+ void bundle_begin()
+ { push_sig(bundle_begin_slot); }
+
+ void bundle_end()
+ { push_sig(bundle_end_slot); }
+
+ void response_ok(int32_t id)
+ { push_sig(sigc::bind(response_ok_slot, id)); }
+
+ void response_error(int32_t id, const std::string& msg)
+ { push_sig(sigc::bind(response_error_slot, id, msg)); }
+
+ void error(const std::string& msg)
+ { push_sig(sigc::bind(error_slot, msg)); }
+
+ void put(const Raul::URI& path,
+ const Resource::Properties& properties,
+ Resource::Graph ctx=Resource::DEFAULT)
+ { push_sig(sigc::bind(put_slot, path, properties, ctx)); }
+
+ void delta(const Raul::URI& path,
+ const Resource::Properties& remove,
+ const Resource::Properties& add)
+ { push_sig(sigc::bind(delta_slot, path, remove, add)); }
+
+ void connect(const Raul::Path& src_port_path, const Raul::Path& dst_port_path)
+ { push_sig(sigc::bind(connection_slot, src_port_path, dst_port_path)); }
+
+ void del(const Raul::URI& uri)
+ { push_sig(sigc::bind(object_deleted_slot, uri)); }
+
+ void move(const Raul::Path& old_path, const Raul::Path& new_path)
+ { push_sig(sigc::bind(object_moved_slot, old_path, new_path)); }
+
+ void disconnect(const Raul::URI& src, const Raul::URI& dst)
+ { push_sig(sigc::bind(disconnection_slot, src, dst)); }
+
+ void disconnect_all(const Raul::Path& parent_patch_path, const Raul::Path& path)
+ { push_sig(sigc::bind(disconnect_all_slot, parent_patch_path, path)); }
+
+ void set_property(const Raul::URI& subject, const Raul::URI& key, const Raul::Atom& value)
+ { push_sig(sigc::bind(property_change_slot, subject, key, value)); }
+
+ void activity(const Raul::Path& port_path)
+ { push_sig(sigc::bind(activity_slot, port_path)); }
+
+ /** Process all queued events - Called from GTK thread to emit signals. */
+ bool emit_signals();
+
+private:
+ void push_sig(Closure ev);
+
+ Glib::Mutex _mutex;
+ Glib::Cond _cond;
+
+ Raul::SRSWQueue<Closure> _sigs;
+
+ sigc::slot<void> bundle_begin_slot;
+ sigc::slot<void> bundle_end_slot;
+ sigc::slot<void, int32_t> response_ok_slot;
+ sigc::slot<void, int32_t, std::string> response_error_slot;
+ sigc::slot<void, std::string> error_slot;
+ sigc::slot<void, Raul::URI, Raul::URI, Raul::Symbol> new_plugin_slot;
+ sigc::slot<void, Raul::Path, Raul::URI, uint32_t, bool> new_port_slot;
+ sigc::slot<void, Raul::URI, Resource::Properties,
+ Resource::Graph> put_slot;
+ sigc::slot<void, Raul::URI, Resource::Properties,
+ Resource::Properties> delta_slot;
+ 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::URI, Raul::URI> disconnection_slot;
+ sigc::slot<void, Raul::Path, Raul::Path> disconnect_all_slot;
+ sigc::slot<void, Raul::URI, Raul::URI, Raul::Atom> variable_change_slot;
+ sigc::slot<void, Raul::URI, Raul::URI, Raul::Atom> property_change_slot;
+ sigc::slot<void, Raul::Path, Raul::Atom> port_value_slot;
+ sigc::slot<void, Raul::Path> activity_slot;
+};
+
+} // namespace Client
+} // namespace Ingen
+
+#endif
diff --git a/include/ingen/client/signal.hpp b/include/ingen/client/signal.hpp
new file mode 100644
index 00000000..f40c6a57
--- /dev/null
+++ b/include/ingen/client/signal.hpp
@@ -0,0 +1,32 @@
+/* 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
+ */
+
+#ifndef INGEN_CLIENT_SIGNAL_HPP
+#define INGEN_CLIENT_SIGNAL_HPP
+
+#include <sigc++/sigc++.h>
+
+#define INGEN_SIGNAL(name, ...) \
+protected: \
+sigc::signal<__VA_ARGS__> _signal_##name; \
+public: \
+sigc::signal<__VA_ARGS__> signal_##name() const { return _signal_##name; } \
+sigc::signal<__VA_ARGS__>& signal_##name() { return _signal_##name; }
+
+#define INGEN_TRACKABLE sigc::trackable
+
+#endif // INGEN_CLIENT_SIGNAL_HPP