module-arch-POC/src/port_base.hpp

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_;
};
};