90 lines
3.3 KiB
C++
90 lines
3.3 KiB
C++
#pragma once
|
|
|
|
#include "src/tuple.hpp"
|
|
#include <boost/callable_traits/args.hpp>
|
|
#include <boost/callable_traits/return_type.hpp>
|
|
#include <msgpack.hpp>
|
|
#include <tuple>
|
|
|
|
#define ZMQ_BUILD_DRAFT_API
|
|
#include <zmq.hpp>
|
|
|
|
#define FMT_HEADER_ONLY
|
|
#include <fmt/format.h>
|
|
#include <fmt/ranges.h>
|
|
|
|
#include "adapter_base.hpp"
|
|
#include "port_types.hpp"
|
|
#include "utils.hpp"
|
|
|
|
using namespace boost::callable_traits;
|
|
|
|
template <typename EncodedType> class PortBase {
|
|
class AddressedPort_ {
|
|
public:
|
|
AddressedPort_(const PortBase<EncodedType> *port, const std::string &address) : mc_addr_(address), mc_port_(port) {}
|
|
template <typename InType> const auto &operator<<(const InType &in) const {
|
|
mc_port_->send__(mc_addr_, &in, sizeof(InType), typeid(InType).hash_code());
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
const std::string mc_addr_;
|
|
const PortBase<EncodedType> *mc_port_;
|
|
};
|
|
|
|
public:
|
|
PortBase(enum port_types_e port_type, const std::string &name, const std::string &endpoint, zmq::context_t &zmq_ctx)
|
|
: mc_type_(port_type), mc_name_(name), mc_endpoint_(endpoint), mc_name_hash_(std::hash<std::string>()(name)), mc_endpoint_hash_(std::hash<std::string>()(endpoint)) {}
|
|
|
|
virtual ~PortBase() = default;
|
|
|
|
inline const auto &type() const { return mc_type_; }
|
|
inline const auto &name() const { return mc_name_; }
|
|
inline const auto &endpoint() const { return mc_endpoint_; }
|
|
inline const auto &name_hash() const { return mc_name_hash_; }
|
|
inline const auto &endpoint_hash() const { return mc_endpoint_hash_; }
|
|
|
|
const auto operator[](const std::string &address) const { return AddressedPort_(this, address); }
|
|
|
|
template <typename InType> const PortBase<EncodedType> &operator<<(const InType &in) const {
|
|
send__("", &in, sizeof(InType), typeid(InType).hash_code());
|
|
return *this;
|
|
}
|
|
|
|
// void listen() const { listen__(m_ss_.get_token()); };
|
|
virtual void stop() const = 0;
|
|
|
|
template <typename Signature> auto &callback(const std::string &name) const {
|
|
return GetCallbackHelper_<typename tp::tuple_tail<args_t<Signature>>::type>(this).template operator()<Signature>(name);
|
|
}
|
|
|
|
protected:
|
|
virtual void stop__() const = 0;
|
|
virtual void send__(const std::string &addr, const void *data, size_t size, size_t type_hash) const = 0;
|
|
virtual void *get_adapter__(const std::string &name, size_t namehash, size_t typehash, size_t cbk_typehash) const = 0;
|
|
|
|
private:
|
|
const enum port_types_e mc_type_;
|
|
const std::string mc_name_, mc_endpoint_;
|
|
const size_t mc_name_hash_, mc_endpoint_hash_;
|
|
|
|
template <typename...> class GetCallbackHelper_;
|
|
template <typename... Aargs> class GetCallbackHelper_<std::tuple<Aargs...>> {
|
|
public:
|
|
GetCallbackHelper_(const PortBase *port) : mc_port_(port) {}
|
|
|
|
template <typename Signature> auto &operator()(const std::string &name) const {
|
|
using ret_type_t = std::remove_cvref_t<return_type_t<std::function<Signature>>>;
|
|
using arg_type_t = std::tuple_element_t<0, args_t<std::function<Signature>>>;
|
|
return (*static_cast<AdapterBase<arg_type_t, tag_s<ret_type_t>, Aargs...> *>(
|
|
mc_port_->get_adapter__(name, std::hash<std::string>()(name), typeid(arg_type_t).hash_code(),
|
|
typeid(typename AdapterBase<arg_type_t, tag_s<ret_type_t>, Aargs...>::callback_type_t).hash_code())))
|
|
.callback();
|
|
}
|
|
|
|
private:
|
|
const PortBase *mc_port_;
|
|
};
|
|
};
|