DeviceInterface.hpp
1 #pragma once
2 #include <Device/Node/DeviceNode.hpp>
3 #include <Device/Protocol/DeviceSettings.hpp>
4 
5 #include <ossia/detail/callback_container.hpp>
6 #include <ossia/network/base/value_callback.hpp>
7 
8 #include <ossia-qt/device_metatype.hpp>
9 
10 #include <nano_signal_slot.hpp>
11 #include <score_lib_device_export.h>
12 
13 #include <verdigris>
14 class QMenu;
15 namespace score
16 {
17 struct DocumentContext;
18 }
19 namespace ossia
20 {
21 class value;
22 }
23 
24 namespace ossia::net
25 {
26 class node_base;
27 class parameter_base;
28 class device_base;
29 struct network_context;
30 using network_context_ptr = std::shared_ptr<network_context>;
31 }
32 namespace State
33 {
34 struct Message;
35 }
36 namespace Device
37 {
38 struct FullAddressSettings;
39 
40 struct SCORE_LIB_DEVICE_EXPORT DeviceCapas
41 {
42  bool canAddNode{true};
43  bool canRemoveNode{true};
44  bool canRenameNode{true};
45  bool canSetProperties{true};
46  bool canDisconnect{true};
47  bool canRefreshValue{true};
48  bool canRefreshTree{false};
49  bool asyncConnect{false};
50  bool canListen{true};
51  bool canSerialize{true};
52  bool canLearn{false};
53  bool hasCallbacks{true};
54 };
55 
56 enum DeviceLogging : int8_t
57 {
58  LogNothing,
59  LogUnfolded,
60  LogEverything
61 };
62 
63 class SCORE_LIB_DEVICE_EXPORT DeviceInterface
64  : public QObject
65  , public Nano::Observer
66 {
67  W_OBJECT(DeviceInterface)
68 
69 public:
71  virtual ~DeviceInterface();
72 
73  const Device::DeviceSettings& settings() const;
74  const QString& name() const;
75 
76  virtual void addNode(const Device::Node& n);
77 
78  DeviceCapas capabilities() const;
79 
80  virtual void disconnect();
81  virtual bool reconnect() = 0;
82  virtual void recreate(const Device::Node&); // Argument is the node of the
83  // device, used for recreation
84  virtual bool connected() const;
85 
86  void updateSettings(const Device::DeviceSettings&);
87 
88  // Asks, and returns all the new addresses if the device can refresh itself
89  // Minuit-like.
90  // The addresses are not applied to the device, they have to be via a
91  // command!
92  virtual Device::Node refresh();
93  std::optional<ossia::value> refresh(const State::Address&);
94  void request(const Device::Node&);
95  void setListening(const State::Address&, bool);
96  void addToListening(const std::vector<State::Address>&);
97  std::vector<State::Address> listening() const;
98 
99  virtual void addAddress(const Device::FullAddressSettings&);
100  virtual void updateAddress(
101  const State::Address& currentAddr, const Device::FullAddressSettings& newAddr);
102  void removeNode(const State::Address&);
103 
104  void sendMessage(const State::Address& addr, const ossia::value& v);
105 
106  // Make a node from an inside path, if it has been added for instance.
107  Device::Node getNode(const State::Address&) const;
108  Device::Node getNodeWithoutChildren(const State::Address&) const;
109 
110  bool isLogging() const;
111  void setLogging(DeviceLogging);
112 
113  virtual ossia::net::device_base* getDevice() const = 0;
114 
115  virtual bool isLearning() const;
116  virtual void setLearning(bool);
117 
118  virtual QMimeData* mimeData() const;
119  virtual void setupContextMenu(QMenu&) const;
120 
121  void nodeCreated(const ossia::net::node_base&);
122  void nodeRemoving(const ossia::net::node_base&);
123  void nodeRenamed(const ossia::net::node_base&, std::string);
124  void addressCreated(const ossia::net::parameter_base&);
125  void addressUpdated(const ossia::net::node_base&, ossia::string_view key);
126  void addressRemoved(const ossia::net::parameter_base& addr);
127 
128  Nano::Signal<void(const State::Address&, const ossia::value&)> valueUpdated;
129 
130 public:
131  // These signals are emitted if a device changes from the inside
132  void pathAdded(const State::Address& arg_1)
133  E_SIGNAL(SCORE_LIB_DEVICE_EXPORT, pathAdded, arg_1)
134  void pathUpdated(
135  const State::Address& arg_1, // current address
136  const Device::AddressSettings& arg_2)
137  E_SIGNAL(SCORE_LIB_DEVICE_EXPORT, pathUpdated, arg_1, arg_2) // new data
138  void pathRemoved(const State::Address& arg_1)
139  E_SIGNAL(SCORE_LIB_DEVICE_EXPORT, pathRemoved, arg_1)
140 
141  // In case the whole namespace changed?
142  void namespaceUpdated() E_SIGNAL(SCORE_LIB_DEVICE_EXPORT, namespaceUpdated)
143 
144  // In case the device changed
145  void deviceChanged(ossia::net::device_base* old_dev, ossia::net::device_base* new_dev)
146  E_SIGNAL(SCORE_LIB_DEVICE_EXPORT, deviceChanged, old_dev, new_dev)
147 
148  /* If logging is enabled, these two signals may be sent
149  * when something happens */
150  void logInbound(const QString& arg_1) const
151  E_SIGNAL(SCORE_LIB_DEVICE_EXPORT, logInbound, arg_1)
152  void logOutbound(const QString& arg_1) const
153  E_SIGNAL(SCORE_LIB_DEVICE_EXPORT, logOutbound, arg_1)
154 
155  void connectionChanged(bool arg_1) const
156  E_SIGNAL(SCORE_LIB_DEVICE_EXPORT, connectionChanged, arg_1)
157 
158 protected:
159  Device::DeviceSettings m_settings;
160  DeviceCapas m_capas;
161 
162  using callback_pair = std::pair<
163  ossia::net::parameter_base*,
164  ossia::callback_container<ossia::value_callback>::iterator>;
165  score::hash_map<State::Address, callback_pair> m_callbacks;
166 
167  void removeListening_impl(ossia::net::node_base& node, State::Address addr);
168  void removeListening_impl(
169  ossia::net::node_base& node, State::Address addr, std::vector<State::Address>&);
170  void renameListening_impl(const State::Address& parent, const QString& newName);
171  void setLogging_impl(DeviceLogging) const;
172  void enableCallbacks();
173  void disableCallbacks();
174 
175  // Refresh without handling callbacks
176  Device::Node simple_refresh();
177 
178 private:
179  DeviceLogging m_logging = DeviceLogging::LogNothing;
180  bool m_callbacksEnabled = false;
181 };
182 
183 class SCORE_LIB_DEVICE_EXPORT OwningDeviceInterface : public DeviceInterface
184 {
185 public:
186  ~OwningDeviceInterface() override;
187  void replaceDevice(ossia::net::device_base*);
188  void releaseDevice();
189 
190 protected:
191  void disconnect() override;
192 
193  using DeviceInterface::DeviceInterface;
194 
195  ossia::net::device_base* getDevice() const final override { return m_dev.get(); }
196 
197  std::unique_ptr<ossia::net::device_base> m_dev;
198  bool m_owned{true};
199 };
200 
201 SCORE_LIB_DEVICE_EXPORT ossia::net::node_base*
202 getNodeFromPath(const QStringList& path, ossia::net::device_base& dev);
203 
204 SCORE_LIB_DEVICE_EXPORT ossia::net::node_base*
205 createNodeFromPath(const QStringList& path, ossia::net::device_base& dev);
206 
207 SCORE_LIB_DEVICE_EXPORT Device::Node ToDeviceExplorer(const ossia::net::node_base& node);
208 
209 SCORE_LIB_DEVICE_EXPORT ossia::net::node_base*
210 findNodeFromPath(const Device::Node& path, ossia::net::device_base& dev);
211 
212 SCORE_LIB_DEVICE_EXPORT ossia::net::node_base*
213 findNodeFromPath(const QStringList& path, ossia::net::device_base& dev);
214 
215 SCORE_LIB_DEVICE_EXPORT
216 void releaseDevice(
217  ossia::net::network_context& ctx, std::unique_ptr<ossia::net::device_base> dev);
218 }
Definition: DeviceInterface.hpp:66
Definition: DeviceInterface.hpp:184
Manipulation of Devices from Qt.
Definition: AddressSettings.cpp:14
Utilities for OSSIA data structures.
Definition: DeviceInterface.hpp:33
Base toolkit upon which the software is built.
Definition: Application.cpp:90
Definition: AddressSettings.hpp:49
Definition: DeviceInterface.hpp:41
Definition: DeviceSettings.hpp:16
Definition: AddressSettings.hpp:62
The Address struct.
Definition: Address.hpp:58
The Message struct.
Definition: Message.hpp:15