3#include <ossia/detail/thread.hpp>
5#include <oscpack/ip/UdpSocket.h>
6#include <oscpack/osc/OscDebug.h>
7#include <oscpack/osc/OscPacketListener.h>
20template <
typename Impl_T>
21struct ClearListener :
public oscpack::TimerListener
23 ClearListener(UdpSocket<Impl_T>& s)
27 UdpSocket<Impl_T>& socket;
29 void TimerExpired()
override { socket.AsynchronousBreak(); }
32template <
typename Impl_T>
33class ReceiveSocket :
public UdpSocket<Impl_T>
35 SocketReceiveMultiplexer<Impl_T> mux_;
36 PacketListener* listener_;
39 ReceiveSocket(
const IpEndpointName& localEndpoint, PacketListener* listener)
42 this->Bind(localEndpoint);
43 mux_.AttachSocketListener(&this->impl_, listener_);
46 ~ReceiveSocket() { mux_.DetachSocketListener(&this->impl_, listener_); }
49 void Run() { mux_.Run(); }
52 ClearListener<Impl_T> l{*
this};
53 mux_.AttachPeriodicTimerListener(0, &l);
56 void AsynchronousBreak()
58 ClearListener<Impl_T> l{*
this};
59 mux_.AttachPeriodicTimerListener(0, &l);
60 mux_.AsynchronousBreak();
65 :
public detail::UdpListeningReceiveSocket<detail::Implementation>
68 using UdpListeningReceiveSocket::UdpListeningReceiveSocket;
72 unsigned int BoundPort()
76 int len =
sizeof(addr);
78 socklen_t len =
sizeof(addr);
80 if(getsockname(this->impl_.Socket(),
reinterpret_cast<sockaddr*
>(&addr), &len) != 0)
82 return ntohs(addr.sin_port);
89template <
typename MessageHandler>
95class listener final :
public oscpack::OscPacketListener
98 listener(MessageHandler msg)
99 : m_messageHandler{msg}
104 const oscpack::ReceivedMessage& m,
const oscpack::IpEndpointName& ip)
override
108 m_messageHandler(m, ip);
110 catch(std::exception& e)
113 oscpack::debug(s, m);
116 "osc::listener::ProcessMessage error: '{}': {}", s.str(), e.what());
121 oscpack::debug(s, m);
122 ossia::logger().error(
"osc::listener::ProcessMessage error: '{}'", s.str());
127 const char* data,
int size,
const oscpack::IpEndpointName& remoteEndpoint)
override
131 oscpack::ReceivedPacket p(data, size);
133 this->ProcessBundle(oscpack::ReceivedBundle(p), remoteEndpoint);
135 this->ProcessMessage(oscpack::ReceivedMessage(p), remoteEndpoint);
137 catch(std::exception& e)
139 ossia::logger().error(
"osc::listener::ProcessPacket error: {}", e.what());
148 MessageHandler m_messageHandler;
160 template <
typename Handler>
161 receiver(
unsigned int port, Handler msg)
162 : m_impl{std::make_unique<listener<Handler>>(msg)}
167 receiver() =
default;
168 receiver(receiver&& other)
noexcept
171 m_impl = std::move(other.m_impl);
172 m_socket = std::move(other.m_socket);
173 setPort(other.m_port);
176 receiver& operator=(receiver&& other)
noexcept
180 m_impl = std::move(other.m_impl);
181 m_socket = std::move(other.m_socket);
183 setPort(other.m_port);
188 ~receiver() { stop(); }
192 if(m_runThread.joinable())
196 ossia::set_thread_name(
"ossia osc");
200 std::this_thread::sleep_for(std::chrono::microseconds(1));
226 if(m_runThread.joinable())
232 oscpack::UdpTransmitSocket send_socket(
233 oscpack::IpEndpointName(
"127.0.0.1", port()));
234 send_socket.Send(
"__stop_", 8);
239 m_socket->AsynchronousBreak();
249 m_runThread.detach();
250 (void)m_socket.release();
259 if(m_runThread.joinable())
262 m_runThread.detach();
267 unsigned int port()
const {
return m_port; }
269 unsigned int setPort(
unsigned int port)
278 m_socket = std::make_unique<oscpack::ReceiveSocket>(
279 oscpack::IpEndpointName(oscpack::IpEndpointName::ANY_ADDRESS, m_port),
282 m_port = m_socket->BoundPort();
285 catch(std::runtime_error&)
295 unsigned int m_port = 0;
296 std::unique_ptr<oscpack::OscPacketListener> m_impl;
297 std::unique_ptr<oscpack::ReceiveSocket> m_socket;
300 std::atomic_bool m_running =
false;
spdlog::logger & logger() noexcept
Where the errors will be logged. Default is stderr.
Definition context.cpp:120