OSSIA
Open Scenario System for Interactive Application
ossia/network/base/device.hpp
1 #pragma once
2 #include <ossia/detail/config.hpp>
3 
4 #include <ossia/network/base/node.hpp>
6 
7 #include <nano_signal_slot.hpp>
8 
9 namespace ossia
10 {
11 namespace net
12 {
13 struct parameter_data;
14 class protocol_base;
15 
20 {
24  bool change_tree = false;
25 };
26 
27 struct message_origin_identifier;
57 class OSSIA_EXPORT device_base
58 {
59 public:
60  device_base(std::unique_ptr<ossia::net::protocol_base> proto);
61 
62  device_base() = delete;
63  device_base(const device_base&) = delete;
64  device_base(device_base&&) = delete;
65  device_base& operator=(const device_base&) = delete;
66  device_base& operator=(device_base&&) = delete;
67 
68  ossia::net::protocol_base& get_protocol() const;
69 
70  virtual ~device_base();
71 
72  virtual const ossia::net::node_base& get_root_node() const = 0;
73  virtual ossia::net::node_base& get_root_node() = 0;
74 
75  device_capabilities get_capabilities() const { return m_capabilities; }
76 
77  void set_name(const std::string& str) { get_root_node().set_name(str); }
78  std::string get_name() const { return get_root_node().get_name(); }
79 
80  bool has_echo() { return m_echo; }
81 
82  void set_echo(bool echo) { m_echo = echo; }
83 
84  void apply_incoming_message(
85  const message_origin_identifier& id, ossia::net::parameter_base& param,
87 
88  void apply_incoming_message_quiet(
89  const message_origin_identifier& id, ossia::net::parameter_base& param,
91 
92  Nano::Signal<void(node_base&)> on_node_created; // The node being created
93  Nano::Signal<void(node_base&)> on_node_removing; // The node being removed
94  Nano::Signal<void(node_base&, std::string)>
95  on_node_renamed; // Node has the new name, second argument is the old
96  // name
97  Nano::Signal<void(node_base&, const std::string&)>
98  on_attribute_modified; // Second argument is an identifier
99  Nano::Signal<void(const parameter_base&)>
100  on_parameter_created; // The parameter being created
101  Nano::Signal<void(const parameter_base&)>
102  on_parameter_removing; // The node whose parameter was removed
103  Nano::Signal<void(const parameter_base&)> on_message; // A received value
104  Nano::Signal<void(const std::string, const ossia::value& val)>
105  on_unhandled_message; // A received value on a non-existing address
106 
109  Nano::Signal<void(std::string, const parameter_data&)> on_add_node_requested;
110 
113  Nano::Signal<void(std::string, std::string)> on_remove_node_requested;
114 
117  Nano::Signal<void(std::string, std::string)> on_rename_node_requested;
118 
119 protected:
120  std::unique_ptr<ossia::net::protocol_base> m_protocol;
121  device_capabilities m_capabilities{};
122  bool m_echo{false};
123 };
124 
125 template <typename T>
126 void node_base::set(std::string_view str, const T& value)
127 {
128  static_assert(!is_parameter_attribute<T>::value, "No parameter");
129  auto opt = ossia::get_optional_attribute<T>(*this, str);
130  if((opt && *opt != value) || !opt)
131  {
132  ossia::set_attribute((extended_attributes&)*this, str, value);
133  get_device().on_attribute_modified(*this, std::string(str));
134  }
135 }
136 
137 template <typename T>
138 void node_base::set(std::string_view str, T&& value)
139 {
140  static_assert(!is_parameter_attribute<T>::value, "No parameter");
141  auto opt = ossia::get_optional_attribute<T>(*this, str);
142  if((opt && *opt != value) || !opt)
143  {
144  ossia::set_attribute((extended_attributes&)*this, str, std::move(value));
145  get_device().on_attribute_modified(*this, std::string(str));
146  }
147 }
148 
149 template <typename T>
150 void node_base::set(std::string_view str, const std::optional<T>& value)
151 {
152  static_assert(!is_parameter_attribute<T>::value, "No parameter");
153  auto opt = ossia::get_optional_attribute<T>(*this, str);
154  if(opt != value)
155  {
156  ossia::set_optional_attribute((extended_attributes&)*this, str, value);
157  get_device().on_attribute_modified(*this, std::string(str));
158  }
159 }
160 
161 template <typename T>
162 void node_base::set(std::string_view str, std::optional<T>&& value)
163 {
164  static_assert(!is_parameter_attribute<T>::value, "No parameter");
165  auto opt = ossia::get_optional_attribute<T>(*this, str);
166  if(opt != value)
167  {
168  ossia::set_optional_attribute((extended_attributes&)*this, str, std::move(value));
169  get_device().on_attribute_modified(*this, std::string(str));
170  }
171 }
172 
173 template <typename Attribute, typename T>
174 void node_base::set(Attribute a, const T& value)
175 {
176  // We make a copy here to prevent a double conversion
177  // for instance from std::vector<> to value. TODO do the same in the other.
178  typename Attribute::type val = value;
179  a.setter(*this, std::move(val));
180 }
181 
182 template <typename Attribute, typename T>
183 void node_base::set(Attribute a, T& value)
184 {
185  set(a, const_cast<const T&>(value));
186 }
187 
188 template <typename Attribute, typename T>
189 void node_base::set(Attribute a, T&& value)
190 {
191  typename Attribute::type val = std::move(value);
192  a.setter(*this, std::move(val));
193 }
194 }
195 }
Root of a device tree.
Definition: ossia/network/base/device.hpp:58
Nano::Signal< void(std::string, const parameter_data &)> on_add_node_requested
Definition: ossia/network/base/device.hpp:109
Nano::Signal< void(std::string, std::string)> on_remove_node_requested
Definition: ossia/network/base/device.hpp:113
Nano::Signal< void(std::string, std::string)> on_rename_node_requested
Definition: ossia/network/base/device.hpp:117
The node_base class.
Definition: network/base/node.hpp:48
virtual device_base & get_device() const =0
The device in which this node is.
The parameter_base class.
Definition: ossia/network/base/parameter.hpp:48
The protocol_base class.
Definition: protocol.hpp:40
The value class.
Definition: value.hpp:173
Definition: git_info.h:7
void set_optional_attribute(any_map &e, std::string_view str, const std::optional< T > &opt)
Sets an attribute if opt has a value, else remove the attribute.
Definition: any_map.hpp:140
void set_attribute(any_map &e, std::string_view str)
Sets a bool-like attribute. It should be checked for with has_attribute.
Definition: any_map.cpp:11
What a device is able to do.
Definition: ossia/network/base/device.hpp:20
bool change_tree
change_tree : nodes can be added and removed externally.
Definition: ossia/network/base/device.hpp:24
The data that can be found inside a parameter.
Definition: parameter_data.hpp:21