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));
307OSSIA_EXPORT
void registerQVariantConverters();
309#if defined(QT_QML_LIB)
315struct OSSIA_EXPORT js_value_outbound_visitor
319 [[nodiscard]] QJSValue to_enum(qml_val_type::val_type t)
const;
321 QJSValue operator()(impulse)
const;
323 QJSValue operator()(int32_t val)
const;
324 QJSValue operator()(
float val)
const;
325 QJSValue operator()(
bool val)
const;
327 QJSValue operator()(
const std::string& val)
const;
329 [[nodiscard]] QJSValue make_list(
const std::vector<ossia::value>& arr)
const;
331 QJSValue operator()(
const std::vector<ossia::value>& val)
const;
332 QJSValue operator()(
const value_map_type& val)
const;
334 template <std::
size_t N>
335 QJSValue make_array(
const std::array<float, N>& arr)
const
337 auto array = engine.newArray(arr.size());
339 for(
auto child : arr)
341 array.setProperty(i++, child);
347 QJSValue operator()(vec2f val)
const;
348 QJSValue operator()(vec3f val)
const;
349 QJSValue operator()(vec4f val)
const;
351 QJSValue operator()()
const;
361struct OSSIA_EXPORT js_string_outbound_visitor
363 QString operator()(impulse)
const;
365 QString operator()(int32_t val)
const;
367 QString operator()(
float val)
const;
368 QString operator()(
bool val)
const;
369 QString operator()(
char val)
const;
371 QString operator()(
const std::string& val)
const;
373 QString operator()(
const std::vector<ossia::value>& val)
const;
374 QString operator()(
const value_map_type& val)
const;
376 template <std::
size_t N>
377 QString make_array(
const std::array<float, N>& arr)
const
379 static_assert(N > 0,
"N <= 0");
382 s += QString::number(arr[0]);
383 for(std::size_t i = 1; i < N; i++)
385 s +=
", " % QString::number(arr[i]);
391 QString operator()(vec2f val)
const;
392 QString operator()(vec3f val)
const;
393 QString operator()(vec4f val)
const;
395 QString operator()()
const;
397struct OSSIA_EXPORT js_string_unquoted_outbound_visitor : js_string_outbound_visitor
399 using js_string_outbound_visitor::operator();
400 QString operator()(
char val)
const;
401 QString operator()(
const std::string& val)
const;
404OSSIA_EXPORT
ossia::value value_from_js(
const QJSValue& v);
408 return cur.apply(js_value_inbound_visitor{v});
411inline QJSValue value_to_js_value(
const ossia::value& cur, QJSEngine& engine)
413 return cur.apply(js_value_outbound_visitor{engine});
416inline QString value_to_js_string(
const ossia::value& cur)
418 return cur.apply(js_string_outbound_visitor{});
421inline QString value_to_js_string_unquoted(
const ossia::value& cur)
423 return cur.apply(js_string_unquoted_outbound_visitor{});
433std::optional<T> get_enum(
const QJSValue& val)
437 const int n = val.toInt();
439 && n < QMetaEnum::fromType<
typename matching_ossia_enum<T>::type>().keyCount())
441 return static_cast<T
>(n);
463template <
typename Device_T,
typename Node_T,
typename Protocol_T>
465void create_device(Device_T& device, QJSValue root);
467template <
typename Device_T,
typename Node_T,
typename Protocol_T>
469void create_node_rec(QJSValue js, Device_T& device, Node_T& parent);
471template <
typename Device_T,
typename Node_T,
typename Protocol_T>
473void create_device(Device_T& device, QJSValue root)
478 QJSValueIterator it(root);
482 create_node_rec<Device_T, Node_T, Protocol_T>(
483 it.value(), device,
static_cast<Node_T&
>(device.get_root_node()));
487template <
typename Device_T,
typename Node_T,
typename Protocol_T>
489void create_node_rec(QJSValue js, Device_T& device, Node_T& parent)
491 auto data = Protocol_T::read_data(js);
492 if(data.name.empty())
495 auto node =
new Node_T{std::move(data), device, parent};
496 parent.add_child(std::unique_ptr<ossia::net::node_base>(node));
498 device.on_node_created(*node);
500 QJSValue children = js.property(
"children");
501 if(!children.isArray())
504 QJSValueIterator it(children);
508 create_node_rec<Device_T, Node_T, Protocol_T>(it.value(), device, *node);
512template <
typename Data>
514struct deferred_js_node
517 std::vector<deferred_js_node> children;
520template <
typename Data,
typename Protocol_T>
522void create_node_deferred_rec(QJSValue js, deferred_js_node<Data>& parent)
524 auto data = Protocol_T::read_data(js);
525 if(data.name.empty())
528 parent.children.push_back(deferred_js_node<Data>{std::move(data), {}});
530 QJSValue children = js.property(
"children");
531 if(!children.isArray())
534 deferred_js_node<Data>& node = parent.children.back();
536 node.children.reserve(children.property(
"length").toInt());
537 QJSValueIterator it(children);
541 create_node_deferred_rec<Data, Protocol_T>(it.value(), node);
545template <
typename Protocol_T>
547auto create_device_nodes_deferred(QJSValue root)
549 using data_type =
decltype(Protocol_T::read_data(root));
550 deferred_js_node<data_type> node_root;
555 node_root.children.reserve(root.property(
"length").toInt());
556 QJSValueIterator it(root);
560 create_node_deferred_rec<data_type, Protocol_T>(it.value(), node_root);
566template <
typename Device_T,
typename Node_T,
typename Data>
568void apply_deferred_device_rec(
569 Device_T& device, Node_T& parent_ossia, deferred_js_node<Data>& node_js)
571 auto node =
new Node_T{std::move(node_js.data), device, parent_ossia};
572 parent_ossia.add_child(std::unique_ptr<ossia::net::node_base>(node));
574 for(
auto& cld : node_js.children)
576 apply_deferred_device_rec<Device_T, Node_T, Data>(device, *node, cld);
582 for(
auto& node : root_node.children())
584 device.on_node_created(*node);
585 if(
auto p = node->get_parameter())
586 device.on_parameter_created(*p);
588 device_creation_notify_recursively(device, *node);
592template <
typename Device_T,
typename Node_T,
typename Data>
594void apply_deferred_device(Device_T& device, deferred_js_node<Data>& root)
596 auto& nroot =
static_cast<Node_T&
>(device.get_root_node());
597 for(
auto& cld : root.children)
599 apply_deferred_device_rec<Device_T, Node_T, Data>(device, nroot, cld);
602 device_creation_notify_recursively(device, nroot);
605template <
typename Methods>
606QMetaObject::Connection connectSignalToMatchingMethod(
607 const QMetaMethod& sig, Methods& meth, QObject* source, QObject* target)
609 switch(sig.parameterCount())
612 return QObject::connect(source, sig, target, meth[QMetaType::UnknownType]);
615 auto t = sig.parameterType(0);
617 auto method_it = meth.find((QMetaType::Type)t);
618 if(method_it != meth.end())
620 return QObject::connect(source, sig, target, method_it->second);
628template <
typename Methods>
629QMetaObject::Connection connectSignalToMatchingMethod(
630 const QQmlProperty& prop, Methods& methods, QMetaMethod variantMethod,
631 QObject* source, QObject* target)
633 auto meth = prop.method();
635 switch(meth.parameterCount())
638 return QObject::connect(source, prop.method(), target, variantMethod);
641 auto t = meth.parameterType(0);
643 auto method_it = methods.find((QMetaType::Type)t);
644 if(method_it != methods.end())
646 return QObject::connect(source, prop.method(), target, method_it->second);
656OSSIA_EXPORT QDebug operator<<(QDebug s,
const ossia::value& v);
658W_REGISTER_ARGTYPE(QJSValue)
660Q_DECLARE_METATYPE(QJSValueList)
661W_REGISTER_ARGTYPE(QJSValueList)
664#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