Property.hpp
1 #pragma once
2 #include <State/Value.hpp>
3 #include <State/ValueConversion.hpp>
4 
5 #include <Process/TypeConversion.hpp>
6 
7 #include <LocalTree/BaseCallbackWrapper.hpp>
8 
9 #include <score/tools/Debug.hpp>
10 #include <score/tools/std/Invoke.hpp>
11 
12 #include <ossia/network/base/node.hpp>
13 
14 #include <QApplication>
15 namespace LocalTree
16 {
17 template <typename T>
18 using qt_property_converter_T
19  = ossia::qt_property_converter<std::remove_const_t<std::remove_reference_t<T>>>;
20 
21 template <typename Property>
22 struct PropertyWrapper final : public BaseCallbackWrapper
23 {
24  using model_t = typename Property::model_type;
25  using param_t = typename Property::param_type;
26  model_t& m_model;
27  using converter_t = ossia::qt_property_converter<typename Property::param_type>;
28  PropertyWrapper(ossia::net::parameter_base& param_addr, model_t& obj, QObject* context)
29  : BaseCallbackWrapper{param_addr}
30  , m_model{obj}
31  {
32  QObject::connect(
33  &m_model, Property::notify, context,
34  [this] {
35  auto newVal = converter_t::convert((m_model.*Property::get)());
36  try
37  {
38  auto res = addr.value();
39 
40  if(newVal != res)
41  {
42  addr.set_value_quiet(newVal);
43  addr.push_value();
44  }
45  }
46  catch(...)
47  {
48  }
49  },
50  Qt::QueuedConnection);
51 
52  addr.set_value(converter_t::convert((m_model.*Property::get)()));
53  callbackIt
54  = addr.add_callback([=, m = QPointer<model_t>{&m_model}](const ossia::value& v) {
55  ossia::qt::run_async(qApp, [m, v] {
56  if(m)
57  ((*m).*Property::set)(::State::convert::value<param_t>(v));
58  });
59  });
60  }
61 };
62 
63 template <typename Property, typename Object>
64 auto add_property(ossia::net::node_base& n, Object& obj, QObject* context)
65 {
66  SCORE_ASSERT(!std::string_view(Property::name).empty());
67  constexpr const auto t
68  = ossia::qt_property_converter<typename Property::param_type>::val;
69  auto node = n.create_child(Property::name);
70  SCORE_ASSERT(node);
71 
72  auto addr = node->create_parameter(t);
73  SCORE_ASSERT(addr);
74 
75  addr->set_access(ossia::access_mode::BI);
76  return std::make_unique<PropertyWrapper<Property>>(*addr, obj, context);
77 }
78 
79 template <typename Property, typename Object>
80 auto add_property(
81  ossia::net::node_base& n, Object& obj, const std::string& name, QObject* context)
82 {
83  SCORE_ASSERT(!name.empty());
84  constexpr const auto t
85  = ossia::qt_property_converter<typename Property::param_type>::val;
86  auto node = n.create_child(name);
87  SCORE_ASSERT(node);
88 
89  auto addr = node->create_parameter(t);
90  SCORE_ASSERT(addr);
91 
92  addr->set_access(ossia::access_mode::BI);
93  return std::make_unique<PropertyWrapper<Property>>(*addr, obj, context);
94 }
95 }
Definition: BaseCallbackWrapper.hpp:11
Local tree provides a way to extend the tree given through the Engine::Network::LocalDevice.
Definition: BaseCallbackWrapper.hpp:9
Definition: Property.hpp:23