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()(
unsigned char v) {
return (
char)v; }
159 ossia::value operator()(
signed char v) {
return (
char)v; }
160 ossia::value operator()(QChar v) {
return v.toLatin1(); }
161 ossia::value operator()(
const QString& v) {
return v.toStdString(); }
162 ossia::value operator()(
const QByteArray& v) {
return v.toStdString(); }
165 std::vector<ossia::value> tpl;
166 tpl.reserve(v.size());
169 tpl.push_back(val.toStdString());
177 return make_vec(v.alphaF(), v.redF(), v.greenF(), v.blueF());
179 ossia::value operator()(QPoint v) {
return make_vec(v.x(), v.y()); }
180 ossia::value operator()(QPointF v) {
return make_vec(v.x(), v.y()); }
181 ossia::value operator()(QSize v) {
return make_vec(v.width(), v.height()); }
182 ossia::value operator()(QSizeF v) {
return make_vec(v.width(), v.height()); }
185 return make_vec(v.x(), v.y(), v.width(), v.height());
189 return make_vec(v.x(), v.y(), v.width(), v.height());
193 return make_vec(v.p1().x(), v.p1().y(), v.p2().x(), v.p2().y());
197 return make_vec(v.p1().x(), v.p1().y(), v.p2().x(), v.p2().y());
199 ossia::value operator()(QVector2D v) {
return make_vec(v.x(), v.y()); }
200 ossia::value operator()(QVector3D v) {
return make_vec(v.x(), v.y(), v.z()); }
201 ossia::value operator()(QVector4D v) {
return make_vec(v.x(), v.y(), v.z(), v.w()); }
204 return make_vec(v.scalar(), v.x(), v.y(), v.z());
206 auto operator()(
const QVariantList& v)
208 std::vector<ossia::value> tpl;
209 tpl.reserve(v.size());
212 tpl.push_back(qt_to_ossia{}(val));
216 auto operator()(
const QVariantMap& v)
219 tpl.reserve(v.size());
220 for(
auto it = v.cbegin(); it != v.cend(); ++it)
222 tpl.emplace_back(it.key().toStdString(), qt_to_ossia{}(it.value()));
226 auto operator()(
const QVariantHash& v)
229 tpl.reserve(v.size());
230 for(
auto it = v.cbegin(); it != v.cend(); ++it)
232 tpl.emplace_back(it.key().toStdString(), qt_to_ossia{}(it.value()));
238 std::vector<ossia::value> tpl;
239 tpl.reserve(v.size());
242 tpl.emplace_back(val.toStdString());
246 ossia::value operator()(
const QDate& v) {
return v.toString().toStdString(); }
251struct ossia_to_qvariant
253 QVariant operator()(QMetaType::Type type,
const ossia::value& ossia_val);
255 QVariant operator()(impulse)
const {
return {}; }
257 QVariant operator()(int32_t val)
const {
return val; }
259 QVariant operator()(
float val)
const {
return val; }
260 QVariant operator()(
bool val)
const {
return val; }
261 QVariant operator()(
char val)
const {
return val; }
263 QVariant operator()(
const std::string& val)
const
265 return QString::fromStdString(val);
268 template <std::
size_t N>
269 [[nodiscard]]
typename QArray<N>::type
270 make_array(
const std::array<float, N>& arr)
const
272 typename QArray<N>::type vec;
274 for(std::size_t i = 0U; i < N; i++)
279 QVariant operator()(vec2f val)
const {
return make_array(val); }
280 QVariant operator()(vec3f val)
const {
return make_array(val); }
281 QVariant operator()(vec4f val)
const {
return make_array(val); }
283 QVariant operator()()
const {
return {}; }
285 QVariant operator()(
const std::vector<ossia::value>& val)
const
288 v.reserve(val.size());
291 v.push_back(e.apply(*
this));
296 QVariant operator()(
const value_map_type& val)
const
299 for(
const auto& [k, e] : val)
301 v.insert(QString::fromStdString(k), e.apply(*
this));
307#if defined(QT_QML_LIB)
313struct OSSIA_EXPORT js_value_outbound_visitor
317 [[nodiscard]] QJSValue to_enum(qml_val_type::val_type t)
const;
319 QJSValue operator()(impulse)
const;
321 QJSValue operator()(int32_t val)
const;
322 QJSValue operator()(
float val)
const;
323 QJSValue operator()(
bool val)
const;
325 QJSValue operator()(
const std::string& val)
const;
327 [[nodiscard]] QJSValue make_list(
const std::vector<ossia::value>& arr)
const;
329 QJSValue operator()(
const std::vector<ossia::value>& val)
const;
330 QJSValue operator()(
const value_map_type& val)
const;
332 template <std::
size_t N>
333 QJSValue make_array(
const std::array<float, N>& arr)
const
335 auto array = engine.newArray(arr.size());
337 for(
auto child : arr)
339 array.setProperty(i++, child);
345 QJSValue operator()(vec2f val)
const;
346 QJSValue operator()(vec3f val)
const;
347 QJSValue operator()(vec4f val)
const;
349 QJSValue operator()()
const;
359struct OSSIA_EXPORT js_string_outbound_visitor
361 QString operator()(impulse)
const;
363 QString operator()(int32_t val)
const;
365 QString operator()(
float val)
const;
366 QString operator()(
bool val)
const;
367 QString operator()(
char val)
const;
369 QString operator()(
const std::string& val)
const;
371 QString operator()(
const std::vector<ossia::value>& val)
const;
372 QString operator()(
const value_map_type& val)
const;
374 template <std::
size_t N>
375 QString make_array(
const std::array<float, N>& arr)
const
377 static_assert(N > 0,
"N <= 0");
380 s += QString::number(arr[0]);
381 for(std::size_t i = 1; i < N; i++)
383 s +=
", " % QString::number(arr[i]);
389 QString operator()(vec2f val)
const;
390 QString operator()(vec3f val)
const;
391 QString operator()(vec4f val)
const;
393 QString operator()()
const;
395struct OSSIA_EXPORT js_string_unquoted_outbound_visitor : js_string_outbound_visitor
397 using js_string_outbound_visitor::operator();
398 QString operator()(
char val)
const;
399 QString operator()(
const std::string& val)
const;
402OSSIA_EXPORT
ossia::value value_from_js(
const QJSValue& v);
406 return cur.apply(js_value_inbound_visitor{v});
409inline QJSValue value_to_js_value(
const ossia::value& cur, QJSEngine& engine)
411 return cur.apply(js_value_outbound_visitor{engine});
414inline QString value_to_js_string(
const ossia::value& cur)
416 return cur.apply(js_string_outbound_visitor{});
419inline QString value_to_js_string_unquoted(
const ossia::value& cur)
421 return cur.apply(js_string_unquoted_outbound_visitor{});
431std::optional<T> get_enum(
const QJSValue& val)
435 const int n = val.toInt();
437 && n < QMetaEnum::fromType<
typename matching_ossia_enum<T>::type>().keyCount())
439 return static_cast<T
>(n);
461template <
typename Device_T,
typename Node_T,
typename Protocol_T>
463void create_device(Device_T& device, QJSValue root);
465template <
typename Device_T,
typename Node_T,
typename Protocol_T>
467void create_node_rec(QJSValue js, Device_T& device, Node_T& parent);
469template <
typename Device_T,
typename Node_T,
typename Protocol_T>
471void create_device(Device_T& device, QJSValue root)
476 QJSValueIterator it(root);
480 create_node_rec<Device_T, Node_T, Protocol_T>(
481 it.value(), device,
static_cast<Node_T&
>(device.get_root_node()));
485template <
typename Device_T,
typename Node_T,
typename Protocol_T>
487void create_node_rec(QJSValue js, Device_T& device, Node_T& parent)
489 auto data = Protocol_T::read_data(js);
490 if(data.name.empty())
493 auto node =
new Node_T{std::move(data), device, parent};
494 parent.add_child(std::unique_ptr<ossia::net::node_base>(node));
496 device.on_node_created(*node);
498 QJSValue children = js.property(
"children");
499 if(!children.isArray())
502 QJSValueIterator it(children);
506 create_node_rec<Device_T, Node_T, Protocol_T>(it.value(), device, *node);
510template <
typename Data>
512struct deferred_js_node
515 std::vector<deferred_js_node> children;
518template <
typename Data,
typename Protocol_T>
520void create_node_deferred_rec(QJSValue js, deferred_js_node<Data>& parent)
522 auto data = Protocol_T::read_data(js);
523 if(data.name.empty())
526 parent.children.push_back(deferred_js_node<Data>{std::move(data), {}});
528 QJSValue children = js.property(
"children");
529 if(!children.isArray())
532 deferred_js_node<Data>& node = parent.children.back();
534 node.children.reserve(children.property(
"length").toInt());
535 QJSValueIterator it(children);
539 create_node_deferred_rec<Data, Protocol_T>(it.value(), node);
543template <
typename Protocol_T>
545auto create_device_nodes_deferred(QJSValue root)
547 using data_type =
decltype(Protocol_T::read_data(root));
548 deferred_js_node<data_type> node_root;
553 node_root.children.reserve(root.property(
"length").toInt());
554 QJSValueIterator it(root);
558 create_node_deferred_rec<data_type, Protocol_T>(it.value(), node_root);
564template <
typename Device_T,
typename Node_T,
typename Data>
566void apply_deferred_device_rec(
567 Device_T& device, Node_T& parent_ossia, deferred_js_node<Data>& node_js)
569 auto node =
new Node_T{std::move(node_js.data), device, parent_ossia};
570 parent_ossia.add_child(std::unique_ptr<ossia::net::node_base>(node));
572 for(
auto& cld : node_js.children)
574 apply_deferred_device_rec<Device_T, Node_T, Data>(device, *node, cld);
580 for(
auto& node : root_node.children())
582 device.on_node_created(*node);
583 if(
auto p = node->get_parameter())
584 device.on_parameter_created(*p);
586 device_creation_notify_recursively(device, *node);
590template <
typename Device_T,
typename Node_T,
typename Data>
592void apply_deferred_device(Device_T& device, deferred_js_node<Data>& root)
594 auto& nroot =
static_cast<Node_T&
>(device.get_root_node());
595 for(
auto& cld : root.children)
597 apply_deferred_device_rec<Device_T, Node_T, Data>(device, nroot, cld);
600 device_creation_notify_recursively(device, nroot);
603template <
typename Methods>
604QMetaObject::Connection connectSignalToMatchingMethod(
605 const QMetaMethod& sig, Methods& meth, QObject* source, QObject* target)
607 switch(sig.parameterCount())
610 return QObject::connect(source, sig, target, meth[QMetaType::UnknownType]);
613 auto t = sig.parameterType(0);
615 auto method_it = meth.find((QMetaType::Type)t);
616 if(method_it != meth.end())
618 return QObject::connect(source, sig, target, method_it->second);
626template <
typename Methods>
627QMetaObject::Connection connectSignalToMatchingMethod(
628 const QQmlProperty& prop, Methods& methods, QMetaMethod variantMethod,
629 QObject* source, QObject* target)
631 auto meth = prop.method();
633 switch(meth.parameterCount())
636 return QObject::connect(source, prop.method(), target, variantMethod);
639 auto t = meth.parameterType(0);
641 auto method_it = methods.find((QMetaType::Type)t);
642 if(method_it != methods.end())
644 return QObject::connect(source, prop.method(), target, method_it->second);
654OSSIA_EXPORT QDebug operator<<(QDebug s,
const ossia::value& v);
656W_REGISTER_ARGTYPE(QJSValue)
658Q_DECLARE_METATYPE(QJSValueList)
659W_REGISTER_ARGTYPE(QJSValueList)
662#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
Definition qml_device.cpp:43
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