2#if defined(QT_CORE_LIB)
3#include <ossia/detail/optional.hpp>
4#include <ossia/network/base/node.hpp>
5#include <ossia/network/base/parameter_data.hpp>
6#include <ossia/network/common/parameter_properties.hpp>
8#include <ossia/network/generic/generic_node.hpp>
9#include <ossia/network/value/value.hpp>
10#include <ossia/preset/preset.hpp>
12#include <ossia-qt/metatypes.hpp>
13#include <ossia-qt/name_utils.hpp>
22#include <QStringBuilder>
25#include <QVariantList>
26#include <QtGui/QColor>
27#include <QtGui/QQuaternion>
28#include <QtGui/QVector2D>
29#include <QtGui/QVector3D>
30#include <QtGui/QVector4D>
32#if defined(QT_QML_LIB)
33#include <ossia-qt/qml_context.hpp>
37#include <QJSValueIterator>
38#include <QQmlExtensionPlugin>
39#include <QQmlProperty>
44template <std::
size_t N>
52 using type = QVector2D;
57 using type = QVector3D;
62 using type = QVector4D;
65#if defined(QT_QML_LIB)
72struct matching_ossia_enum
78 using type = qml_val_type::val_type;
83 using type = qml_access_mode::access_mode;
88 using type = qml_bounding_mode::bounding_mode;
93 using type = qml_rep_filter::repetition_filter;
101struct OSSIA_EXPORT js_value_inbound_visitor
114 ossia::value operator()(
const std::vector<ossia::value>& v)
const;
125struct OSSIA_EXPORT variant_inbound_visitor
138 ossia::value operator()(
const std::vector<ossia::value>& v)
const;
148struct OSSIA_EXPORT qt_to_ossia
158 ossia::value operator()(QChar v) {
return v.toLatin1(); }
159 ossia::value operator()(
const QString& v) {
return v.toStdString(); }
160 ossia::value operator()(
const QByteArray& v) {
return v.toStdString(); }
164 return make_vec(v.alphaF(), v.redF(), v.greenF(), v.blueF());
166 ossia::value operator()(QPoint v) {
return make_vec(v.x(), v.y()); }
167 ossia::value operator()(QPointF v) {
return make_vec(v.x(), v.y()); }
168 ossia::value operator()(QSize v) {
return make_vec(v.width(), v.height()); }
169 ossia::value operator()(QSizeF v) {
return make_vec(v.width(), v.height()); }
172 return make_vec(v.x(), v.y(), v.width(), v.height());
176 return make_vec(v.x(), v.y(), v.width(), v.height());
180 return make_vec(v.p1().x(), v.p1().y(), v.p2().x(), v.p2().y());
184 return make_vec(v.p1().x(), v.p1().y(), v.p2().x(), v.p2().y());
186 ossia::value operator()(QVector2D v) {
return make_vec(v.x(), v.y()); }
187 ossia::value operator()(QVector3D v) {
return make_vec(v.x(), v.y(), v.z()); }
188 ossia::value operator()(QVector4D v) {
return make_vec(v.x(), v.y(), v.z(), v.w()); }
191 return make_vec(v.scalar(), v.x(), v.y(), v.z());
193 auto operator()(
const QVariantList& v)
195 std::vector<ossia::value> tpl;
196 tpl.reserve(v.size());
199 tpl.push_back(qt_to_ossia{}(val));
203 auto operator()(
const QVariantMap& v)
206 tpl.reserve(v.size());
207 for(
auto it = v.cbegin(); it != v.cend(); ++it)
209 tpl.emplace_back(it.key().toStdString(), qt_to_ossia{}(it.value()));
215 std::vector<ossia::value> tpl;
216 tpl.reserve(v.size());
219 tpl.emplace_back(val.toStdString());
223 ossia::value operator()(
const QDate& v) {
return v.toString().toStdString(); }
228struct ossia_to_qvariant
230 QVariant operator()(QMetaType::Type type,
const ossia::value& ossia_val);
232 QVariant operator()(impulse)
const {
return {}; }
234 QVariant operator()(int32_t val)
const {
return val; }
236 QVariant operator()(
float val)
const {
return val; }
237 QVariant operator()(
bool val)
const {
return val; }
238 QVariant operator()(
char val)
const {
return val; }
240 QVariant operator()(
const std::string& val)
const
242 return QString::fromStdString(val);
245 template <std::
size_t N>
246 [[nodiscard]]
typename QArray<N>::type
247 make_array(
const std::array<float, N>& arr)
const
249 typename QArray<N>::type vec;
251 for(std::size_t i = 0U; i < N; i++)
256 QVariant operator()(vec2f val)
const {
return make_array(val); }
257 QVariant operator()(vec3f val)
const {
return make_array(val); }
258 QVariant operator()(vec4f val)
const {
return make_array(val); }
260 QVariant operator()()
const {
return {}; }
262 QVariant operator()(
const std::vector<ossia::value>& val)
const
265 v.reserve(val.size());
268 v.push_back(e.apply(*
this));
273 QVariant operator()(
const value_map_type& val)
const
276 for(
const auto& [k, e] : val)
278 v.insert(QString::fromStdString(k), e.apply(*
this));
284#if defined(QT_QML_LIB)
290struct OSSIA_EXPORT js_value_outbound_visitor
294 [[nodiscard]] QJSValue to_enum(qml_val_type::val_type t)
const;
296 QJSValue operator()(impulse)
const;
298 QJSValue operator()(int32_t val)
const;
299 QJSValue operator()(
float val)
const;
300 QJSValue operator()(
bool val)
const;
302 QJSValue operator()(
const std::string& val)
const;
304 [[nodiscard]] QJSValue make_list(
const std::vector<ossia::value>& arr)
const;
306 QJSValue operator()(
const std::vector<ossia::value>& val)
const;
307 QJSValue operator()(
const value_map_type& val)
const;
309 template <std::
size_t N>
310 QJSValue make_array(
const std::array<float, N>& arr)
const
312 auto array = engine.newArray(arr.size());
314 for(
auto child : arr)
316 array.setProperty(i++, child);
322 QJSValue operator()(vec2f val)
const;
323 QJSValue operator()(vec3f val)
const;
324 QJSValue operator()(vec4f val)
const;
326 QJSValue operator()()
const;
336struct OSSIA_EXPORT js_string_outbound_visitor
338 QString operator()(impulse)
const;
340 QString operator()(int32_t val)
const;
342 QString operator()(
float val)
const;
343 QString operator()(
bool val)
const;
344 QString operator()(
char val)
const;
346 QString operator()(
const std::string& val)
const;
348 QString operator()(
const std::vector<ossia::value>& val)
const;
349 QString operator()(
const value_map_type& val)
const;
351 template <std::
size_t N>
352 QString make_array(
const std::array<float, N>& arr)
const
354 static_assert(N > 0,
"N <= 0");
357 s += QString::number(arr[0]);
358 for(std::size_t i = 1; i < N; i++)
360 s +=
", " % QString::number(arr[i]);
366 QString operator()(vec2f val)
const;
367 QString operator()(vec3f val)
const;
368 QString operator()(vec4f val)
const;
370 QString operator()()
const;
372struct OSSIA_EXPORT js_string_unquoted_outbound_visitor : js_string_outbound_visitor
374 using js_string_outbound_visitor::operator();
375 QString operator()(
char val)
const;
376 QString operator()(
const std::string& val)
const;
379OSSIA_EXPORT
ossia::value value_from_js(
const QJSValue& v);
383 return cur.apply(js_value_inbound_visitor{v});
386inline QJSValue value_to_js_value(
const ossia::value& cur, QJSEngine& engine)
388 return cur.apply(js_value_outbound_visitor{engine});
391inline QString value_to_js_string(
const ossia::value& cur)
393 return cur.apply(js_string_outbound_visitor{});
396inline QString value_to_js_string_unquoted(
const ossia::value& cur)
398 return cur.apply(js_string_unquoted_outbound_visitor{});
408std::optional<T> get_enum(
const QJSValue& val)
412 const int n = val.toInt();
414 && n < QMetaEnum::fromType<
typename matching_ossia_enum<T>::type>().keyCount())
416 return static_cast<T
>(n);
438template <
typename Device_T,
typename Node_T,
typename Protocol_T>
440void create_device(Device_T& device, QJSValue root);
442template <
typename Device_T,
typename Node_T,
typename Protocol_T>
444void create_node_rec(QJSValue js, Device_T& device, Node_T& parent);
446template <
typename Device_T,
typename Node_T,
typename Protocol_T>
448void create_device(Device_T& device, QJSValue root)
453 QJSValueIterator it(root);
457 create_node_rec<Device_T, Node_T, Protocol_T>(
458 it.value(), device,
static_cast<Node_T&
>(device.get_root_node()));
462template <
typename Device_T,
typename Node_T,
typename Protocol_T>
464void create_node_rec(QJSValue js, Device_T& device, Node_T& parent)
466 auto data = Protocol_T::read_data(js);
467 if(data.name.empty())
470 auto node =
new Node_T{std::move(data), device, parent};
471 parent.add_child(std::unique_ptr<ossia::net::node_base>(node));
473 device.on_node_created(*node);
475 QJSValue children = js.property(
"children");
476 if(!children.isArray())
479 QJSValueIterator it(children);
483 create_node_rec<Device_T, Node_T, Protocol_T>(it.value(), device, *node);
487template <
typename Data>
489struct deferred_js_node
492 std::vector<deferred_js_node> children;
495template <
typename Data,
typename Protocol_T>
497void create_node_deferred_rec(QJSValue js, deferred_js_node<Data>& parent)
499 auto data = Protocol_T::read_data(js);
500 if(data.name.empty())
503 parent.children.push_back(deferred_js_node<Data>{std::move(data), {}});
505 QJSValue children = js.property(
"children");
506 if(!children.isArray())
509 deferred_js_node<Data>& node = parent.children.back();
511 node.children.reserve(children.property(
"length").toInt());
512 QJSValueIterator it(children);
516 create_node_deferred_rec<Data, Protocol_T>(it.value(), node);
520template <
typename Protocol_T>
522auto create_device_nodes_deferred(QJSValue root)
524 using data_type =
decltype(Protocol_T::read_data(root));
525 deferred_js_node<data_type> node_root;
530 node_root.children.reserve(root.property(
"length").toInt());
531 QJSValueIterator it(root);
535 create_node_deferred_rec<data_type, Protocol_T>(it.value(), node_root);
541template <
typename Device_T,
typename Node_T,
typename Data>
543void apply_deferred_device_rec(
544 Device_T& device, Node_T& parent_ossia, deferred_js_node<Data>& node_js)
546 auto node =
new Node_T{std::move(node_js.data), device, parent_ossia};
547 parent_ossia.add_child(std::unique_ptr<ossia::net::node_base>(node));
549 for(
auto& cld : node_js.children)
551 apply_deferred_device_rec<Device_T, Node_T, Data>(device, *node, cld);
557 for(
auto& node : root_node.children())
559 device.on_node_created(*node);
560 if(
auto p = node->get_parameter())
561 device.on_parameter_created(*p);
563 device_creation_notify_recursively(device, *node);
567template <
typename Device_T,
typename Node_T,
typename Data>
569void apply_deferred_device(Device_T& device, deferred_js_node<Data>& root)
571 auto& nroot =
static_cast<Node_T&
>(device.get_root_node());
572 for(
auto& cld : root.children)
574 apply_deferred_device_rec<Device_T, Node_T, Data>(device, nroot, cld);
577 device_creation_notify_recursively(device, nroot);
580template <
typename Methods>
581QMetaObject::Connection connectSignalToMatchingMethod(
582 const QMetaMethod& sig, Methods& meth, QObject* source, QObject* target)
584 switch(sig.parameterCount())
587 return QObject::connect(source, sig, target, meth[QMetaType::UnknownType]);
590 auto t = sig.parameterType(0);
592 auto method_it = meth.find((QMetaType::Type)t);
593 if(method_it != meth.end())
595 return QObject::connect(source, sig, target, method_it->second);
603template <
typename Methods>
604QMetaObject::Connection connectSignalToMatchingMethod(
605 const QQmlProperty& prop, Methods& methods, QMetaMethod variantMethod,
606 QObject* source, QObject* target)
608 auto meth = prop.method();
610 switch(meth.parameterCount())
613 return QObject::connect(source, prop.method(), target, variantMethod);
616 auto t = meth.parameterType(0);
618 auto method_it = methods.find((QMetaType::Type)t);
619 if(method_it != methods.end())
621 return QObject::connect(source, prop.method(), target, method_it->second);
631OSSIA_EXPORT QDebug operator<<(QDebug s,
const ossia::value& v);
633W_REGISTER_ARGTYPE(QJSValue)
635Q_DECLARE_METATYPE(QJSValueList)
636W_REGISTER_ARGTYPE(QJSValueList)
639#error This file requires Qt.
Root of a device tree.
Definition ossia/network/base/device.hpp:58
The parameter_base class.
Definition ossia/network/base/parameter.hpp:48
The value class.
Definition value.hpp:173
val_type
Enum to represent the types that a value can take.
Definition parameter_properties.hpp:16
repetition_filter
If enabled, sending twice the same value will only send it once by network.
Definition parameter_properties.hpp:70
bounding_mode
Address behaviors at crossing domain boundaries.
Definition parameter_properties.hpp:56
access_mode
Address behaviors at crossing domain boundaries time.
Definition parameter_properties.hpp:46
The data that can be found inside a parameter.
Definition parameter_data.hpp:21