OSSIA
Open Scenario System for Interactive Application
sender.hpp
1 #pragma once
2 #include <ossia/detail/buffer_pool.hpp>
4 #include <ossia/network/base/parameter.hpp>
5 #include <ossia/network/base/parameter_data.hpp>
6 #include <ossia/network/common/network_logger.hpp>
7 #include <ossia/network/osc/detail/message_generator.hpp>
8 #include <ossia/network/osc/detail/osc_messages.hpp>
9 #include <ossia/network/value/format_value.hpp>
10 
11 #include <oscpack/ip/UdpSocket.h>
12 #include <oscpack/osc/OscOutboundPacketStream.h>
13 #include <oscpack/osc/OscPrintReceivedElements.h>
14 
15 #include <memory>
16 #include <string>
17 namespace osc
18 {
25 template <typename ValueWriter>
26 class sender
27 {
28 public:
29  sender(const ossia::net::network_logger& l, const std::string& ip, const int port)
30  : m_logger{l}
31  , m_socket{oscpack::IpEndpointName(ip.c_str(), port)}
32  , m_ip(ip)
33  , m_port(port)
34  {
35  }
36  template <typename... Args>
37  void send(const ossia::net::parameter_base& address, Args&&... args)
38  {
39  send_base(address.get_node().osc_address(), std::forward<Args>(args)...);
40  }
41  template <typename... Args>
42  void send(const ossia::net::full_parameter_data& address, Args&&... args)
43  {
44  send_base(address.address, std::forward<Args>(args)...);
45  }
46 
47  template <typename... Args>
48  void send(const std::string& address, Args&&... args)
49  {
50  send_base(address, std::forward<Args>(args)...);
51  }
52 
53  template <typename... Args>
54  void send(std::string_view address, Args&&... args)
55  {
56  send_base(address, std::forward<Args>(args)...);
57  }
58 
59  const std::string& ip() const { return m_ip; }
60 
61  int port() const { return m_port; }
62 
63  int localPort() const { return m_socket.LocalPort(); }
64 
65  oscpack::UdpTransmitSocket& socket() { return m_socket; }
66 
67 private:
68  void debug(const oscpack::OutboundPacketStream& out)
69  {
70  std::string s(out.Data(), out.Data() + out.Size());
71  std::replace(s.begin(), s.end(), '\0', ' ');
72  std::cerr << s << "\n";
73  }
74 
75  template <typename... Args>
76  void send_base(Args&&... args)
77  {
78  auto buf = m_pool.acquire();
79  while(buf.size() < ossia::net::max_osc_message_size)
80  {
81  try
82  {
83  oscpack::OutboundPacketStream p{buf.data(), buf.size()};
84  oscpack::osc_message_generator<ossia::net::osc_1_0_outbound_stream_visitor>
85  generate_message{p};
86  generate_message(std::forward<Args>(args)...);
87  send_impl(p);
88  break;
89  }
90  catch(...)
91  {
92  auto n = buf.size();
93  buf.clear();
94  buf.resize(n * 2 + 1);
95  }
96  }
97 
98  m_pool.release(std::move(buf));
99  if(m_logger.outbound_logger)
100  {
101  std::string format_string;
102  format_string.reserve(5 + 3 * sizeof...(args));
103  format_string += "Out: ";
104  for(std::size_t i = 0; i < sizeof...(args); i++)
105  format_string += "{} ";
106  m_logger.outbound_logger->info(fmt::runtime(format_string), args...);
107  }
108  }
109 
110  void send_impl(const oscpack::OutboundPacketStream& m)
111  {
112  try
113  {
114  m_socket.Send(m.Data(), m.Size());
115  }
116  catch(...)
117  {
118  }
119  }
120 
121  const ossia::net::network_logger& m_logger;
122  oscpack::UdpTransmitSocket m_socket;
123  std::string m_ip;
124  int m_port;
125 
126  ossia::buffer_pool& m_pool = ossia::buffer_pool::instance();
127 };
128 }
The sender class.
Definition: sender.hpp:27
Stores custom loggers for the inbound and outbound network messages.
Definition: network_logger.hpp:19
std::shared_ptr< ossia::logger_type > outbound_logger
outbound_logger Set log function for messages going outside.
Definition: network_logger.hpp:40
The parameter_base class.
Definition: ossia/network/base/parameter.hpp:48
Full information about a parameter.
Definition: parameter_data.hpp:61