2#include <ossia/network/context.hpp>
3#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
4#include <ossia/network/sockets/unix_socket.hpp>
6#include <ossia-qt/protocols/utils.hpp>
12#include <nano_observer.hpp>
18class qml_unix_datagram_inbound_socket
20 ,
public Nano::Observer
22 W_OBJECT(qml_unix_datagram_inbound_socket)
26 ossia::net::unix_datagram_socket socket;
27 std::atomic_bool alive{
true};
29 state(
const ossia::net::fd_configuration& conf, boost::asio::io_context& ctx)
35 qml_unix_datagram_inbound_socket(
36 const ossia::net::fd_configuration& conf, boost::asio::io_context& ctx)
37 : m_state{std::make_shared<state>(conf, ctx)}
41 ~qml_unix_datagram_inbound_socket() { m_state->alive =
false; }
43 inline boost::asio::io_context& context() noexcept {
return m_state->socket.m_context; }
47 if(onClose.isCallable())
48 m_state->socket.on_close.connect<&qml_unix_datagram_inbound_socket::on_close>(
this);
50 m_state->socket.open();
51 if(onOpen.isCallable())
53 onOpen.call({qjsEngine(
this)->newQObject(
this)});
56 auto self = QPointer{
this};
57 st->socket.receive([st, self](
const char* data, std::size_t sz) {
62 [self, arg = QByteArray(data, sz)] {
65 if(self->onMessage.isCallable())
67 self->onMessage.call({qjsEngine(self.get())->toScriptValue(arg)});
74 void close() { m_state->socket.close(); }
81 ossia::qt::run_async(
this, [=,
this] { onClose.call(); }, Qt::AutoConnection);
90 std::shared_ptr<state> m_state;
93class qml_unix_stream_connection
95 ,
public Nano::Observer
97 W_OBJECT(qml_unix_stream_connection)
101 boost::asio::io_context& context;
102 ossia::net::unix_stream_listener listener;
104 std::atomic_bool alive{
true};
106 state(ossia::net::unix_stream_listener l, boost::asio::io_context& ctx)
108 , listener{std::move(l)}
113 qml_unix_stream_connection(
114 ossia::net::unix_stream_listener listener, boost::asio::io_context& ctx)
115 : m_state{std::make_shared<state>(std::move(listener), ctx)}
119 ~qml_unix_stream_connection() { m_state->alive =
false; }
121 inline boost::asio::io_context& context() noexcept {
return m_state->context; }
123 void write(QByteArray buffer)
126 boost::asio::dispatch(st->context, [st, buffer] {
128 st->listener.write(boost::asio::buffer(buffer.data(), buffer.size()));
133 void startReceive() { receive_impl(m_state, QPointer{
this}); }
138 static void receive_impl(
139 std::shared_ptr<state> st, QPointer<qml_unix_stream_connection> self)
141 st->listener.m_socket.async_read_some(
142 boost::asio::buffer(st->data,
sizeof(st->data)),
143 [self, st](boost::system::error_code ec, std::size_t bytes_transferred) {
148 ossia::qt::run_async(
150 [self, arg = QString::fromUtf8(st->data, bytes_transferred)] {
153 if(self->onMessage.isCallable())
155 self->onMessage.call({arg});
159 receive_impl(st, self);
164 std::shared_ptr<state> m_state;
167class qml_unix_stream_inbound_socket
169 ,
public Nano::Observer
171 W_OBJECT(qml_unix_stream_inbound_socket)
175 ossia::net::unix_stream_server server;
176 std::atomic_bool alive{
true};
178 state(
const ossia::net::fd_configuration& conf, boost::asio::io_context& ctx)
184 qml_unix_stream_inbound_socket(
185 const ossia::net::fd_configuration& conf, boost::asio::io_context& ctx)
186 : m_state{std::make_shared<state>(conf, ctx)}
190 ~qml_unix_stream_inbound_socket() { m_state->alive =
false; }
192 inline boost::asio::io_context& context() noexcept {
return m_state->server.m_context; }
196 accept_impl(m_state, QPointer{
this});
197 if(onOpen.isCallable())
199 onOpen.call({qjsEngine(
this)->newQObject(
this)});
204 m_state->server.m_acceptor.close();
205 if(onClose.isCallable())
214 ossia::qt::run_async(
this, [=,
this] { onClose.call(); }, Qt::AutoConnection);
220 QJSValue onConnection;
223 static void accept_impl(
224 std::shared_ptr<state> st, QPointer<qml_unix_stream_inbound_socket> self)
226 st->server.m_acceptor.async_accept(
228 boost::system::error_code ec,
229 ossia::net::unix_stream_server::proto::socket socket) {
234 ossia::qt::run_async(
236 [self, st, socket = std::move(socket)]()
mutable {
239 auto conn = new qml_unix_stream_connection{
240 ossia::net::unix_stream_listener{std::move(socket)},
241 st->server.m_context};
242 conn->onMessage = self->onConnection;
243 conn->startReceive();
245 if(self->onConnection.isCallable())
247 self->onConnection.call(
248 {qjsEngine(self.get())->newQObject(
static_cast<QObject*
>(conn))});
252 accept_impl(st, self);
257 std::shared_ptr<state> m_state;
Definition qml_device.cpp:43