OSSIA
Open Scenario System for Interactive Application
wrapped_parameter.hpp
1 #pragma once
2 #include <ossia/network/base/osc_address.hpp>
3 #include <ossia/network/base/protocol.hpp>
4 #include <ossia/network/generic/generic_parameter.hpp>
5 
6 namespace ossia::net
7 {
8 
9 template <typename T, typename Parameter_T>
10 class wrapped_node : public ossia::net::node_base
11 {
12  ossia::net::device_base& m_device;
13  ossia::net::node_base* m_parent{};
14  std::unique_ptr<Parameter_T> m_parameter;
15 
16 public:
17  using data_type = T;
18  wrapped_node(
19  T&& data, ossia::net::device_base& aDevice, ossia::net::node_base& aParent)
20  : m_device{aDevice}
21  , m_parent{&aParent}
22  {
23  m_name = data.name;
24  m_oscAddressCache = ossia::net::osc_parameter_string(*this);
25  if(data.valid())
26  m_parameter.reset(new Parameter_T(std::move(data), *this));
27  }
28 
29  wrapped_node(T&& data, ossia::net::device_base& aDevice)
30  : m_device{aDevice}
31  {
32  m_name = data.name;
33  m_oscAddressCache = ossia::net::osc_parameter_string(*this);
34  if(data.valid())
35  m_parameter.reset(new Parameter_T(std::move(data), *this));
36  }
37 
38  ~wrapped_node() override { clear(); }
39 
40  void clear()
41  {
42  about_to_be_deleted(*this);
43 
44  write_lock_t lock{m_mutex};
45  m_children.clear();
46  m_parameter.reset();
47  }
48 
49  device_base& get_device() const final override { return m_device; }
50 
51  node_base* get_parent() const final override { return m_parent; }
52 
53  node_base& set_name(std::string) final override { return *this; }
54 
55  parameter_base* get_parameter() const final override { return m_parameter.get(); }
56 
57  parameter_base* create_parameter(val_type = val_type::IMPULSE) final override
58  {
59  return nullptr;
60  }
61 
62  bool remove_parameter() final override { return false; }
63 
64  void add_child(std::unique_ptr<ossia::net::node_base> p)
65  {
66  if(p)
67  {
68  write_lock_t lock{m_mutex};
69  m_children.push_back(std::move(p));
70  }
71  }
72 
73 private:
74  std::unique_ptr<node_base> make_child(const std::string& name) final override
75  {
76  return std::make_unique<generic_node>(name, m_device, *this);
77  return nullptr;
78  }
79 
80  void removing_child(node_base& node_base) final override { }
81 };
82 
83 template <typename T>
84 class wrapped_parameter : public ossia::net::generic_parameter
85 {
86 public:
87  using base_data_type = typename T::base_data_type;
88 
89  wrapped_parameter(T&& data, ossia::net::node_base& node_base)
90  : generic_parameter{data, node_base}
91  , m_data(std::move(data))
92  {
93  }
94 
95  wrapped_parameter() = delete;
96  wrapped_parameter(const wrapped_parameter& other) = delete;
97  wrapped_parameter(wrapped_parameter&& other) = delete;
98  wrapped_parameter& operator=(const wrapped_parameter& other) = delete;
99  wrapped_parameter& operator=(wrapped_parameter&& other) = delete;
100  ~wrapped_parameter() { callback_container<value_callback>::callbacks_clear(); }
101 
102  const base_data_type& data() const { return m_data; }
103 
104  base_data_type& data() { return m_data; }
105 
106 private:
107  base_data_type m_data;
108 };
109 
110 template <typename Node_T, typename Protocol_T>
111 class wrapped_device final
112  : public ossia::net::device_base
113  , public Node_T
114 {
115 public:
116  wrapped_device() = delete;
117  wrapped_device(const wrapped_device&) = delete;
118  wrapped_device(wrapped_device&&) = delete;
119  wrapped_device& operator=(const wrapped_device&) = delete;
120  wrapped_device& operator=(wrapped_device&&) = delete;
121 
122  wrapped_device(std::unique_ptr<Protocol_T> protocol_base, std::string name)
123  : device_base(std::move(protocol_base))
124  , Node_T{typename Node_T::data_type{name}, *this}
125  {
126  m_capabilities.change_tree = true;
127  m_protocol->set_device(*this);
128  }
129 
130  const ossia::net::node_base& get_root_node() const override { return *this; }
131  ossia::net::node_base& get_root_node() override { return *this; }
132 
133  using Node_T::get_name;
134  using Node_T::set_name;
135 
136  ~wrapped_device()
137  {
138  // TODO c.f. generic_device
139  this->remove_parameter();
140 
141  m_protocol->stop();
142 
143  {
144  write_lock_t lock{this->m_mutex};
145  this->m_children.clear();
146  }
147 
148  // Parameters, etc of the device's own node must also be cleared
149  // before removing the protocol:
150  Node_T::clear();
151 
152  m_protocol.reset();
153  }
154 };
155 }
void callbacks_clear()
clear Clears callbacks.
Definition: callback_container.hpp:203
Root of a device tree.
Definition: ossia/network/base/device.hpp:58
Definition: generic_parameter.hpp:24
generic_parameter(ossia::net::node_base &node_base)
Used for repetition filter.
Definition: generic_parameter.cpp:28
The node_base class.
Definition: network/base/node.hpp:48
Nano::Signal< void(const node_base &)> about_to_be_deleted
The node subclasses must call this in their destructor.
Definition: network/base/node.hpp:201
node_base * add_child(std::unique_ptr< node_base >)
Adds a new child if it can be added.
Definition: node.cpp:140
val_type
Enum to represent the types that a value can take.
Definition: parameter_properties.hpp:16
@ IMPULSE
array<float, 4>
bool change_tree
change_tree : nodes can be added and removed externally.
Definition: ossia/network/base/device.hpp:24