5 #include "oscpack/oscOutboundPacketStream.h"
7 #include <common/utility/string.h>
12 #include <boost/asio.hpp>
13 #include <boost/foreach.hpp>
14 #include <boost/thread.hpp>
16 using namespace boost::asio::ip;
18 namespace caspar { namespace protocol { namespace osc {
21 struct param_visitor : public boost::static_visitor<void>
30 void operator()(const bool value) {o << value;}
31 void operator()(const int32_t value) {o << static_cast<int64_t>(value);}
32 void operator()(const uint32_t value) {o << static_cast<int64_t>(value);}
33 void operator()(const int64_t value) {o << static_cast<int64_t>(value);}
34 void operator()(const uint64_t value) {o << static_cast<int64_t>(value);}
35 void operator()(const float value) {o << value;}
36 void operator()(const double value) {o << static_cast<float>(value);}
37 void operator()(const std::string& value) {o << value.c_str();}
38 void operator()(const std::wstring& value) {o << narrow(value).c_str();}
39 void operator()(const std::vector<int8_t>& value) {o << ::osc::Blob(value.data(), static_cast<unsigned long>(value.size()));}
42 std::vector<char> write_osc_event(const core::monitor::message& e)
44 std::array<char, 4096> buffer;
45 ::osc::OutboundPacketStream o(buffer.data(), static_cast<unsigned long>(buffer.size()));
47 o << ::osc::BeginMessage(e.path().c_str());
49 param_visitor<decltype(o)> pd_visitor(o);
50 BOOST_FOREACH(auto data, e.data())
51 boost::apply_visitor(pd_visitor, data);
53 o << ::osc::EndMessage;
55 return std::vector<char>(o.Data(), o.Data() + o.Size());
60 boost::asio::io_service service_;
62 udp::endpoint endpoint_;
65 boost::thread thread_;
67 Concurrency::call<core::monitor::message> on_next_;
70 impl(udp::endpoint endpoint,
71 Concurrency::ISource<core::monitor::message>& source)
73 , socket_(service_, endpoint_.protocol())
74 , thread_(std::bind(&boost::asio::io_service::run, &service_))
75 , on_next_([this](const core::monitor::message& msg){ on_next(msg); })
77 source.link_target(&on_next_);
85 void on_next(const core::monitor::message& msg)
87 auto data_ptr = make_safe<std::vector<char>>(write_osc_event(msg));
89 socket_.async_send_to(boost::asio::buffer(*data_ptr),
91 boost::bind(&impl::handle_send_to, this,
92 boost::asio::placeholders::error,
93 boost::asio::placeholders::bytes_transferred));
96 void handle_send_to(const boost::system::error_code& /*error*/, size_t /*bytes_sent*/)
101 server::server(udp::endpoint endpoint,
102 Concurrency::ISource<core::monitor::message>& source)
103 : impl_(new impl(endpoint, source))
107 server::server(server&& other)
108 : impl_(std::move(other.impl_))
112 server& server::operator=(server&& other)
114 impl_ = std::move(other.impl_);