OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
ossia-qt/protocols/utils.hpp
1#pragma once
2#include <ossia/network/osc/detail/osc_value_write_visitor.hpp>
3#include <ossia/network/osc/detail/osc_packet_processor.hpp>
4#include <ossia/network/sockets/writers.hpp>
5
6#include <ossia-qt/invoke.hpp>
7#include <ossia-qt/js_utilities.hpp>
8
9#include <boost/asio/io_context.hpp>
10
11#include <QPointer>
12#include <QJSEngine>
13
14#define run_on_qt_thread(...) \
15 ossia::qt::run_async(this, [=, this] { __VA_ARGS__; }, Qt::AutoConnection);
16#define run_on_asio_thread(...) \
17 boost::asio::dispatch(this->context(), [=, self = QPointer{this}] { __VA_ARGS__ });
18
19namespace ossia::qt
20{
21struct buffer_writer
22{
23 QByteArray& buffer;
24 void operator()(const char* data, std::size_t sz) const
25 {
26 buffer.append(data, sz);
27 }
28};
29
30struct protocols_sender
31{
32 void send_osc(this auto&& self, QByteArray address, const QJSValueList& values)
33 {
34 auto& sock = *self.socket;
35 using socket_type = std::remove_cvref_t<decltype(sock)>;
36 using writer_type = ossia::net::socket_writer<socket_type>;
37 using send_visitor = ossia::net::osc_value_send_visitor<
38 ossia::net::full_parameter_data, ossia::net::osc_1_0_policy, writer_type>;
39
41 const std::string addr = address.toStdString();
42
43 switch(values.size())
44 {
45 case 0: {
46 ossia::value{ossia::impulse{}}.apply(
47 send_visitor{p, addr, writer_type{sock}});
48 break;
49 }
50 case 1: {
51 auto v = ossia::qt::value_from_js(values[0]);
52 v.apply(send_visitor{p, addr, writer_type{sock}});
53 break;
54 }
55 default: {
56 std::vector<ossia::value> vec;
57 vec.reserve(values.size());
58 for(const auto& v : values)
59 vec.push_back(ossia::qt::value_from_js(v));
60 ossia::value vvec(std::move(vec));
61 vvec.apply(send_visitor{p, addr, writer_type{sock}});
62 }
63 }
64 }
65};
66
67class qml_osc_processor : public QObject
68{
69 W_OBJECT(qml_osc_processor)
70public:
71 explicit qml_osc_processor() { }
72
73 QJSValue onOsc;
74
75 void processMessage(const QByteArray& bv)
76 {
77 if(onOsc.isCallable())
78 {
79 ossia::net::osc_packet_processor<decltype(*this)> processor{*this};
80 processor(bv.data(), bv.size());
81 }
82 }
83 W_SLOT(processMessage)
84
85 void operator()(const oscpack::ReceivedMessage& msg)
86 {
87 QString address = QString::fromUtf8(msg.AddressPattern());
88
89 QJSValueList values;
90 auto* engine = qjsEngine(this);
91 if(!engine)
92 return;
93
94 for(auto it = msg.ArgumentsBegin(); it != msg.ArgumentsEnd(); ++it)
95 values.append(oscArgToQJSValue(*it, *engine));
96
97 onOsc.call({engine->toScriptValue(address), engine->toScriptValue(values)});
98 }
99
100 static QJSValue
101 oscArgToQJSValue(const oscpack::ReceivedMessageArgument& arg, QJSEngine& engine)
102 {
103 switch(arg.TypeTag())
104 {
105 case oscpack::INT32_TYPE_TAG:
106 return QJSValue(arg.AsInt32Unchecked());
107 case oscpack::INT64_TYPE_TAG:
108 return QJSValue((int)arg.AsInt64Unchecked());
109 case oscpack::FLOAT_TYPE_TAG:
110 return QJSValue(arg.AsFloatUnchecked());
111 case oscpack::DOUBLE_TYPE_TAG:
112 return QJSValue(arg.AsDoubleUnchecked());
113 case oscpack::TIME_TAG_TYPE_TAG:
114 return QJSValue((int)arg.AsTimeTagUnchecked());
115 case oscpack::CHAR_TYPE_TAG:
116 return QJSValue(QString(QChar(arg.AsCharUnchecked())));
117 case oscpack::TRUE_TYPE_TAG:
118 return QJSValue(true);
119 case oscpack::FALSE_TYPE_TAG:
120 return QJSValue(false);
121 case oscpack::STRING_TYPE_TAG:
122 return QJSValue(QString::fromUtf8(arg.AsStringUnchecked()));
123 case oscpack::SYMBOL_TYPE_TAG:
124 return QJSValue(QString::fromUtf8(arg.AsSymbolUnchecked()));
125 case oscpack::BLOB_TYPE_TAG: {
126 const void* data{};
127 oscpack::osc_bundle_element_size_t size{};
128 arg.AsBlobUnchecked(data, size);
129 QByteArray blob((const char*)data, size);
130 return engine.toScriptValue(blob);
131 }
132 case oscpack::RGBA_COLOR_TYPE_TAG: {
133 auto c = arg.AsRgbaColorUnchecked();
134 auto array = engine.newArray(4);
135 array.setProperty(0, uint8_t(c >> 24 & 0xFF));
136 array.setProperty(1, uint8_t(c >> 16 & 0xFF));
137 array.setProperty(2, uint8_t(c >> 8 & 0xFF));
138 array.setProperty(3, uint8_t(c & 0xFF));
139 return array;
140 }
141 default:
142 return QJSValue(QJSValue::NullValue);
143 }
144 }
145};
146}
The value class.
Definition value.hpp:173
Definition qml_device.cpp:43
Definition git_info.h:7
Full information about a parameter.
Definition parameter_data.hpp:61