603 lines
34 KiB
C++
603 lines
34 KiB
C++
#include <boost/signals2/signal_type.hpp>
|
|
#include <boost/signals2/variadic_signal.hpp>
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
#include <list>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <tuple>
|
|
#include <unordered_map>
|
|
|
|
#define FMT_HEADER_ONLY
|
|
#include <fmt/format.h>
|
|
#include <fmt/ranges.h>
|
|
|
|
#include "adapter_factory.hpp"
|
|
#include "codecs.hpp"
|
|
#include "module_factory.hpp"
|
|
#include "port_factory.hpp"
|
|
|
|
using env_data_type_t = std::vector<uint8_t>;
|
|
|
|
void subscriber_entry(int32_t argc, char **argv, char **envp, const std::unordered_map<std::string, const PortBase<env_data_type_t> *> &ports) {
|
|
// Resolve port by name.
|
|
const auto &subscriber = *ports.at("subscriber_port"); // Get subscriber port
|
|
|
|
// Fetch typed callbacks by adapter name and signature.
|
|
auto &int_cbk = subscriber.callback<void(const int32_t &, const std::string &)>("int-vector<uint8_t>-int");
|
|
auto &string_cbk = subscriber.callback<void(const std::string &, const std::string &)>("string-vector<uint8_t>-string");
|
|
auto &double_cbk = subscriber.callback<void(const double &, const std::string &)>("double-vector<uint8_t>-double");
|
|
|
|
// Connect callbacks
|
|
int_cbk.connect([](const int32_t &i, const std::string &addr) {
|
|
fmt::print("SUBSCRIBER socket: got data: {} of {} type from address: {}\r\n", i, type_name<std::remove_cvref_t<decltype(i)>>(), addr);
|
|
});
|
|
|
|
string_cbk.connect([](const std::string &s, const std::string &addr) {
|
|
fmt::print("SUBSCRIBER socket: got data: {} of {} type from address: {}\r\n", s, type_name<std::remove_cvref_t<decltype(s)>>(), addr);
|
|
});
|
|
|
|
double_cbk.connect([](const double &d, const std::string &addr) {
|
|
fmt::print("SUBSCRIBER socket: got data: {} of {} type from address: {}\r\n", d, type_name<std::remove_cvref_t<decltype(d)>>(), addr);
|
|
});
|
|
}
|
|
|
|
// Publisher module entrypoint
|
|
void publisher_entry(int32_t argc, char **argv, char **envp, const std::unordered_map<std::string, const PortBase<env_data_type_t> *> &ports) {
|
|
// Resolve port by name.
|
|
const auto &publisher = *ports.at("publisher_port"); // Get publisher port
|
|
|
|
// Publish data
|
|
publisher["topic0"] << 1 << 2 << double{3.f} << std::string("test");
|
|
publisher["topic1"] << 1 << 2 << double{3.f} << std::string("test");
|
|
publisher["topic2"] << 1 << 2 << double{3.f} << std::string("test");
|
|
publisher["topic3"] << 1 << 2 << double{3.f} << std::string("test");
|
|
}
|
|
|
|
// Publisher module entrypoint
|
|
void pusher_entry(int32_t argc, char **argv, char **envp, const std::unordered_map<std::string, const PortBase<env_data_type_t> *> &ports) {
|
|
// Resolve port by name.
|
|
const auto &publisher = *ports.at("push_port"); // Get publisher port
|
|
publisher << 1 << 2 << double{3.f} << std::string("test");
|
|
}
|
|
|
|
void puller_entry(int32_t argc, char **argv, char **envp, const std::unordered_map<std::string, const PortBase<env_data_type_t> *> &ports) {
|
|
// Resolve port by name.
|
|
const auto &puller = *ports.at("pull_port"); // Get subscriber port
|
|
|
|
// Fetch typed callbacks by adapter name and signature.
|
|
auto &int_cbk = puller.callback<void(const int32_t &)>("int-vector<uint8_t>-int");
|
|
auto &string_cbk = puller.callback<void(const std::string &)>("string-vector<uint8_t>-string");
|
|
auto &double_cbk = puller.callback<void(const double &)>("double-vector<uint8_t>-double");
|
|
|
|
// Connect callbacks
|
|
int_cbk.connect([](const int32_t &i) { fmt::print("PULL socket: got data: {} of {} type\r\n", i, type_name<std::remove_cvref_t<decltype(i)>>()); });
|
|
string_cbk.connect([](const std::string &s) { fmt::print("PULL socket: got data: {} of {} type\r\n", s, type_name<std::remove_cvref_t<decltype(s)>>()); });
|
|
double_cbk.connect([](const double &d) { fmt::print("PULL socket: got data: {} of {} type\r\n", d, type_name<std::remove_cvref_t<decltype(d)>>()); });
|
|
}
|
|
|
|
void req_entry(int32_t argc, char **argv, char **envp, const std::unordered_map<std::string, const PortBase<env_data_type_t> *> &ports) {
|
|
// Resolve port by name.
|
|
const auto &req = *ports.at("req_port"); // Get publisher port
|
|
// static_assert(std::is_same_v<typename std::remove_cvref_t<decltype(req)>, void>, "");
|
|
// Fetch typed callbacks by adapter name and signature.
|
|
auto &int_cbk = req.callback<void(const int32_t &)>("int-vector<uint8_t>-int");
|
|
auto &string_cbk = req.callback<void(const std::string &)>("string-vector<uint8_t>-string");
|
|
auto &double_cbk = req.callback<void(const double &)>("double-vector<uint8_t>-double");
|
|
|
|
// Connect callbacks
|
|
int_cbk.connect([](const int32_t &i) { fmt::print("REQUEST socket: got data: {} of {} type\r\n", i, type_name<std::remove_cvref_t<decltype(i)>>()); });
|
|
string_cbk.connect([](const std::string &s) { fmt::print("REQUEST socket: got data: {} of {} type\r\n", s, type_name<std::remove_cvref_t<decltype(s)>>()); });
|
|
double_cbk.connect([](const double &d) { fmt::print("REQUEST socket: got data: {} of {} type\r\n", d, type_name<std::remove_cvref_t<decltype(d)>>()); });
|
|
|
|
req << 1 << 2 << double{3.f} << std::string("test");
|
|
}
|
|
|
|
void rep_entry(int32_t argc, char **argv, char **envp, const std::unordered_map<std::string, const PortBase<env_data_type_t> *> &ports) {
|
|
// Resolve port by name.
|
|
const auto &rep = *ports.at("rep_port"); // Get subscriber port
|
|
|
|
// Fetch typed callbacks by adapter name and signature.
|
|
auto &int_cbk = rep.callback<std::string(const int32_t &)>("int-vector<uint8_t>-int");
|
|
auto &string_cbk = rep.callback<std::string(const std::string &)>("string-vector<uint8_t>-string");
|
|
auto &double_cbk = rep.callback<std::string(const double &)>("double-vector<uint8_t>-double");
|
|
|
|
// Connect callbacks
|
|
int_cbk.connect([](const int32_t &i) -> std::string {
|
|
fmt::print("REPLY socket: got data: {} of {} type\r\n", i, type_name<std::remove_cvref_t<decltype(i)>>());
|
|
// Handle data ...
|
|
return fmt::format("'Handle request: {} of type: {}'", i, type_name<std::remove_cvref_t<decltype(i)>>());
|
|
});
|
|
|
|
string_cbk.connect([](const std::string &s) -> std::string {
|
|
fmt::print("REPLY socket: got data: {} of {} type (FIRST callback)\r\n", s, type_name<std::remove_cvref_t<decltype(s)>>());
|
|
// Handle data ...
|
|
return fmt::format("'Handle request: {} of type: {}' (FIRST callback)", s, type_name<std::remove_cvref_t<decltype(s)>>());
|
|
});
|
|
|
|
string_cbk.connect([](const std::string &s) -> std::string {
|
|
fmt::print("REPLY socket: got data: {} of {} type (SECOND callback)\r\n", s, type_name<std::remove_cvref_t<decltype(s)>>());
|
|
// Handle data ...
|
|
return fmt::format("'Handle request: {} of type: {}' (SECOND callback)", s, type_name<std::remove_cvref_t<decltype(s)>>());
|
|
});
|
|
|
|
double_cbk.connect([](const double &d) -> std::string {
|
|
fmt::print("REPLY socket: got data: {} of {} type\r\n", d, type_name<std::remove_cvref_t<decltype(d)>>());
|
|
// Handle data ...
|
|
return fmt::format("'Handle request: {} of type: {}'", d, type_name<std::remove_cvref_t<decltype(d)>>());
|
|
});
|
|
}
|
|
|
|
void pair_server_entry(int32_t argc, char **argv, char **envp, const std::unordered_map<std::string, const PortBase<env_data_type_t> *> &ports) {
|
|
// Resolve port by name.
|
|
const auto &pair = *ports.at("pair_server_port");
|
|
|
|
auto &int_cbk = pair.callback<void(const int32_t &)>("int-vector<uint8_t>-int");
|
|
auto &string_cbk = pair.callback<void(const std::string &)>("string-vector<uint8_t>-string");
|
|
auto &double_cbk = pair.callback<void(const double &)>("double-vector<uint8_t>-double");
|
|
|
|
int_cbk.connect([](const int32_t &i) { fmt::print("PAIR server: got data: {} of {} type\r\n", i, type_name<std::remove_cvref_t<decltype(i)>>()); });
|
|
string_cbk.connect([](const std::string &s) { fmt::print("PAIR server: got data: {} of {} type\r\n", s, type_name<std::remove_cvref_t<decltype(s)>>()); });
|
|
double_cbk.connect([](const double &d) { fmt::print("PAIR server: got data: {} of {} type\r\n", d, type_name<std::remove_cvref_t<decltype(d)>>()); });
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
pair << 4 << 5 << double{6.f} << std::string("server->client");
|
|
}
|
|
|
|
void pair_client_entry(int32_t argc, char **argv, char **envp, const std::unordered_map<std::string, const PortBase<env_data_type_t> *> &ports) {
|
|
// Resolve port by name.
|
|
const auto &pair = *ports.at("pair_client_port");
|
|
|
|
auto &int_cbk = pair.callback<void(const int32_t &)>("int-vector<uint8_t>-int");
|
|
auto &string_cbk = pair.callback<void(const std::string &)>("string-vector<uint8_t>-string");
|
|
auto &double_cbk = pair.callback<void(const double &)>("double-vector<uint8_t>-double");
|
|
|
|
int_cbk.connect([](const int32_t &i) { fmt::print("PAIR client: got data: {} of {} type\r\n", i, type_name<std::remove_cvref_t<decltype(i)>>()); });
|
|
string_cbk.connect([](const std::string &s) { fmt::print("PAIR client: got data: {} of {} type\r\n", s, type_name<std::remove_cvref_t<decltype(s)>>()); });
|
|
double_cbk.connect([](const double &d) { fmt::print("PAIR client: got data: {} of {} type\r\n", d, type_name<std::remove_cvref_t<decltype(d)>>()); });
|
|
|
|
pair << 1 << 2 << double{3.f} << std::string("test");
|
|
}
|
|
|
|
void dish_entry(int32_t argc, char **argv, char **envp, const std::unordered_map<std::string, const PortBase<env_data_type_t> *> &ports) {
|
|
// Resolve port by name.
|
|
const auto &dish = *ports.at("dish_port");
|
|
|
|
auto &int_cbk = dish.callback<void(const int32_t &, const std::string &)>("int-vector<uint8_t>-int");
|
|
auto &string_cbk = dish.callback<void(const std::string &, const std::string &)>("string-vector<uint8_t>-string");
|
|
auto &double_cbk = dish.callback<void(const double &, const std::string &)>("double-vector<uint8_t>-double");
|
|
|
|
int_cbk.connect([](const int32_t &i, const std::string &group) {
|
|
fmt::print("DISH socket: got data: {} of {} type from group: {}\r\n", i, type_name<std::remove_cvref_t<decltype(i)>>(), group);
|
|
});
|
|
|
|
string_cbk.connect([](const std::string &s, const std::string &group) {
|
|
fmt::print("DISH socket: got data: {} of {} type from group: {}\r\n", s, type_name<std::remove_cvref_t<decltype(s)>>(), group);
|
|
});
|
|
|
|
double_cbk.connect([](const double &d, const std::string &group) {
|
|
fmt::print("DISH socket: got data: {} of {} type from group: {}\r\n", d, type_name<std::remove_cvref_t<decltype(d)>>(), group);
|
|
});
|
|
}
|
|
|
|
void radio_entry(int32_t argc, char **argv, char **envp, const std::unordered_map<std::string, const PortBase<env_data_type_t> *> &ports) {
|
|
// Resolve port by name.
|
|
const auto &radio = *ports.at("radio_port");
|
|
|
|
radio["grp0"] << 1 << 2 << double{3.f};
|
|
radio["grp1"] << std::string("test");
|
|
}
|
|
|
|
int main(int argc, char *argv[], char *envp[]) {
|
|
using enum port_types_e;
|
|
codecs_s<env_data_type_t> codecs;
|
|
// Shared ZMQ context for in-process transports.
|
|
zmq::context_t zmq_ctx; // Use common context because both modules have in-process ports, but working in different threads
|
|
|
|
// Make module that contains only 1 port working on PUBLISHER pattern
|
|
auto publisher_module = ModuleBuilder()
|
|
.withName("publisher_module")
|
|
.withContext(zmq_ctx)
|
|
.withPorts(std::tuple{
|
|
PortBuilder()
|
|
.withType(PUB)
|
|
.withName("publisher_port")
|
|
.withEndpoints({
|
|
{"test", "inproc://PUB-SUB"},
|
|
})
|
|
.withContext(zmq_ctx)
|
|
.withAdapters(std::tuple{
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_int)
|
|
.decodeDataBy(&codecs.decoders.to_int)
|
|
.withCallbackSignature<void(const int32_t &)>()
|
|
.withName("int-vector<uint8_t>-int")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_string)
|
|
.decodeDataBy(&codecs.decoders.to_string)
|
|
.withCallbackSignature<void(const std::string &)>()
|
|
.withName("string-vector<uint8_t>-string")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_double)
|
|
.decodeDataBy(&codecs.decoders.to_double)
|
|
.withCallbackSignature<void(const double &)>()
|
|
.withName("double-vector<uint8_t>-double")
|
|
.finalize(),
|
|
})
|
|
.finalize(),
|
|
})
|
|
.finalize(argc, argv, envp);
|
|
|
|
// Make module that contains only 1 port working on SUBSCRIBER pattern
|
|
auto subscriber_module = ModuleBuilder()
|
|
.withName("subscriber_module")
|
|
.withContext(zmq_ctx)
|
|
.withPorts(std::tuple{
|
|
PortBuilder()
|
|
.withType(SUB)
|
|
.withName("subscriber_port")
|
|
.withEndpoints({
|
|
{"test", "inproc://PUB-SUB"},
|
|
})
|
|
.withContext(zmq_ctx)
|
|
.withAdapters(std::tuple{
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_int)
|
|
.decodeDataBy(&codecs.decoders.to_int)
|
|
.withCallbackSignature<void(const int32_t &, const std::string &)>()
|
|
.withName("int-vector<uint8_t>-int")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_string)
|
|
.decodeDataBy(&codecs.decoders.to_string)
|
|
.withCallbackSignature<void(const std::string &, const std::string &)>()
|
|
.withName("string-vector<uint8_t>-string")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_double)
|
|
.decodeDataBy(&codecs.decoders.to_double)
|
|
.withCallbackSignature<void(const double &, const std::string &)>()
|
|
.withName("double-vector<uint8_t>-double")
|
|
.finalize(),
|
|
})
|
|
.withArgs(std::tuple{
|
|
std::list<std::string>{"topic0", "topic1", "topic2", "topic3"},
|
|
})
|
|
.finalize(),
|
|
})
|
|
.finalize(argc, argv, envp);
|
|
|
|
auto pusher_module = ModuleBuilder()
|
|
.withName("pusher_module")
|
|
.withContext(zmq_ctx)
|
|
.withPorts(std::tuple{
|
|
PortBuilder()
|
|
.withType(PUSH)
|
|
.withName("push_port")
|
|
.withEndpoints({
|
|
{"test", "inproc://PUSH-PULL"},
|
|
})
|
|
.withContext(zmq_ctx)
|
|
.withAdapters(std::tuple{
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_int)
|
|
.decodeDataBy(&codecs.decoders.to_int)
|
|
.withCallbackSignature<void(const int32_t &)>()
|
|
.withName("int-vector<uint8_t>-int")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_string)
|
|
.decodeDataBy(&codecs.decoders.to_string)
|
|
.withCallbackSignature<void(const std::string &)>()
|
|
.withName("string-vector<uint8_t>-string")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_double)
|
|
.decodeDataBy(&codecs.decoders.to_double)
|
|
.withCallbackSignature<void(const double &)>()
|
|
.withName("double-vector<uint8_t>-double")
|
|
.finalize(),
|
|
})
|
|
.finalize(),
|
|
})
|
|
.finalize(argc, argv, envp);
|
|
|
|
auto puller_module = ModuleBuilder()
|
|
.withName("puller_module")
|
|
.withContext(zmq_ctx)
|
|
.withPorts(std::tuple{
|
|
PortBuilder()
|
|
.withType(PULL)
|
|
.withName("pull_port")
|
|
.withEndpoints({
|
|
{"test", "inproc://PUSH-PULL"},
|
|
})
|
|
.withContext(zmq_ctx)
|
|
.withAdapters(std::tuple{
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_int)
|
|
.decodeDataBy(&codecs.decoders.to_int)
|
|
.withCallbackSignature<void(const int32_t &)>()
|
|
.withName("int-vector<uint8_t>-int")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_string)
|
|
.decodeDataBy(&codecs.decoders.to_string)
|
|
.withCallbackSignature<void(const std::string &)>()
|
|
.withName("string-vector<uint8_t>-string")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_double)
|
|
.decodeDataBy(&codecs.decoders.to_double)
|
|
.withCallbackSignature<void(const double &)>()
|
|
.withName("double-vector<uint8_t>-double")
|
|
.finalize(),
|
|
})
|
|
.finalize(),
|
|
})
|
|
.finalize(argc, argv, envp);
|
|
|
|
auto req_module = ModuleBuilder()
|
|
.withName("req_module")
|
|
.withContext(zmq_ctx)
|
|
.withPorts(std::tuple{
|
|
PortBuilder()
|
|
.withType(REQ)
|
|
.withName("req_port")
|
|
.withEndpoints({
|
|
{"test", "inproc://REQ-REP"},
|
|
})
|
|
.withContext(zmq_ctx)
|
|
.withAdapters(std::tuple{
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_int)
|
|
.decodeDataBy(&codecs.decoders.to_int)
|
|
.withCallbackSignature<void(const int32_t &)>()
|
|
.withName("int-vector<uint8_t>-int")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_string)
|
|
.decodeDataBy(&codecs.decoders.to_string)
|
|
.withCallbackSignature<void(const std::string &)>()
|
|
.withName("string-vector<uint8_t>-string")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_double)
|
|
.decodeDataBy(&codecs.decoders.to_double)
|
|
.withCallbackSignature<void(const double &)>()
|
|
.withName("double-vector<uint8_t>-double")
|
|
.finalize(),
|
|
})
|
|
.finalize(),
|
|
})
|
|
.finalize(argc, argv, envp);
|
|
|
|
auto rep_module = ModuleBuilder()
|
|
.withName("rep_module")
|
|
.withContext(zmq_ctx)
|
|
.withPorts(std::tuple{
|
|
PortBuilder()
|
|
.withType(REP)
|
|
.withName("rep_port")
|
|
.withEndpoints({
|
|
{"test", "inproc://REQ-REP"},
|
|
})
|
|
.withContext(zmq_ctx)
|
|
.withAdapters(std::tuple{
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_int)
|
|
.decodeDataBy(&codecs.decoders.to_int)
|
|
.withCallbackSignature<std::string(const int32_t &)>()
|
|
.withName("int-vector<uint8_t>-int")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_string)
|
|
.decodeDataBy(&codecs.decoders.to_string)
|
|
.withCallbackSignature<std::string(const std::string &)>()
|
|
.withName("string-vector<uint8_t>-string")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_double)
|
|
.decodeDataBy(&codecs.decoders.to_double)
|
|
.withCallbackSignature<std::string(const double &)>()
|
|
.withName("double-vector<uint8_t>-double")
|
|
.finalize(),
|
|
})
|
|
.finalize(),
|
|
})
|
|
.finalize(argc, argv, envp);
|
|
|
|
auto pair_server_module = ModuleBuilder()
|
|
.withName("pair_server_module")
|
|
.withContext(zmq_ctx)
|
|
.withPorts(std::tuple{
|
|
PortBuilder()
|
|
.withType(PAIR_SERVER)
|
|
.withName("pair_server_port")
|
|
.withEndpoints({
|
|
{"test", "inproc://PAIR"},
|
|
})
|
|
.withContext(zmq_ctx)
|
|
.withAdapters(std::tuple{
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_int)
|
|
.decodeDataBy(&codecs.decoders.to_int)
|
|
.withCallbackSignature<void(const int32_t &)>()
|
|
.withName("int-vector<uint8_t>-int")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_string)
|
|
.decodeDataBy(&codecs.decoders.to_string)
|
|
.withCallbackSignature<void(const std::string &)>()
|
|
.withName("string-vector<uint8_t>-string")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_double)
|
|
.decodeDataBy(&codecs.decoders.to_double)
|
|
.withCallbackSignature<void(const double &)>()
|
|
.withName("double-vector<uint8_t>-double")
|
|
.finalize(),
|
|
})
|
|
.finalize(),
|
|
})
|
|
.finalize(argc, argv, envp);
|
|
|
|
auto pair_client_module = ModuleBuilder()
|
|
.withName("pair_client_module")
|
|
.withContext(zmq_ctx)
|
|
.withPorts(std::tuple{
|
|
PortBuilder()
|
|
.withType(PAIR_CLIENT)
|
|
.withName("pair_client_port")
|
|
.withEndpoints({
|
|
{"test", "inproc://PAIR"},
|
|
})
|
|
.withContext(zmq_ctx)
|
|
.withAdapters(std::tuple{
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_int)
|
|
.decodeDataBy(&codecs.decoders.to_int)
|
|
.withCallbackSignature<void(const int32_t &)>()
|
|
.withName("int-vector<uint8_t>-int")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_string)
|
|
.decodeDataBy(&codecs.decoders.to_string)
|
|
.withCallbackSignature<void(const std::string &)>()
|
|
.withName("string-vector<uint8_t>-string")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_double)
|
|
.decodeDataBy(&codecs.decoders.to_double)
|
|
.withCallbackSignature<void(const double &)>()
|
|
.withName("double-vector<uint8_t>-double")
|
|
.finalize(),
|
|
})
|
|
.finalize(),
|
|
})
|
|
.finalize(argc, argv, envp);
|
|
|
|
auto dish_module = ModuleBuilder()
|
|
.withName("dish_module")
|
|
.withContext(zmq_ctx)
|
|
.withPorts(std::tuple{
|
|
PortBuilder()
|
|
.withType(DISH)
|
|
.withName("dish_port")
|
|
.withEndpoints({
|
|
{"test", "inproc://RADIO-DISH"},
|
|
})
|
|
.withContext(zmq_ctx)
|
|
.withAdapters(std::tuple{
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_int)
|
|
.decodeDataBy(&codecs.decoders.to_int)
|
|
.withCallbackSignature<void(const int32_t &, const std::string &)>()
|
|
.withName("int-vector<uint8_t>-int")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_string)
|
|
.decodeDataBy(&codecs.decoders.to_string)
|
|
.withCallbackSignature<void(const std::string &, const std::string &)>()
|
|
.withName("string-vector<uint8_t>-string")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_double)
|
|
.decodeDataBy(&codecs.decoders.to_double)
|
|
.withCallbackSignature<void(const double &, const std::string &)>()
|
|
.withName("double-vector<uint8_t>-double")
|
|
.finalize(),
|
|
})
|
|
.withArgs(std::tuple{
|
|
std::list<std::string>{"grp0", "grp1"},
|
|
})
|
|
.finalize(),
|
|
})
|
|
.finalize(argc, argv, envp);
|
|
|
|
auto radio_module = ModuleBuilder()
|
|
.withName("radio_module")
|
|
.withContext(zmq_ctx)
|
|
.withPorts(std::tuple{
|
|
PortBuilder()
|
|
.withType(RADIO)
|
|
.withName("radio_port")
|
|
.withEndpoints({
|
|
{"test", "inproc://RADIO-DISH"},
|
|
})
|
|
.withContext(zmq_ctx)
|
|
.withAdapters(std::tuple{
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_int)
|
|
.decodeDataBy(&codecs.decoders.to_int)
|
|
.withCallbackSignature<void(const int32_t &)>()
|
|
.withName("int-vector<uint8_t>-int")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_string)
|
|
.decodeDataBy(&codecs.decoders.to_string)
|
|
.withCallbackSignature<void(const std::string &)>()
|
|
.withName("string-vector<uint8_t>-string")
|
|
.finalize(),
|
|
|
|
AdapterBuilder()
|
|
.encodeDataBy(&codecs.encoders.from_double)
|
|
.decodeDataBy(&codecs.decoders.to_double)
|
|
.withCallbackSignature<void(const double &)>()
|
|
.withName("double-vector<uint8_t>-double")
|
|
.finalize(),
|
|
})
|
|
.finalize(),
|
|
})
|
|
.finalize(argc, argv, envp);
|
|
|
|
fmt::print("\r\nPUB-SUB test:\r\n");
|
|
subscriber_module->run(subscriber_entry); // Subscribe and get data
|
|
publisher_module->run(publisher_entry); // Publish data
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
|
|
|
fmt::print("\r\nPUSH-PULL test:\r\n");
|
|
pusher_module->run(pusher_entry);
|
|
puller_module->run(puller_entry);
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
|
|
|
fmt::print("\r\nREQ-REP test:\r\n");
|
|
rep_module->run(rep_entry);
|
|
req_module->run(req_entry);
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
|
|
|
fmt::print("\r\nPAIR test:\r\n");
|
|
pair_server_module->run(pair_server_entry);
|
|
pair_client_module->run(pair_client_entry);
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
|
|
|
fmt::print("\r\nRADIO-DISH test:\r\n");
|
|
dish_module->run(dish_entry);
|
|
radio_module->run(radio_entry);
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
|
fmt::print("DONE!\r\n");
|
|
|
|
return 0;
|
|
}
|