OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
qml_tcp_outbound_socket.hpp
1#pragma once
2#include <ossia/network/context.hpp>
3#include <ossia/network/sockets/tcp_socket.hpp>
4
5#include <ossia-qt/protocols/utils.hpp>
6
7#include <QJSValue>
8#include <QObject>
9#include <QQmlEngine>
10
11#include <nano_observer.hpp>
12
13#include <verdigris>
14
15namespace ossia::qt
16{
17class qml_tcp_outbound_socket
18 : public QObject
19 , public Nano::Observer
20 , public protocols_sender
21{
22 W_OBJECT(qml_tcp_outbound_socket)
23public:
24 struct state
25 {
26 ossia::net::tcp_client socket;
27 std::atomic_bool alive{true};
28
29 state(
30 const ossia::net::outbound_socket_configuration& conf,
31 boost::asio::io_context& ctx)
32 : socket{conf, ctx}
33 {
34 }
35 };
36
37private:
38 std::shared_ptr<state> m_state;
39
40public:
41 ossia::net::tcp_client& socket;
42
43 qml_tcp_outbound_socket(
44 const ossia::net::outbound_socket_configuration& conf,
45 boost::asio::io_context& ctx)
46 : m_state{std::make_shared<state>(conf, ctx)}
47 , socket{m_state->socket}
48 {
49 }
50
51 ~qml_tcp_outbound_socket() { m_state->alive = false; }
52
53 inline boost::asio::io_context& context() noexcept { return m_state->socket.m_context; }
54
55 void open()
56 {
57 try
58 {
59 if(onOpen.isCallable())
60 m_state->socket.on_open.connect<&qml_tcp_outbound_socket::on_open>(this);
61 if(onClose.isCallable())
62 m_state->socket.on_close.connect<&qml_tcp_outbound_socket::on_close>(this);
63 if(onError.isCallable())
64 m_state->socket.on_fail.connect<&qml_tcp_outbound_socket::on_fail>(this);
65 m_state->socket.connect();
66 }
67 catch(const std::exception& e)
68 {
69 if(onError.isCallable())
70 {
71 onError.call({QString::fromStdString(e.what())});
72 }
73 }
74 }
75
76 void write(QByteArray buffer)
77 {
78 auto st = m_state;
79 boost::asio::dispatch(st->socket.m_context, [st, buffer] {
80 if(st->alive)
81 st->socket.write(buffer.data(), buffer.size());
82 });
83 }
84 W_SLOT(write)
85
86 void close() { m_state->socket.close(); }
87 W_SLOT(close)
88
89 void on_open()
90 {
91 if(!m_state->alive)
92 return;
93 ossia::qt::run_async(
94 this, [=, this] { onOpen.call({qjsEngine(this)->newQObject(this)}); },
95 Qt::AutoConnection);
96 }
97 void on_fail()
98 {
99 if(!m_state->alive)
100 return;
101 ossia::qt::run_async(this, [=, this] { onError.call(); }, Qt::AutoConnection);
102 }
103 void on_close()
104 {
105 if(!m_state->alive)
106 return;
107 ossia::qt::run_async(this, [=, this] { onClose.call(); }, Qt::AutoConnection);
108 }
109
110 void osc(QByteArray address, QJSValueList values) { this->send_osc(address, values); }
111 W_SLOT(osc)
112
113 QJSValue onOpen;
114 QJSValue onClose;
115 QJSValue onError;
116 QJSValue onBytes;
117};
118
119}
Definition qml_device.cpp:43