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