OSSIA
Open Scenario System for Interactive Application
serial_protocol.hpp
1 #pragma once
3 #include <ossia/detail/variant.hpp>
4 #include <ossia/network/base/message_queue.hpp>
5 #include <ossia/network/base/protocol.hpp>
6 #include <ossia/network/context.hpp>
7 #include <ossia/network/generic/wrapped_parameter.hpp>
8 #include <ossia/network/sockets/line_framing.hpp>
9 #include <ossia/network/sockets/no_framing.hpp>
10 #include <ossia/network/sockets/serial_socket.hpp>
11 #include <ossia/network/sockets/size_prefix_framing.hpp>
12 #include <ossia/network/sockets/slip_framing.hpp>
13 
14 #include <ossia-qt/js_utilities.hpp>
15 
16 #include <boost/asio/error.hpp>
17 #include <boost/asio/streambuf.hpp>
18 
19 #include <QObject>
20 #include <QSerialPort>
21 #include <QThread>
22 
23 #include <verdigris>
24 
25 class QQmlEngine;
26 class QQmlComponent;
27 
28 namespace ossia
29 {
30 namespace net
31 {
32 struct serial_parameter_data_base
33 {
34  serial_parameter_data_base() = default;
35  serial_parameter_data_base(const serial_parameter_data_base&) = default;
36  serial_parameter_data_base(serial_parameter_data_base&&) = default;
37  serial_parameter_data_base& operator=(const serial_parameter_data_base&) = default;
38  serial_parameter_data_base& operator=(serial_parameter_data_base&&) = default;
39  serial_parameter_data_base(const QJSValue& val)
40  {
41  request = val.property("request");
42  if(!request.isString() && !request.isCallable())
43  {
44  request = val.property("name");
45  }
46  }
47 
48  QJSValue request;
49 };
50 struct serial_parameter_data final
51  : public parameter_data
52  , public serial_parameter_data_base
53 {
54  using base_data_type = serial_parameter_data_base;
55  serial_parameter_data() = default;
56  serial_parameter_data(const serial_parameter_data&) = default;
57  serial_parameter_data(serial_parameter_data&&) = default;
58  serial_parameter_data& operator=(const serial_parameter_data&) = default;
59  serial_parameter_data& operator=(serial_parameter_data&&) = default;
60 
61  serial_parameter_data(const std::string& name)
62  : parameter_data{name}
63  {
64  }
65 
66  serial_parameter_data(const QJSValue& val)
67  : parameter_data{ossia::qt::make_parameter_data(val)}
68  , serial_parameter_data_base{val}
69  {
70  }
71 
72  bool valid() const noexcept
73  {
74  return request.isString() || request.isCallable() || type;
75  }
76 };
77 
78 struct no_framing_socket : ossia::net::serial_socket<no_framing>
79 {
80  using serial_socket::serial_socket;
81 };
82 struct size_framing_socket : ossia::net::serial_socket<size_prefix_framing>
83 {
84  using serial_socket::serial_socket;
85 };
86 struct slip_framing_socket : ossia::net::serial_socket<slip_framing>
87 {
88  using serial_socket::serial_socket;
89 };
90 struct line_framing_socket : ossia::net::serial_socket<line_framing>
91 {
92  using serial_socket::serial_socket;
93 };
94 
95 using framed_serial_socket = ossia::slow_variant<
96  no_framing_socket, size_framing_socket, slip_framing_socket, line_framing_socket>;
97 
98 struct serial_protocol_configuration
99 {
100  ossia::net::framing framing;
101  std::string line_framing_delimiter;
102 
103  serial_configuration transport;
104 };
105 
106 class OSSIA_EXPORT serial_wrapper final : public QObject
107 {
108  W_OBJECT(serial_wrapper)
109 
110 public:
111  serial_wrapper(
112  const network_context_ptr& ctx,
113  const ossia::net::serial_protocol_configuration& port);
114  ~serial_wrapper() noexcept;
115 
116  void write(QByteArray arg_1) E_SIGNAL(OSSIA_EXPORT, write, arg_1);
117  void read(QString txt, QByteArray raw) E_SIGNAL(OSSIA_EXPORT, read, txt, raw);
118 
119  void on_write(const QByteArray& b) noexcept;
120  W_SLOT(on_write)
121 
122  void on_read(const QByteArray& arr);
123  W_SLOT(on_read)
124 
125  void close();
126 
127 private:
128  framed_serial_socket make_socket(
129  const network_context_ptr& ctx,
130  const ossia::net::serial_protocol_configuration& port);
131  framed_serial_socket m_socket;
132  bool m_open{};
133 };
134 
135 class serial_protocol;
136 struct serial_protocol_object;
137 
138 using serial_parameter = wrapped_parameter<serial_parameter_data>;
139 using serial_node = ossia::net::wrapped_node<serial_parameter_data, serial_parameter>;
140 class OSSIA_EXPORT serial_protocol final
141  : public QObject
143 {
144 public:
145  // Param : the name of the serial port
146  serial_protocol(
147  const ossia::net::network_context_ptr&, const QByteArray& code,
148  const ossia::net::serial_configuration& bot);
149  ~serial_protocol() override;
150 
151  bool pull(ossia::net::parameter_base&) override;
152  bool push(const ossia::net::parameter_base&, const ossia::value& v) override;
153  bool push_raw(const ossia::net::full_parameter_data& parameter_base) override;
154  bool observe(ossia::net::parameter_base&, bool) override;
155  bool update(ossia::net::node_base& node_base) override;
156 
157  void set_device(ossia::net::device_base& dev) override;
158  void stop() override;
159 
160  static serial_parameter_data read_data(const QJSValue& js) { return js; }
161 
162 private:
163  static serial_protocol_object load_serial_object_from_qml(
164  serial_protocol& proto, const ossia::net::network_context_ptr& ctx,
165  const ossia::net::serial_configuration& cfg);
166  void create(
167  const ossia::net::network_context_ptr&,
168  const ossia::net::serial_configuration& cfg);
169  void on_read(const QString& txt, const QByteArray&);
170  void do_write(const ossia::net::parameter_base&, const ossia::value& v);
171  QQmlEngine* m_engine{};
172  QQmlComponent* m_component{};
173 
174  ossia::net::device_base* m_device{};
175  QObject* m_object{};
176  QJSValue m_jsObj{};
177  QJSValue m_onTextMessage{};
178  QJSValue m_onBinaryMessage{};
179  QJSValue m_onRead{};
180  std::shared_ptr<serial_wrapper> m_port;
181  QByteArray m_code;
182 
183  QObject* m_threadWorker{};
184  QThread m_thread{};
185 
186  coalescing_queue m_queue;
187  std::optional<double> m_coalesce{};
188 };
189 using serial_device = ossia::net::wrapped_device<serial_node, serial_protocol>;
190 
191 class OSSIA_EXPORT Serial : public QObject
192 {
193 };
194 
195 }
196 }
Root of a device tree.
Definition: ossia/network/base/device.hpp:58
The node_base class.
Definition: network/base/node.hpp:48
The parameter_base class.
Definition: ossia/network/base/parameter.hpp:48
The protocol_base class.
Definition: protocol.hpp:40
The value class.
Definition: value.hpp:173
Definition: git_info.h:7
Full information about a parameter.
Definition: parameter_data.hpp:61