From c0f567d3232cbe165e56cb2684cda52df7cfb90f Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 1 Aug 2020 22:41:11 +0200 Subject: Move public headers to a separate include directory This is more conventional and probably best practice (since it avoids polluting the include path with non-headers), and is supported by the clang-tidy llvm-header-guard check. --- include/ingen/client/ArcModel.hpp | 67 ++++++++++++++ include/ingen/client/BlockModel.hpp | 117 ++++++++++++++++++++++++ include/ingen/client/ClientStore.hpp | 132 ++++++++++++++++++++++++++++ include/ingen/client/GraphModel.hpp | 82 +++++++++++++++++ include/ingen/client/ObjectModel.hpp | 99 +++++++++++++++++++++ include/ingen/client/PluginModel.hpp | 127 ++++++++++++++++++++++++++ include/ingen/client/PluginUI.hpp | 116 ++++++++++++++++++++++++ include/ingen/client/PortModel.hpp | 97 ++++++++++++++++++++ include/ingen/client/SigClientInterface.hpp | 63 +++++++++++++ include/ingen/client/SocketClient.hpp | 80 +++++++++++++++++ include/ingen/client/signal.hpp | 31 +++++++ 11 files changed, 1011 insertions(+) create mode 100644 include/ingen/client/ArcModel.hpp create mode 100644 include/ingen/client/BlockModel.hpp create mode 100644 include/ingen/client/ClientStore.hpp create mode 100644 include/ingen/client/GraphModel.hpp create mode 100644 include/ingen/client/ObjectModel.hpp create mode 100644 include/ingen/client/PluginModel.hpp create mode 100644 include/ingen/client/PluginUI.hpp create mode 100644 include/ingen/client/PortModel.hpp create mode 100644 include/ingen/client/SigClientInterface.hpp create mode 100644 include/ingen/client/SocketClient.hpp create mode 100644 include/ingen/client/signal.hpp (limited to 'include/ingen/client') diff --git a/include/ingen/client/ArcModel.hpp b/include/ingen/client/ArcModel.hpp new file mode 100644 index 00000000..e42dd7bd --- /dev/null +++ b/include/ingen/client/ArcModel.hpp @@ -0,0 +1,67 @@ +/* + This file is part of Ingen. + Copyright 2007-2015 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_CLIENT_ARCMODEL_HPP +#define INGEN_CLIENT_ARCMODEL_HPP + +#include "ingen/Arc.hpp" +#include "ingen/client/PortModel.hpp" +#include "ingen/ingen.h" +#include "ingen/types.hpp" +#include "raul/Path.hpp" + +#include + +namespace ingen { +namespace client { + +class ClientStore; + +/** Class to represent a port->port connections in the engine. + * + * @ingroup IngenClient + */ +class INGEN_API ArcModel : public Arc +{ +public: + SPtr tail() const { return _tail; } + SPtr head() const { return _head; } + + const Raul::Path& tail_path() const override { return _tail->path(); } + const Raul::Path& head_path() const override { return _head->path(); } + +private: + friend class ClientStore; + + ArcModel(SPtr tail, SPtr head) + : _tail(std::move(tail)) + , _head(std::move(head)) + { + assert(_tail); + assert(_head); + assert(_tail->parent()); + assert(_head->parent()); + assert(_tail->path() != _head->path()); + } + + const SPtr _tail; + const SPtr _head; +}; + +} // namespace client +} // namespace ingen + +#endif // INGEN_CLIENT_ARCMODEL_HPP diff --git a/include/ingen/client/BlockModel.hpp b/include/ingen/client/BlockModel.hpp new file mode 100644 index 00000000..d003b7d1 --- /dev/null +++ b/include/ingen/client/BlockModel.hpp @@ -0,0 +1,117 @@ +/* + This file is part of Ingen. + Copyright 2007-2015 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_CLIENT_BLOCKMODEL_HPP +#define INGEN_CLIENT_BLOCKMODEL_HPP + +#include "ingen/Node.hpp" +#include "ingen/client/ObjectModel.hpp" +#include "ingen/client/PluginModel.hpp" +#include "ingen/ingen.h" +#include "ingen/types.hpp" + +#include +#include +#include +#include + +namespace Raul { class Path; } + +namespace ingen { + +class URIs; + +namespace client { + +class PortModel; + +/** Block model class, used by the client to store engine's state. + * + * @ingroup IngenClient + */ +class INGEN_API BlockModel : public ObjectModel +{ +public: + BlockModel(const BlockModel& copy); + virtual ~BlockModel(); + + GraphType graph_type() const override { return Node::GraphType::BLOCK; } + + using Ports = std::vector>; + + SPtr get_port(const Raul::Symbol& symbol) const; + SPtr get_port(uint32_t index) const; + + Node* port(uint32_t index) const override; + + const URI& plugin_uri() const { return _plugin_uri; } + const Resource* plugin() const override { return _plugin.get(); } + Resource* plugin() { return _plugin.get(); } + SPtr plugin_model() const { return _plugin; } + uint32_t num_ports() const override { return _ports.size(); } + const Ports& ports() const { return _ports; } + + void default_port_value_range(const SPtr& port, + float& min, + float& max, + uint32_t srate = 1) const; + + void port_value_range(const SPtr& port, + float& min, + float& max, + uint32_t srate = 1) const; + + std::string label() const; + std::string port_label(const SPtr& port) const; + + // Signals + INGEN_SIGNAL(new_port, void, SPtr) + INGEN_SIGNAL(removed_port, void, SPtr) + +protected: + friend class ClientStore; + + BlockModel(URIs& uris, URI plugin_uri, const Raul::Path& path); + + BlockModel(URIs& uris, + const SPtr& plugin, + const Raul::Path& path); + + explicit BlockModel(const Raul::Path& path); + + void add_child(const SPtr& c) override; + bool remove_child(const SPtr& c) override; + void add_port(const SPtr& pm); + void remove_port(const SPtr& port); + void remove_port(const Raul::Path& port_path); + void set(const SPtr& model) override; + + virtual void clear(); + + Ports _ports; ///< Vector of ports + URI _plugin_uri; ///< Plugin URI (if PluginModel is unknown) + SPtr _plugin; ///< The plugin this block 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_BLOCKMODEL_HPP diff --git a/include/ingen/client/ClientStore.hpp b/include/ingen/client/ClientStore.hpp new file mode 100644 index 00000000..54eaf373 --- /dev/null +++ b/include/ingen/client/ClientStore.hpp @@ -0,0 +1,132 @@ +/* + This file is part of Ingen. + Copyright 2007-2016 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_CLIENT_CLIENTSTORE_HPP +#define INGEN_CLIENT_CLIENTSTORE_HPP + +#include "ingen/Interface.hpp" +#include "ingen/Message.hpp" +#include "ingen/Store.hpp" +#include "ingen/URI.hpp" +#include "ingen/client/signal.hpp" +#include "ingen/ingen.h" +#include "ingen/types.hpp" +#include "raul/Path.hpp" + +#include + +namespace Raul { +class Path; +} // namespace Raul + +namespace ingen { + +class Atom; +class Log; +class Node; +class Resource; +class URIs; + +namespace client { + +class BlockModel; +class GraphModel; +class ObjectModel; +class PluginModel; +class PortModel; +class SigClientInterface; + +/** Automatically manages models of objects in the engine. + * + * @ingroup IngenClient + */ +class INGEN_API ClientStore : public Store + , public Interface + , public INGEN_TRACKABLE { +public: + ClientStore( + URIs& uris, + Log& log, + const SPtr& emitter = SPtr()); + + URI uri() const override { return URI("ingen:/clients/store"); } + + SPtr object(const Raul::Path& path) const; + SPtr plugin(const URI& uri) const; + SPtr resource(const URI& uri) const; + + void clear(); + + using Plugins = std::map>; + + SPtr plugins() const { return _plugins; } + SPtr plugins() { return _plugins; } + void set_plugins(SPtr p) { _plugins = std::move(p); } + + URIs& uris() { return _uris; } + + void message(const Message& msg) override; + + void operator()(const BundleBegin&) {} + void operator()(const BundleEnd&) {} + void operator()(const Connect&); + void operator()(const Copy&); + void operator()(const Del&); + void operator()(const Delta&); + void operator()(const Disconnect&); + void operator()(const DisconnectAll&); + void operator()(const Error&) {} + void operator()(const Get&) {} + void operator()(const Move&); + void operator()(const Put&); + void operator()(const Redo&) {} + void operator()(const Response&) {} + void operator()(const SetProperty&); + void operator()(const Undo&) {} + + INGEN_SIGNAL(new_object, void, SPtr) + INGEN_SIGNAL(new_plugin, void, SPtr) + INGEN_SIGNAL(plugin_deleted, void, URI) + +private: + SPtr _object(const Raul::Path& path); + SPtr _plugin(const URI& uri); + SPtr _plugin(const Atom& uri); + SPtr _resource(const URI& uri); + + void add_object(const SPtr& object); + SPtr remove_object(const Raul::Path& path); + + void add_plugin(const SPtr& pm); + + SPtr connection_graph(const Raul::Path& tail_path, + const Raul::Path& head_path); + + // Slots for SigClientInterface signals + bool attempt_connection(const Raul::Path& tail_path, + const Raul::Path& head_path); + + URIs& _uris; + Log& _log; + SPtr _emitter; + + SPtr _plugins; ///< Map, keyed by plugin URI +}; + +} // namespace client +} // namespace ingen + +#endif // INGEN_CLIENT_CLIENTSTORE_HPP diff --git a/include/ingen/client/GraphModel.hpp b/include/ingen/client/GraphModel.hpp new file mode 100644 index 00000000..2248e7e3 --- /dev/null +++ b/include/ingen/client/GraphModel.hpp @@ -0,0 +1,82 @@ +/* + This file is part of Ingen. + Copyright 2007-2015 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_CLIENT_GRAPHMODEL_HPP +#define INGEN_CLIENT_GRAPHMODEL_HPP + +#include "ingen/Node.hpp" +#include "ingen/URIs.hpp" +#include "ingen/client/BlockModel.hpp" +#include "ingen/client/signal.hpp" +#include "ingen/ingen.h" +#include "ingen/types.hpp" + +#include + +namespace ingen { +namespace client { + +class ArcModel; +class ClientStore; + +/** Client's model of a graph. + * + * @ingroup IngenClient + */ +class INGEN_API GraphModel : public BlockModel +{ +public: + /* WARNING: Copy constructor creates a shallow copy WRT connections */ + + GraphType graph_type() const override { return Node::GraphType::GRAPH; } + + SPtr get_arc(const ingen::Node* tail, + const ingen::Node* head); + + bool enabled() const; + bool polyphonic() const; + uint32_t internal_poly() const; + + // Signals + INGEN_SIGNAL(new_block, void, SPtr) + INGEN_SIGNAL(removed_block, void, SPtr) + INGEN_SIGNAL(new_arc, void, SPtr) + INGEN_SIGNAL(removed_arc, void, SPtr) + +private: + friend class ClientStore; + + GraphModel(URIs& uris, const Raul::Path& graph_path) + : BlockModel(uris, + static_cast(uris.ingen_Graph), + graph_path) + { + } + + void clear() override; + void add_child(const SPtr& c) override; + bool remove_child(const SPtr& o) override; + void remove_arcs_on(const SPtr& p); + + void add_arc(const SPtr& arc); + void remove_arc(const ingen::Node* tail, + const ingen::Node* head); +}; + +} // namespace client +} // namespace ingen + +#endif // INGEN_CLIENT_GRAPHMODEL_HPP diff --git a/include/ingen/client/ObjectModel.hpp b/include/ingen/client/ObjectModel.hpp new file mode 100644 index 00000000..39729377 --- /dev/null +++ b/include/ingen/client/ObjectModel.hpp @@ -0,0 +1,99 @@ +/* + This file is part of Ingen. + Copyright 2007-2015 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +/** + @defgroup IngenClient Client-Side Models and Utilities +*/ + +#ifndef INGEN_CLIENT_OBJECTMODEL_HPP +#define INGEN_CLIENT_OBJECTMODEL_HPP + +#include "ingen/Node.hpp" +#include "ingen/URI.hpp" +#include "ingen/URIs.hpp" +#include "ingen/client/signal.hpp" +#include "ingen/ingen.h" +#include "ingen/types.hpp" +#include "raul/Path.hpp" +#include "raul/Symbol.hpp" + +namespace ingen { + +class Atom; + +namespace client { + +/** Base class for all Node models (BlockModel, GraphModel, 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 INGEN_API ObjectModel : public Node +{ +public: + bool is_a(const URIs::Quark& type) const; + + const Atom& get_property(const URI& key) const override; + + void on_property(const URI& uri, const Atom& value) override; + void on_property_removed(const URI& uri, const Atom& value) override; + + const Raul::Path& path() const override { return _path; } + const Raul::Symbol& symbol() const override { return _symbol; } + + SPtr parent() const { return _parent; } + bool polyphonic() const; + + Node* graph_parent() const override { return _parent.get(); } + + // Signals + INGEN_SIGNAL(new_child, void, SPtr) + INGEN_SIGNAL(removed_child, void, SPtr) + INGEN_SIGNAL(property, void, const URI&, const Atom&) + INGEN_SIGNAL(property_removed, void, const URI&, const Atom&) + INGEN_SIGNAL(destroyed, void) + INGEN_SIGNAL(moved, void) + +protected: + friend class ClientStore; + + ObjectModel(URIs& uris, const Raul::Path& path); + ObjectModel(const ObjectModel& copy); + + void set_path(const Raul::Path& p) override; + virtual void set_parent(const SPtr& p); + virtual void add_child(const SPtr& c) {} + virtual bool remove_child(const SPtr& c) { return true; } + + virtual void set(const SPtr& o); + + SPtr _parent; + +private: + Raul::Path _path; + Raul::Symbol _symbol; +}; + +} // namespace client +} // namespace ingen + +#endif // INGEN_CLIENT_OBJECTMODEL_HPP diff --git a/include/ingen/client/PluginModel.hpp b/include/ingen/client/PluginModel.hpp new file mode 100644 index 00000000..dbefaf95 --- /dev/null +++ b/include/ingen/client/PluginModel.hpp @@ -0,0 +1,127 @@ +/* + This file is part of Ingen. + Copyright 2007-2017 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_CLIENT_PLUGINMODEL_HPP +#define INGEN_CLIENT_PLUGINMODEL_HPP + +#include "ingen/Forge.hpp" +#include "ingen/Resource.hpp" +#include "ingen/World.hpp" +#include "ingen/client/signal.hpp" +#include "ingen/ingen.h" +#include "ingen/types.hpp" +#include "lilv/lilv.h" +#include "raul/Symbol.hpp" +#include "sord/sordmm.hpp" + +#include +#include +#include + +namespace ingen { + +class URIs; + +namespace client { + +class GraphModel; +class BlockModel; +class PluginUI; + +/** Model for a plugin available for loading. + * + * @ingroup IngenClient + */ +class INGEN_API PluginModel : public ingen::Resource +{ +public: + PluginModel(URIs& uris, + const URI& uri, + const Atom& type, + const ingen::Properties& properties); + + const Atom& type() const { return _type; } + + URI type_uri() const + { + return URI(_type.is_valid() ? _uris.forge.str(_type, false) + : "http://www.w3.org/2002/07/owl#Nothing"); + } + + const Atom& get_property(const URI& key) const override; + + Raul::Symbol default_block_symbol() const; + std::string human_name() const; + std::string port_human_name(uint32_t i) const; + + using ScalePoints = std::map; + ScalePoints port_scale_points(uint32_t i) const; + + using Presets = std::map; + const Presets& presets() const { return _presets; } + + 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; + + SPtr + ui(ingen::World& world, const SPtr& block) const; + + std::string documentation(bool html) const; + std::string port_documentation(uint32_t index, bool html) 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 URI&, const Atom&) + INGEN_SIGNAL(preset, void, const URI&, const std::string&) + + bool fetched() const { return _fetched; } + void set_fetched(bool f) { _fetched = f; } + +protected: + friend class ClientStore; + void set(const SPtr& p); + + void add_preset(const URI& uri, const std::string& label); + +private: + static std::string get_documentation(const LilvNode* subject, bool html); + + static Sord::World* _rdf_world; + static LilvWorld* _lilv_world; + static const LilvPlugins* _lilv_plugins; + + Atom _type; + const LilvPlugin* _lilv_plugin; + Presets _presets; + bool _fetched; +}; + +} // 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..70ff7274 --- /dev/null +++ b/include/ingen/client/PluginUI.hpp @@ -0,0 +1,116 @@ +/* + This file is part of Ingen. + Copyright 2007-2015 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_CLIENT_PLUGINUI_HPP +#define INGEN_CLIENT_PLUGINUI_HPP + +#include "signal.hpp" + +#include "ingen/LV2Features.hpp" +#include "ingen/Resource.hpp" +#include "ingen/ingen.h" +#include "ingen/types.hpp" +#include "lilv/lilv.h" +#include "suil/suil.h" + +#include +#include + +namespace ingen { + +class Atom; +class URI; +class World; + +namespace client { + +class BlockModel; + +/** Custom user interface for a plugin. + * + * @ingroup IngenClient + */ +class INGEN_API PluginUI { +public: + ~PluginUI(); + + /** Create a UI for the given block and plugin. + * + * This does not actually instantiate the UI itself, so signals can be + * connected first. The caller should connect to signal_property_changed, + * then call instantiate(). + */ + static SPtr create(ingen::World& world, + const SPtr& block, + const LilvPlugin* plugin); + + /** Instantiate the UI. + * + * If true is returned, instantiation was successfull and the widget can be + * obtained with get_widget(). Otherwise, instantiation failed, so there is + * no widget and the UI can not be used. + */ + bool instantiate(); + bool instantiated () { return _instance != nullptr; } + + SuilWidget get_widget(); + + void port_event(uint32_t port_index, + uint32_t buffer_size, + uint32_t format, + const void* buffer); + + bool is_resizable() const; + + /** Signal emitted when the UI sets a property. + * + * The application must connect to this signal to communicate with the + * engine and/or update itself as necessary. + */ + INGEN_SIGNAL(property_changed, void, + const URI&, // Subject + const URI&, // Predicate + const Atom&, // Object + Resource::Graph) // Context + + ingen::World& world() const { return _world; } + SPtr block() const { return _block; } + +private: + PluginUI(ingen::World& world, + SPtr block, + LilvUIs* uis, + const LilvUI* ui, + const LilvNode* ui_type); + + ingen::World& _world; + SPtr _block; + SuilInstance* _instance; + LilvUIs* _uis; + const LilvUI* _ui; + LilvNode* _ui_node; + LilvNode* _ui_type; + std::set _subscribed_ports; + + static SuilHost* ui_host; + + SPtr _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..c386dff0 --- /dev/null +++ b/include/ingen/client/PortModel.hpp @@ -0,0 +1,97 @@ +/* + This file is part of Ingen. + Copyright 2007-2015 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_CLIENT_PORTMODEL_HPP +#define INGEN_CLIENT_PORTMODEL_HPP + +#include "ingen/client/ObjectModel.hpp" +#include "ingen/ingen.h" +#include "ingen/types.hpp" +#include "lv2/core/lv2.h" +#include "lv2/port-props/port-props.h" + +#include +#include + +namespace Raul { class Path; } + +namespace ingen { +namespace client { + +/** Model of a port. + * + * @ingroup IngenClient + */ +class INGEN_API PortModel : public ObjectModel +{ +public: + enum class Direction { INPUT, OUTPUT }; + + GraphType graph_type() const override { return Node::GraphType::PORT; } + + bool supports(const URIs::Quark& value_type) const; + + inline uint32_t index() const { return _index; } + inline const Atom& value() const { return get_property(_uris.ingen_value); } + inline bool is_input() const { return (_direction == Direction::INPUT); } + inline bool is_output() const { return (_direction == Direction::OUTPUT); } + + bool port_property(const URIs::Quark& uri) const; + + bool is_logarithmic() const { return port_property(_uris.pprops_logarithmic); } + bool is_enumeration() const { return port_property(_uris.lv2_enumeration); } + bool is_integer() const { return port_property(_uris.lv2_integer); } + bool is_toggle() const { return port_property(_uris.lv2_toggled); } + bool is_numeric() const { + return ObjectModel::is_a(_uris.lv2_ControlPort) + || ObjectModel::is_a(_uris.lv2_CVPort); + } + bool is_uri() const; + + inline bool operator==(const PortModel& pm) const { return (path() == pm.path()); } + + void on_property(const URI& uri, const Atom& value) override; + + // Signals + INGEN_SIGNAL(value_changed, void, const Atom&) + INGEN_SIGNAL(voice_changed, void, uint32_t, const Atom&) + INGEN_SIGNAL(activity, void, const Atom&) + +private: + friend class ClientStore; + + PortModel(URIs& uris, + const Raul::Path& path, + uint32_t index, + Direction dir) + : ObjectModel(uris, path) + , _index(index) + , _direction(dir) + {} + + void add_child(const SPtr& c) override { throw; } + bool remove_child(const SPtr& c) override { throw; } + + void set(const SPtr& model) override; + + uint32_t _index; + Direction _direction; +}; + +} // 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..674714a3 --- /dev/null +++ b/include/ingen/client/SigClientInterface.hpp @@ -0,0 +1,63 @@ +/* + This file is part of Ingen. + Copyright 2007-2016 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_CLIENT_SIGCLIENTINTERFACE_HPP +#define INGEN_CLIENT_SIGCLIENTINTERFACE_HPP + +#include "ingen/Interface.hpp" +#include "ingen/client/signal.hpp" +#include "ingen/ingen.h" +#include "raul/Path.hpp" + +#include +#include + +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. + * + * @ingroup IngenClient + */ +class INGEN_API SigClientInterface : public ingen::Interface, + public INGEN_TRACKABLE +{ +public: + SigClientInterface() = default; + + URI uri() const override { return URI("ingen:/clients/sig"); } + + INGEN_SIGNAL(message, void, Message) + + /** Fire pending signals. Only does anything on derived classes (that may queue) */ + virtual bool emit_signals() { return false; } + +protected: + void message(const Message& msg) override { + _signal_message(msg); + } +}; + +} // namespace client +} // namespace ingen + +#endif diff --git a/include/ingen/client/SocketClient.hpp b/include/ingen/client/SocketClient.hpp new file mode 100644 index 00000000..8e551821 --- /dev/null +++ b/include/ingen/client/SocketClient.hpp @@ -0,0 +1,80 @@ +/* + This file is part of Ingen. + Copyright 2012-2015 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_CLIENT_SOCKET_CLIENT_HPP +#define INGEN_CLIENT_SOCKET_CLIENT_HPP + +#include "ingen/SocketReader.hpp" +#include "ingen/SocketWriter.hpp" +#include "ingen/ingen.h" +#include "raul/Socket.hpp" + +namespace ingen { +namespace client { + +/** The client side of an Ingen socket connection. */ +class INGEN_API SocketClient : public SocketWriter +{ +public: + SocketClient(World& world, + const URI& uri, + const SPtr& sock, + const SPtr& respondee) + : SocketWriter(world.uri_map(), world.uris(), uri, sock) + , _respondee(respondee) + , _reader(world, *respondee.get(), sock) + {} + + SPtr respondee() const override { + return _respondee; + } + + void set_respondee(const SPtr& respondee) override { + _respondee = respondee; + } + + static SPtr + new_socket_interface(ingen::World& world, + const URI& uri, + const SPtr& respondee) + { + const Raul::Socket::Type type = (uri.scheme() == "unix" + ? Raul::Socket::Type::UNIX + : Raul::Socket::Type::TCP); + + SPtr sock(new Raul::Socket(type)); + if (!sock->connect(uri)) { + world.log().error("Failed to connect <%1%> (%2%)\n", + sock->uri(), strerror(errno)); + return SPtr(); + } + return SPtr(new SocketClient(world, uri, sock, respondee)); + } + + static void register_factories(World& world) { + world.add_interface_factory("unix", &new_socket_interface); + world.add_interface_factory("tcp", &new_socket_interface); + } + +private: + SPtr _respondee; + SocketReader _reader; +}; + +} // namespace client +} // namespace ingen + +#endif // INGEN_CLIENT_SOCKET_CLIENT_HPP diff --git a/include/ingen/client/signal.hpp b/include/ingen/client/signal.hpp new file mode 100644 index 00000000..ba5b017b --- /dev/null +++ b/include/ingen/client/signal.hpp @@ -0,0 +1,31 @@ +/* + This file is part of Ingen. + Copyright 2007-2015 David Robillard + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or 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 Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see . +*/ + +#ifndef INGEN_CLIENT_SIGNAL_HPP +#define INGEN_CLIENT_SIGNAL_HPP + +#include + +#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 -- cgit v1.2.1