Loading...
Searching...
No Matches
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>
15namespace LocalTree
16{
17template <typename T>
18using qt_property_converter_T
19 = ossia::qt_property_converter<std::remove_const_t<std::remove_reference_t<T>>>;
20
21template <typename Property>
23{
24 using model_t = typename Property::model_type;
25 using param_t = typename Property::param_type;
26 model_t& m_model;
28 {
29 bool active{};
30 bool in_push_from_qt{};
31 bool in_push_from_ossia{};
32 auto push_from_qt() noexcept
33 {
34 struct res
35 {
36 shared_state& self;
37 res(shared_state& self)
38 : self{self}
39 {
40 self.in_push_from_qt = true;
41 }
42 ~res() { self.in_push_from_qt = false; }
43 };
44 return res{*this};
45 }
46 auto push_from_ossia() noexcept
47 {
48 struct res
49 {
50 shared_state& self;
51 res(shared_state& self)
52 : self{self}
53 {
54 self.in_push_from_ossia = true;
55 }
56 ~res() { self.in_push_from_ossia = false; }
57 };
58 return res{*this};
59 }
60 };
61
62 std::shared_ptr<shared_state> state
63 = std::make_shared<shared_state>(shared_state{.active = true});
64 using converter_t = ossia::qt_property_converter<typename Property::param_type>;
65 PropertyWrapper(ossia::net::parameter_base& param_addr, model_t& obj, QObject* context)
66 : BaseCallbackWrapper{param_addr}
67 , m_model{obj}
68 {
69 qtCallback
70 = QObject::connect(&m_model, Property::notify, context, [this, state = state] {
71 if(!state->active)
72 return;
73 if(state->in_push_from_qt)
74 return;
75 if(state->in_push_from_ossia)
76 return;
77 auto push = state->push_from_qt();
78
79 auto newVal = converter_t::convert((m_model.*Property::get)());
80 try
81 {
82 auto res = addr.value();
83
84 if(newVal != res)
85 {
86 addr.push_value(newVal);
87 }
88 }
89 catch(...)
90 {
91 }
92 }, Qt::QueuedConnection);
93
94 addr.set_value(converter_t::convert((m_model.*Property::get)()));
95 callbackIt = addr.add_callback(
96 [=, m = QPointer<model_t>{&m_model}, state = state](const ossia::value& v) {
97 if(!state->active)
98 return;
99 if(state->in_push_from_qt)
100 return;
101 if(state->in_push_from_ossia)
102 return;
103 auto push = state->push_from_ossia();
104 ossia::qt::run_async(qApp, [m, v] {
105 if(m)
106 ((*m).*Property::set)(::State::convert::value<param_t>(v));
107 });
108 });
109 }
110
111 ~PropertyWrapper()
112 {
113 this->clear();
114 state->active = false;
115 auto& node = this->addr.get_node();
116 auto par = node.get_parent();
117 if(par)
118 par->remove_child(node);
119 }
120};
121
122template <typename Property, typename Object>
123auto add_property(ossia::net::node_base& n, Object& obj, QObject* context)
124{
125 SCORE_ASSERT(!std::string_view(Property::name).empty());
126 constexpr const auto t
127 = ossia::qt_property_converter<typename Property::param_type>::val;
128 auto node = n.create_child(Property::name);
129 SCORE_ASSERT(node);
130
131 auto addr = node->create_parameter(t);
132 SCORE_ASSERT(addr);
133
134 addr->set_access(ossia::access_mode::BI);
135 return std::make_unique<PropertyWrapper<Property>>(*addr, obj, context);
136}
137
138template <typename Property, typename Object>
139auto add_property(
140 ossia::net::node_base& n, Object& obj, const std::string& name, QObject* context)
141{
142 SCORE_ASSERT(!name.empty());
143 constexpr const auto t
144 = ossia::qt_property_converter<typename Property::param_type>::val;
145 auto node = n.create_child(name);
146 SCORE_ASSERT(node);
147
148 auto addr = node->create_parameter(t);
149 SCORE_ASSERT(addr);
150
151 addr->set_access(ossia::access_mode::BI);
152 return std::make_unique<PropertyWrapper<Property>>(*addr, obj, context);
153}
154}
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