From 91b91f45c1138294f2ad815e0640b088affd93c6 Mon Sep 17 00:00:00 2001 From: rex-schilasky <49162693+rex-schilasky@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:11:52 +0200 Subject: [PATCH] first draft new publisher config API --- .../include/ecal/cimpl/ecal_publisher_cimpl.h | 20 -- ecal/core/include/ecal/ecal_publisher.h | 61 +++-- ecal/core/include/ecal/ecal_tlayer.h | 1 + .../include/ecal/msg/capnproto/publisher.h | 10 +- .../include/ecal/msg/flatbuffers/publisher.h | 8 +- .../include/ecal/msg/messagepack/publisher.h | 8 +- .../include/ecal/msg/protobuf/publisher.h | 7 +- ecal/core/include/ecal/msg/publisher.h | 11 +- ecal/core/include/ecal/msg/string/publisher.h | 7 +- ecal/core/src/cimpl/ecal_publisher_cimpl.cpp | 16 -- ecal/core/src/pubsub/ecal_pubgate.cpp | 5 +- ecal/core/src/pubsub/ecal_publisher.cpp | 65 +++-- ecal/core/src/readwrite/ecal_reader.cpp | 12 +- ecal/core/src/readwrite/ecal_reader.h | 4 +- ecal/core/src/readwrite/ecal_writer.cpp | 225 +++++------------- ecal/core/src/readwrite/ecal_writer.h | 25 +- ecal/samples/CMakeLists.txt | 3 + .../protobuf/person_snd_tcp/CMakeLists.txt | 50 ++++ .../person_snd_tcp/src/person_snd_tcp.cpp | 81 +++++++ .../person_snd_tcp/src/protobuf/animal.proto | 28 +++ .../person_snd_tcp/src/protobuf/house.proto | 27 +++ .../person_snd_tcp/src/protobuf/person.proto | 42 ++++ 22 files changed, 399 insertions(+), 317 deletions(-) create mode 100644 ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/CMakeLists.txt create mode 100644 ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/person_snd_tcp.cpp create mode 100644 ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/animal.proto create mode 100644 ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/house.proto create mode 100644 ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/person.proto diff --git a/ecal/core/include/ecal/cimpl/ecal_publisher_cimpl.h b/ecal/core/include/ecal/cimpl/ecal_publisher_cimpl.h index 09f31a1..754af8d 100644 --- a/ecal/core/include/ecal/cimpl/ecal_publisher_cimpl.h +++ b/ecal/core/include/ecal/cimpl/ecal_publisher_cimpl.h @@ -89,26 +89,6 @@ extern "C" **/ ECALC_API int eCAL_Pub_ClearAttribute(ECAL_HANDLE handle_, const char* attr_name_, int attr_name_len_); - /** - * @brief Share topic type. - * - * @param handle_ Publisher handle. - * @param state_ Set type share mode (none zero == share type). - * - * @return None zero if succeeded. - **/ - ECALC_API int eCAL_Pub_ShareType(ECAL_HANDLE handle_, int state_); - - /** - * @brief Share topic description. - * - * @param handle_ Publisher handle. - * @param state_ Set description share mode (none zero == share description). - * - * @return None zero if succeeded. - **/ - ECALC_API int eCAL_Pub_ShareDescription(ECAL_HANDLE handle_, int state_); - /** * @brief Set the specific topic id. * diff --git a/ecal/core/include/ecal/ecal_publisher.h b/ecal/core/include/ecal/ecal_publisher.h index 3711f80..7abf965 100644 --- a/ecal/core/include/ecal/ecal_publisher.h +++ b/ecal/core/include/ecal/ecal_publisher.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -70,7 +71,38 @@ namespace eCAL { public: - ECAL_API static constexpr long long DEFAULT_TIME_ARGUMENT = -1; /*!< Use DEFAULT_TIME_ARGUMENT in the `Send()` function to let eCAL determine the send timestamp */ + ECAL_API static constexpr long long DEFAULT_TIME_ARGUMENT = -1; /*!< Use DEFAULT_TIME_ARGUMENT in the `Send()` function to let eCAL determine the send timestamp */ + + struct ECAL_API SHMConfig + { + TLayer::eSendMode send_mode = TLayer::smode_auto; //!< shm layer send mode (default auto) + bool zero_copy_mode = false; //!< enable zero copy shared memory transport mode + long long acknowledge_timeout_ms = 0; /*!< force connected subscribers to send acknowledge event after processing the message + the publisher send call is blocked on this event with this timeout (0 == no handshake) */ + long buffer_count = 1; //!< maximum number of used buffers (needs to be greater than 1, default = 1) + }; + + struct ECAL_API UDPConfig + { + TLayer::eSendMode send_mode = TLayer::smode_auto; //!< udp layer send mode (default auto) + }; + + struct ECAL_API TCPConfig + { + TLayer::eSendMode send_mode = TLayer::smode_off; //!< tcp layer send mode (default off) + }; + + struct ECAL_API Config + { + Config(); + + SHMConfig shm; + UDPConfig udp; + TCPConfig tcp; + + bool share_topic_type = true; + bool share_topic_description = true; + }; /** * @brief Constructor. @@ -82,15 +114,17 @@ namespace eCAL * * @param topic_name_ Unique topic name. * @param topic_info_ Topic information (encoding, type, descriptor) + * @param config_ Optional configuration parameters. **/ - ECAL_API CPublisher(const std::string& topic_name_, const SDataTypeInformation& topic_info_); + ECAL_API CPublisher(const std::string& topic_name_, const SDataTypeInformation& topic_info_, const Config& config_ = {}); /** * @brief Constructor. * * @param topic_name_ Unique topic name. + * @param config_ Optional configuration parameters. **/ - ECAL_API explicit CPublisher(const std::string& topic_name_); + ECAL_API explicit CPublisher(const std::string& topic_name_, const Config& config_ = {}); /** * @brief Destructor. @@ -122,10 +156,11 @@ namespace eCAL * * @param topic_name_ Unique topic name. * @param topic_info_ Topic information (encoding, type, descriptor) + * @param config_ Optional configuration parameters. * * @return True if it succeeds, false if it fails. **/ - ECAL_API bool Create(const std::string& topic_name_, const SDataTypeInformation& topic_info_); + ECAL_API bool Create(const std::string& topic_name_, const SDataTypeInformation& topic_info_, const Config& config_ = {}); /** * @brief Creates this object. @@ -172,24 +207,6 @@ namespace eCAL **/ ECAL_API bool ClearAttribute(const std::string& attr_name_); - /** - * @brief Share topic type. - * - * @param state_ Set type share mode (true == share type). - * - * @return True if it succeeds, false if it fails. - **/ - ECAL_API bool ShareType(bool state_ = true); - - /** - * @brief Share topic description. - * - * @param state_ Set description share mode (true == share description). - * - * @return True if it succeeds, false if it fails. - **/ - ECAL_API bool ShareDescription(bool state_ = true); - /** * @brief Set the specific topic id. * diff --git a/ecal/core/include/ecal/ecal_tlayer.h b/ecal/core/include/ecal/ecal_tlayer.h index 0fba041..3542c5a 100644 --- a/ecal/core/include/ecal/ecal_tlayer.h +++ b/ecal/core/include/ecal/ecal_tlayer.h @@ -53,6 +53,7 @@ namespace eCAL smode_auto }; + // TODO: Do weed need this ? /** * @brief eCAL transport layer state struct. **/ diff --git a/ecal/core/include/ecal/msg/capnproto/publisher.h b/ecal/core/include/ecal/msg/capnproto/publisher.h index 0809c3b..c13e5a4 100644 --- a/ecal/core/include/ecal/msg/capnproto/publisher.h +++ b/ecal/core/include/ecal/msg/capnproto/publisher.h @@ -99,9 +99,10 @@ namespace eCAL * @brief Constructor. * * @param topic_name_ Unique topic name. + * @param config_ Optional configuration parameters. **/ - CPublisher(const std::string& topic_name_) - : eCAL::CPublisher(topic_name_, GetDataTypeInformation()) + CPublisher(const std::string& topic_name_, const eCAL::CPublisher::Config& config_ = {}) + : eCAL::CPublisher(topic_name_, GetDataTypeInformation(), config_) , builder(std::make_unique()) , root_builder(builder->initRoot()) { @@ -145,12 +146,13 @@ namespace eCAL * @brief Creates this object. * * @param topic_name_ Unique topic name. + * @param config_ Optional configuration parameters. * * @return True if it succeeds, false if it fails. **/ - bool Create(const std::string& topic_name_) + bool Create(const std::string& topic_name_, const eCAL::CPublisher::Config& config_ = {}) { - return(eCAL::CPublisher::Create(topic_name_, GetDataTypeInformation())); + return(eCAL::CPublisher::Create(topic_name_, GetDataTypeInformation(), config_)); } typename message_type::Builder GetBuilder() diff --git a/ecal/core/include/ecal/msg/flatbuffers/publisher.h b/ecal/core/include/ecal/msg/flatbuffers/publisher.h index 51479fe..66746d8 100644 --- a/ecal/core/include/ecal/msg/flatbuffers/publisher.h +++ b/ecal/core/include/ecal/msg/flatbuffers/publisher.h @@ -51,8 +51,9 @@ namespace eCAL * @brief Constructor. * * @param topic_name_ Unique topic name. + * @param config_ Optional configuration parameters. **/ - CPublisher(const std::string& topic_name_) : CMsgPublisher(topic_name_, GetDataTypeInformation()) + CPublisher(const std::string& topic_name_, const Config& config_ = {}) : CMsgPublisher(topic_name_, GetDataTypeInformation(), config_) { } @@ -80,12 +81,13 @@ namespace eCAL * @brief Creates this object. * * @param topic_name_ Unique topic name. + * @param config_ Optional configuration parameters. * * @return True if it succeeds, false if it fails. **/ - bool Create(const std::string& topic_name_) + bool Create(const std::string& topic_name_, const Config& config_ = {}) { - return(CMsgPublisher::Create(topic_name_, GetDataTypeInformation())); + return(CMsgPublisher::Create(topic_name_, GetDataTypeInformation(), config_)); } private: diff --git a/ecal/core/include/ecal/msg/messagepack/publisher.h b/ecal/core/include/ecal/msg/messagepack/publisher.h index 8886b95..e6f09d4 100644 --- a/ecal/core/include/ecal/msg/messagepack/publisher.h +++ b/ecal/core/include/ecal/msg/messagepack/publisher.h @@ -54,8 +54,9 @@ namespace eCAL * @brief Constructor. * * @param topic_name_ Unique topic name. + * @param config_ Optional configuration parameters. **/ - CPublisher(const std::string& topic_name_) : CMsgPublisher(topic_name_, GetDataTypeInformation()) + CPublisher(const std::string& topic_name_, const Config& config_ = {}) : CMsgPublisher(topic_name_, GetDataTypeInformation(), config_) { } @@ -83,12 +84,13 @@ namespace eCAL * @brief Creates this object. * * @param topic_name_ Unique topic name. + * @param config_ Optional configuration parameters. * * @return True if it succeeds, false if it fails. **/ - bool Create(const std::string& topic_name_) + bool Create(const std::string& topic_name_, const Config& config_ = {}) { - return(CMsgPublisher::Create(topic_name_, GetDataTypeInformation())); + return(CMsgPublisher::Create(topic_name_, GetDataTypeInformation(), config_)); } private: diff --git a/ecal/core/include/ecal/msg/protobuf/publisher.h b/ecal/core/include/ecal/msg/protobuf/publisher.h index 8db60be..c0d03da 100644 --- a/ecal/core/include/ecal/msg/protobuf/publisher.h +++ b/ecal/core/include/ecal/msg/protobuf/publisher.h @@ -106,7 +106,7 @@ namespace eCAL // where the vtable is not created yet, or it's destructed. // Probably we can handle the Message publishers differently. One message publisher class and then one class for payloads and getting type // descriptor information. - explicit CPublisher(const std::string& topic_name_) : eCAL::CPublisher(topic_name_, CPublisher::GetDataTypeInformation()) + explicit CPublisher(const std::string& topic_name_, const Config& config_ = {}) : eCAL::CPublisher(topic_name_, CPublisher::GetDataTypeInformation(), config_) { } @@ -139,12 +139,13 @@ namespace eCAL * @brief Creates this object. * * @param topic_name_ Unique topic name. + * @param config_ Optional configuration parameters. * * @return True if it succeeds, false if it fails. **/ - bool Create(const std::string& topic_name_) + bool Create(const std::string& topic_name_, const Config& config_ = {}) { - return(eCAL::CPublisher::Create(topic_name_, GetDataTypeInformation())); + return(eCAL::CPublisher::Create(topic_name_, GetDataTypeInformation(), config_)); } /** diff --git a/ecal/core/include/ecal/msg/publisher.h b/ecal/core/include/ecal/msg/publisher.h index 91988c9..dbc0c33 100644 --- a/ecal/core/include/ecal/msg/publisher.h +++ b/ecal/core/include/ecal/msg/publisher.h @@ -61,8 +61,9 @@ namespace eCAL * * @param topic_name_ Unique topic name. * @param topic_info_ Struct that contains information of the datatype (name, encoding, description) of the topic. + * @param config_ Optional configuration parameters. **/ - CMsgPublisher(const std::string& topic_name_, const struct SDataTypeInformation& topic_info_) : CPublisher(topic_name_, topic_info_) + CMsgPublisher(const std::string& topic_name_, const struct SDataTypeInformation& topic_info_, const Config& config_ = {}) : CPublisher(topic_name_, topic_info_, config_) { } @@ -71,8 +72,9 @@ namespace eCAL * If no datatype information about the topic is available, this constructor can be used. * * @param topic_name_ Unique topic name. + * @param config_ Optional configuration parameters. **/ - explicit CMsgPublisher(const std::string& topic_name_) : CMsgPublisher(topic_name_, GetDataTypeInformation()) + explicit CMsgPublisher(const std::string& topic_name_, const Config& config_ = {}) : CMsgPublisher(topic_name_, GetDataTypeInformation(), config_) { } @@ -103,12 +105,13 @@ namespace eCAL * * @param topic_name_ Unique topic name. * @param topic_info_ Associated datatype description. + * @param config_ Optional configuration parameters. * * @return True if it succeeds, false if it fails. **/ - bool Create(const std::string& topic_name_, const struct SDataTypeInformation& topic_info_) + bool Create(const std::string& topic_name_, const struct SDataTypeInformation& topic_info_, const Config& config_ = {}) { - return(CPublisher::Create(topic_name_, topic_info_)); + return(CPublisher::Create(topic_name_, topic_info_, config_)); } /** diff --git a/ecal/core/include/ecal/msg/string/publisher.h b/ecal/core/include/ecal/msg/string/publisher.h index 8555c49..a51aad0 100644 --- a/ecal/core/include/ecal/msg/string/publisher.h +++ b/ecal/core/include/ecal/msg/string/publisher.h @@ -60,7 +60,7 @@ namespace eCAL // call the function via its class because it's a virtual function that is called in constructor/destructor,- // where the vtable is not created yet, or it's destructed. - explicit CPublisher(const std::string& topic_name_) : CMsgPublisher(topic_name_, GetDataTypeInformation()) + explicit CPublisher(const std::string& topic_name_, const Config& config_ = {}) : CMsgPublisher(topic_name_, GetDataTypeInformation(), config_) { } @@ -88,12 +88,13 @@ namespace eCAL * @brief Creates this object. * * @param topic_name_ Unique topic name. + * @param config_ Optional configuration parameters. * * @return True if it succeeds, false if it fails. **/ - bool Create(const std::string& topic_name_) + bool Create(const std::string& topic_name_, const Config& config_ = {}) { - return(CMsgPublisher::Create(topic_name_, GetDataTypeInformation())); + return(CMsgPublisher::Create(topic_name_, GetDataTypeInformation(), config_)); } private: diff --git a/ecal/core/src/cimpl/ecal_publisher_cimpl.cpp b/ecal/core/src/cimpl/ecal_publisher_cimpl.cpp index 3d1acdf..cec91d2 100644 --- a/ecal/core/src/cimpl/ecal_publisher_cimpl.cpp +++ b/ecal/core/src/cimpl/ecal_publisher_cimpl.cpp @@ -89,22 +89,6 @@ extern "C" return(0); } - ECALC_API int eCAL_Pub_ShareType(ECAL_HANDLE handle_, int state_) - { - if (handle_ == nullptr) return(0); - auto* pub = static_cast(handle_); - pub->ShareType(state_ != 0); - return(1); - } - - ECALC_API int eCAL_Pub_ShareDescription(ECAL_HANDLE handle_, int state_) - { - if (handle_ == nullptr) return(0); - auto* pub = static_cast(handle_); - pub->ShareDescription(state_ != 0); - return(1); - } - ECALC_API int eCAL_Pub_SetID(ECAL_HANDLE handle_, long long id_) { if (handle_ == nullptr) return(0); diff --git a/ecal/core/src/pubsub/ecal_pubgate.cpp b/ecal/core/src/pubsub/ecal_pubgate.cpp index e285cef..aadd4f2 100644 --- a/ecal/core/src/pubsub/ecal_pubgate.cpp +++ b/ecal/core/src/pubsub/ecal_pubgate.cpp @@ -60,10 +60,7 @@ namespace eCAL // destroy all remaining publisher const std::unique_lock lock(m_topic_name_datawriter_sync); - for (auto iter = m_topic_name_datawriter_map.begin(); iter != m_topic_name_datawriter_map.end(); ++iter) - { - iter->second->Destroy(); - } + m_topic_name_datawriter_map.clear(); m_created = false; } diff --git a/ecal/core/src/pubsub/ecal_publisher.cpp b/ecal/core/src/pubsub/ecal_publisher.cpp index 9a917e8..a3f7ce0 100644 --- a/ecal/core/src/pubsub/ecal_publisher.cpp +++ b/ecal/core/src/pubsub/ecal_publisher.cpp @@ -35,6 +35,25 @@ namespace eCAL { + CPublisher::Config::Config() + { + // shm config + shm.send_mode = eCAL::Config::GetPublisherShmMode(); + shm.buffer_count = eCAL::Config::GetMemfileBufferCount(); + shm.zero_copy_mode = eCAL::Config::IsMemfileZerocopyEnabled(); + shm.acknowledge_timeout_ms = eCAL::Config::GetMemfileAckTimeoutMs(); + + // udp config + udp.send_mode = eCAL::Config::GetPublisherUdpMulticastMode(); + + // tcp config + tcp.send_mode = eCAL::Config::GetPublisherTcpMode(); + + // allow to share topic type/description + share_topic_type = eCAL::Config::IsTopicTypeSharingEnabled(); + share_topic_description = eCAL::Config::IsTopicDescriptionSharingEnabled(); + } + CPublisher::CPublisher() : m_datawriter(nullptr), m_id(0), @@ -43,14 +62,14 @@ namespace eCAL { } - CPublisher::CPublisher(const std::string& topic_name_, const SDataTypeInformation& data_type_info_) + CPublisher::CPublisher(const std::string& topic_name_, const SDataTypeInformation& data_type_info_, const Config& config_) : CPublisher() { - CPublisher::Create(topic_name_, data_type_info_); + CPublisher::Create(topic_name_, data_type_info_, config_); } - CPublisher::CPublisher(const std::string& topic_name_) - : CPublisher(topic_name_, SDataTypeInformation{}) + CPublisher::CPublisher(const std::string& topic_name_, const Config& config_) + : CPublisher(topic_name_, SDataTypeInformation{}, config_) {} CPublisher::~CPublisher() @@ -90,7 +109,7 @@ namespace eCAL return *this; } - bool CPublisher::Create(const std::string& topic_name_, const SDataTypeInformation& data_type_info_) + bool CPublisher::Create(const std::string& topic_name_, const SDataTypeInformation& data_type_info_, const Config& config_) { if (m_created) return(false); if (topic_name_.empty()) return(false); @@ -104,19 +123,8 @@ namespace eCAL } // create data writer - m_datawriter = std::make_shared(); - if (!m_datawriter->Create(topic_name_, data_type_info_)) - { -#ifndef NDEBUG - // log it - if (g_log() != nullptr) g_log()->Log(log_level_debug1, topic_name_ + "::CPublisher::Create - FAILED"); -#endif - return(false); - } -#ifndef NDEBUG - // log it - if (g_log() != nullptr) g_log()->Log(log_level_debug1, topic_name_ + "::CPublisher::Create - SUCCESS"); -#endif + m_datawriter = std::make_shared(topic_name_, data_type_info_, config_); + // register publisher gateway (for publisher memory file and event name) g_pubgate()->Register(topic_name_, m_datawriter); @@ -136,9 +144,6 @@ namespace eCAL if(!m_created) return(false); if(g_globals() == nullptr) return(false); - // destroy data writer - m_datawriter->Destroy(); - // unregister data writer if(g_pubgate() != nullptr) g_pubgate()->Unregister(m_datawriter->GetTopicName(), m_datawriter); #ifndef NDEBUG @@ -146,7 +151,7 @@ namespace eCAL if (g_log() != nullptr) g_log()->Log(log_level_debug1, std::string(m_datawriter->GetTopicName() + "::CPublisher::Destroy")); #endif - // free datawriter + // destroy datawriter m_datawriter.reset(); // we made it :-) @@ -181,20 +186,6 @@ namespace eCAL return m_datawriter->ClearAttribute(attr_name_); } - bool CPublisher::ShareType(bool state_ /*= true*/) - { - if (m_datawriter == nullptr) return false; - m_datawriter->ShareType(state_); - return true; - } - - bool CPublisher::ShareDescription(bool state_ /*= true*/) - { - if (m_datawriter == nullptr) return false; - m_datawriter->ShareDescription(state_); - return true; - } - bool CPublisher::SetID(long long id_) { m_id = id_; @@ -289,4 +280,4 @@ namespace eCAL return(out.str()); } -} +} \ No newline at end of file diff --git a/ecal/core/src/readwrite/ecal_reader.cpp b/ecal/core/src/readwrite/ecal_reader.cpp index 71ad234..1983ecb 100644 --- a/ecal/core/src/readwrite/ecal_reader.cpp +++ b/ecal/core/src/readwrite/ecal_reader.cpp @@ -74,8 +74,8 @@ namespace eCAL m_message_drops(0), m_loc_published(false), m_ext_published(false), - m_use_ttype(true), - m_use_tdesc(true), + m_share_ttype(true), + m_share_tdesc(true), m_use_udp_mc_confirmed(false), m_use_shm_confirmed(false), m_use_tcp_confirmed(false), @@ -114,10 +114,10 @@ namespace eCAL m_ext_pub_map.set_expiration(registration_timeout); // allow to share topic type - m_use_ttype = Config::IsTopicTypeSharingEnabled(); + m_share_ttype = Config::IsTopicTypeSharingEnabled(); // allow to share topic description - m_use_tdesc = Config::IsTopicDescriptionSharingEnabled(); + m_share_tdesc = Config::IsTopicDescriptionSharingEnabled(); // start transport layers SubscribeToLayers(); @@ -246,12 +246,12 @@ namespace eCAL // topic_information { auto& ecal_reg_sample_tdatatype = ecal_reg_sample_topic.tdatatype; - if (m_use_ttype) + if (m_share_ttype) { ecal_reg_sample_tdatatype.encoding = m_topic_info.encoding; ecal_reg_sample_tdatatype.name = m_topic_info.name; } - if (m_use_tdesc) + if (m_share_tdesc) { ecal_reg_sample_tdatatype.descriptor = m_topic_info.descriptor; } diff --git a/ecal/core/src/readwrite/ecal_reader.h b/ecal/core/src/readwrite/ecal_reader.h index 2aa3d10..ca56d8b 100644 --- a/ecal/core/src/readwrite/ecal_reader.h +++ b/ecal/core/src/readwrite/ecal_reader.h @@ -159,8 +159,8 @@ namespace eCAL std::atomic m_loc_published; std::atomic m_ext_published; - bool m_use_ttype; - bool m_use_tdesc; + bool m_share_ttype; + bool m_share_tdesc; bool m_use_udp_mc_confirmed; bool m_use_shm_confirmed; diff --git a/ecal/core/src/readwrite/ecal_writer.cpp b/ecal/core/src/readwrite/ecal_writer.cpp index 806deda..1d6c589 100644 --- a/ecal/core/src/readwrite/ecal_writer.cpp +++ b/ecal/core/src/readwrite/ecal_writer.cpp @@ -68,7 +68,7 @@ namespace std namespace eCAL { - CDataWriter::CDataWriter() : + CDataWriter::CDataWriter(const std::string& topic_name_, const SDataTypeInformation& topic_info_, const CPublisher::Config& config_) : m_host_name(Process::GetHostName()), m_host_group_name(Process::GetHostGroupName()), m_pid(Process::GetProcessID()), @@ -80,48 +80,25 @@ namespace eCAL m_connected(false), m_id(0), m_clock(0), - m_frequency_calculator(3.0f), + m_frequency_calculator(0.0f), m_loc_subscribed(false), m_ext_subscribed(false), - m_use_ttype(true), - m_use_tdesc(true), - m_share_ttype(-1), - m_share_tdesc(-1), + m_share_ttype(true), + m_share_tdesc(true), m_created(false) { - // initialize layer modes with configuration settings -#if ECAL_CORE_TRANSPORT_UDP - m_writer.udp_mc_mode.requested = Config::GetPublisherUdpMulticastMode(); -#endif -#if ECAL_CORE_TRANSPORT_SHM - m_writer.shm_mode.requested = Config::GetPublisherShmMode(); -#endif -#if ECAL_CORE_TRANSPORT_TCP - m_writer.tcp_mode.requested = Config::GetPublisherTcpMode(); -#endif - } - - CDataWriter::~CDataWriter() - { - Destroy(); - } - - bool CDataWriter::Create(const std::string& topic_name_, const SDataTypeInformation& topic_info_) - { - if (m_created) return(false); - // set defaults - m_topic_name = topic_name_; + m_topic_name = topic_name_; m_topic_id.clear(); - m_topic_info = topic_info_; - m_id = 0; - m_clock = 0; - m_buffering_shm = Config::GetMemfileBufferCount(); - m_zero_copy = Config::IsMemfileZerocopyEnabled(); - m_acknowledge_timeout_ms = Config::GetMemfileAckTimeoutMs(); - m_connected = false; - m_ext_subscribed = false; - m_created = false; + m_topic_info = topic_info_; + m_id = 0; + m_clock = 0; + m_connected = false; + m_ext_subscribed = false; + m_created = false; + + // configure + Configure(config_); // build topic id std::stringstream counter; @@ -133,12 +110,6 @@ namespace eCAL m_loc_sub_map.set_expiration(registration_timeout); m_ext_sub_map.set_expiration(registration_timeout); - // allow to share topic type - m_use_ttype = Config::IsTopicTypeSharingEnabled(); - - // allow to share topic description - m_use_tdesc = Config::IsTopicDescriptionSharingEnabled(); - // mark as created m_created = true; @@ -156,22 +127,15 @@ namespace eCAL #ifndef NDEBUG // log it - Logging::Log(log_level_debug1, m_topic_name + "::CDataWriter::Created"); + Logging::Log(log_level_debug1, m_topic_name + "::CDataWriter::Constructor"); #endif - - // adapt number of used memory file - ShmSetBufferCount(m_buffering_shm); - - return(true); } - bool CDataWriter::Destroy() + CDataWriter::~CDataWriter() { - if (!m_created) return(false); - #ifndef NDEBUG // log it - Logging::Log(log_level_debug1, m_topic_name + "::CDataWriter::Destroy"); + Logging::Log(log_level_debug1, m_topic_name + "::CDataWriter::Destructor"); #endif // destroy udp multicast writer @@ -190,12 +154,12 @@ namespace eCAL #endif // reset defaults - m_id = 0; - m_clock = 0; - m_buffering_shm = Config::GetMemfileBufferCount(); - m_zero_copy = Config::IsMemfileZerocopyEnabled(); - m_acknowledge_timeout_ms = Config::GetMemfileAckTimeoutMs(); - m_connected = false; + m_id = 0; + m_clock = 0; + m_connected = false; + + // reset configuration + Configure({}); // reset subscriber maps { @@ -215,10 +179,33 @@ namespace eCAL // and unregister Unregister(); - - return(true); } + void CDataWriter::Configure(const CPublisher::Config& config_) + { + // shm config +#if ECAL_CORE_TRANSPORT_SHM + m_writer.shm_mode.requested = config_.shm.send_mode; + m_buffering_shm = config_.shm.buffer_count; + m_zero_copy = config_.shm.zero_copy_mode; + m_acknowledge_timeout_ms = config_.shm.acknowledge_timeout_ms; +#endif + + // udp config +#if ECAL_CORE_TRANSPORT_UDP + m_writer.udp_mc_mode.requested = config_.udp.send_mode; +#endif + + // tcp config +#if ECAL_CORE_TRANSPORT_TCP + m_writer.tcp_mode.requested = config_.tcp.send_mode; +#endif + + // allow to share topic type/description + m_share_ttype = config_.share_topic_type; + m_share_tdesc = config_.share_topic_description; + } + bool CDataWriter::SetDataTypeInformation(const SDataTypeInformation& topic_info_) { // Does it even make sense to register if the info is the same??? @@ -271,101 +258,6 @@ namespace eCAL return(true); } - void CDataWriter::ShareType(bool state_) - { - if (state_) - { - m_share_ttype = 1; - } - else - { - m_share_ttype = 0; - } - } - - void CDataWriter::ShareDescription(bool state_) - { - if (state_) - { - m_share_tdesc = 1; - } - else - { - m_share_tdesc = 0; - } - } - - bool CDataWriter::SetLayerMode(TLayer::eTransportLayer layer_, TLayer::eSendMode mode_) - { - switch (layer_) - { - case TLayer::tlayer_udp_mc: - SetUseUdpMC(mode_); - break; - case TLayer::tlayer_shm: - SetUseShm(mode_); - break; - case TLayer::tlayer_tcp: - SetUseTcp(mode_); - break; - case TLayer::tlayer_all: - SetUseUdpMC(mode_); - SetUseShm(mode_); - SetUseTcp(mode_); - break; - default: - break; - } - return true; - } - - bool CDataWriter::ShmSetBufferCount(size_t buffering_) - { -#if ECAL_CORE_TRANSPORT_SHM - if (buffering_ < 1) - { - Logging::Log(log_level_error, m_topic_name + "::CDataWriter::ShmSetBufferCount minimal number of memory files is 1 !"); - return false; - } - m_buffering_shm = static_cast(buffering_); - - // adapt number of used memory files - if (m_created) - { - m_writer.shm.SetBufferCount(buffering_); - } - - return true; -#else - return false; -#endif - } - - bool CDataWriter::ShmEnableZeroCopy(bool state_) - { -#if ECAL_CORE_TRANSPORT_SHM - m_zero_copy = state_; - return true; -#else - return false; -#endif - } - - bool CDataWriter::ShmSetAcknowledgeTimeout(long long acknowledge_timeout_ms_) - { -#if ECAL_CORE_TRANSPORT_SHM - m_acknowledge_timeout_ms = acknowledge_timeout_ms_; - return true; -#else - return false; -#endif - } - - long long CDataWriter::ShmGetAcknowledgeTimeout() const - { - return m_acknowledge_timeout_ms; - } - bool CDataWriter::AddEventCallback(eCAL_Publisher_Event type_, PubEventCallbackT callback_) { if (!m_created) return(false); @@ -775,19 +667,6 @@ namespace eCAL if (!m_created) return(false); if (m_topic_name.empty()) return(false); - //@Rex: why is the logic different in CDataReader??? - // check share modes - bool share_ttype(m_use_ttype && (g_pubgate() != nullptr) && g_pubgate()->TypeShared()); - if (m_share_ttype != -1) - { - share_ttype = m_share_ttype == 1; - } - bool share_tdesc(m_use_tdesc && (g_pubgate() != nullptr) && g_pubgate()->DescriptionShared()); - if (m_share_tdesc != -1) - { - share_tdesc = m_share_tdesc == 1; - } - // create command parameter Registration::Sample ecal_reg_sample; ecal_reg_sample.cmd_type = bct_reg_publisher; @@ -800,12 +679,12 @@ namespace eCAL // topic_information { auto& ecal_reg_sample_tdatatype = ecal_reg_sample_topic.tdatatype; - if (share_ttype) + if (m_share_ttype) { ecal_reg_sample_tdatatype.encoding = m_topic_info.encoding; ecal_reg_sample_tdatatype.name = m_topic_info.name; } - if (share_tdesc) + if (m_share_tdesc) { ecal_reg_sample_tdatatype.descriptor = m_topic_info.descriptor; } @@ -1029,6 +908,10 @@ namespace eCAL m_writer.shm.Destroy(); break; } + + // set shm buffer count + m_writer.shm.SetBufferCount(m_buffering_shm); + #endif // ECAL_CORE_TRANSPORT_SHM } diff --git a/ecal/core/src/readwrite/ecal_writer.h b/ecal/core/src/readwrite/ecal_writer.h index 51b60db..c2446c3 100644 --- a/ecal/core/src/readwrite/ecal_writer.h +++ b/ecal/core/src/readwrite/ecal_writer.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -84,28 +85,14 @@ namespace eCAL } }; - CDataWriter(); + CDataWriter(const std::string& topic_name_, const SDataTypeInformation& topic_info_, const CPublisher::Config& config_ = {}); ~CDataWriter(); - bool Create(const std::string& topic_name_, const SDataTypeInformation& topic_info_); - bool Destroy(); - bool SetDataTypeInformation(const SDataTypeInformation& topic_info_); bool SetAttribute(const std::string& attr_name_, const std::string& attr_value_); bool ClearAttribute(const std::string& attr_name_); - void ShareType(bool state_); - void ShareDescription(bool state_); - - bool SetLayerMode(TLayer::eTransportLayer layer_, TLayer::eSendMode mode_); - - bool ShmSetBufferCount(size_t buffering_); - bool ShmEnableZeroCopy(bool state_); - - bool ShmSetAcknowledgeTimeout(long long acknowledge_timeout_ms_); - long long ShmGetAcknowledgeTimeout() const; - bool AddEventCallback(eCAL_Publisher_Event type_, PubEventCallbackT callback_); bool RemEventCallback(eCAL_Publisher_Event type_); @@ -135,6 +122,8 @@ namespace eCAL const SDataTypeInformation& GetDataTypeInformation() const { return m_topic_info; } protected: + void Configure(const CPublisher::Config& config_); + bool Register(bool force_); bool Unregister(); @@ -214,10 +203,8 @@ namespace eCAL }; SWriter m_writer; - bool m_use_ttype; - bool m_use_tdesc; - int m_share_ttype; - int m_share_tdesc; + bool m_share_ttype; + bool m_share_tdesc; std::atomic m_created; }; } diff --git a/ecal/samples/CMakeLists.txt b/ecal/samples/CMakeLists.txt index a2ec632..fadfdad 100644 --- a/ecal/samples/CMakeLists.txt +++ b/ecal/samples/CMakeLists.txt @@ -102,6 +102,9 @@ if(ECAL_CORE_PUBLISHER) if(ECAL_CORE_HAS_PROTOBUF) add_subdirectory(cpp/pubsub/protobuf/person_events_snd) add_subdirectory(cpp/pubsub/protobuf/person_snd) + if(ECAL_CORE_TRANSPORT_TCP) + add_subdirectory(cpp/pubsub/protobuf/person_snd_tcp) + endif() endif() endif() diff --git a/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/CMakeLists.txt b/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/CMakeLists.txt new file mode 100644 index 0000000..131fa14 --- /dev/null +++ b/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/CMakeLists.txt @@ -0,0 +1,50 @@ +# ========================= eCAL LICENSE ================================= +# +# Copyright (C) 2016 - 2019 Continental Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ========================= eCAL LICENSE ================================= + +cmake_minimum_required(VERSION 3.10) + +set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) + +project(person_snd_tcp) + +find_package(eCAL REQUIRED) +find_package(Protobuf REQUIRED) + +set(person_snd_tcp_src + src/person_snd_tcp.cpp +) + +set(person_snd_tcp_proto + ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf/animal.proto + ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf/house.proto + ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf/person.proto +) + +ecal_add_sample(${PROJECT_NAME} ${person_snd_tcp_src}) +PROTOBUF_TARGET_CPP(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/src/protobuf ${person_snd_tcp_proto}) + +target_link_libraries(${PROJECT_NAME} + PRIVATE + eCAL::core_protobuf +) + +target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) + +ecal_install_sample(${PROJECT_NAME}) + +set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER samples/cpp/pubsub/protobuf) diff --git a/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/person_snd_tcp.cpp b/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/person_snd_tcp.cpp new file mode 100644 index 0000000..e7e079a --- /dev/null +++ b/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/person_snd_tcp.cpp @@ -0,0 +1,81 @@ +/* ========================= eCAL LICENSE ================================= + * + * Copyright (C) 2016 - 2019 Continental Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ========================= eCAL LICENSE ================================= +*/ + +#include +#include + +#include + +#include "person.pb.h" + +int main(int argc, char **argv) +{ + // initialize eCAL API + eCAL::Initialize(argc, argv, "person publisher tcp"); + + // set process state + eCAL::Process::SetState(proc_sev_healthy, proc_sev_level1, "I feel good !"); + + // create a publisher config + eCAL::CPublisher::Config pub_config; + + // switch shm and udp layer off, tcp layer on + pub_config.shm.send_mode = eCAL::TLayer::smode_off; + pub_config.udp.send_mode = eCAL::TLayer::smode_off; + pub_config.tcp.send_mode = eCAL::TLayer::smode_on; + + // create a publisher (topic name "person") + eCAL::protobuf::CPublisher pub("person", pub_config); + + // generate a class instance of Person + pb::People::Person person; + + // enter main loop + auto cnt(0); + while (eCAL::Ok()) + { + // set person object content + person.set_id(++cnt); + person.set_name("Max"); + person.set_stype(pb::People::Person_SType_MALE); + person.set_email("max@mail.net"); + person.mutable_dog()->set_name("Brandy"); + person.mutable_house()->set_rooms(4); + + // send the person object + pub.Send(person); + + // print content + std::cout << "person id : " << person.id() << std::endl; + std::cout << "person name : " << person.name() << std::endl; + std::cout << "person stype : " << person.stype() << std::endl; + std::cout << "person email : " << person.email() << std::endl; + std::cout << "dog.name : " << person.dog().name() << std::endl; + std::cout << "house.rooms : " << person.house().rooms() << std::endl; + std::cout << std::endl; + + // sleep 500 ms + eCAL::Process::SleepMS(500); + } + + // finalize eCAL API + eCAL::Finalize(); + + return(0); +} diff --git a/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/animal.proto b/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/animal.proto new file mode 100644 index 0000000..625a78d --- /dev/null +++ b/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/animal.proto @@ -0,0 +1,28 @@ +/* ========================= eCAL LICENSE ================================= + * + * Copyright (C) 2016 - 2019 Continental Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ========================= eCAL LICENSE ================================= +*/ + +syntax = "proto3"; + +package pb.Animal; + +message Dog +{ + string name = 1; + string colour = 2; +} diff --git a/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/house.proto b/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/house.proto new file mode 100644 index 0000000..fbe8cce --- /dev/null +++ b/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/house.proto @@ -0,0 +1,27 @@ +/* ========================= eCAL LICENSE ================================= + * + * Copyright (C) 2016 - 2019 Continental Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ========================= eCAL LICENSE ================================= +*/ + +syntax = "proto3"; + +package pb.Environment; + +message House +{ + int32 rooms = 1; +} diff --git a/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/person.proto b/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/person.proto new file mode 100644 index 0000000..4200a43 --- /dev/null +++ b/ecal/samples/cpp/pubsub/protobuf/person_snd_tcp/src/protobuf/person.proto @@ -0,0 +1,42 @@ +/* ========================= eCAL LICENSE ================================= + * + * Copyright (C) 2016 - 2019 Continental Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ========================= eCAL LICENSE ================================= +*/ + +syntax = "proto3"; + +import "animal.proto"; +import "house.proto"; + +package pb.People; + +message Person +{ + enum SType + { + MALE = 0; + FEMALE = 1; + } + + int32 id = 1; + string name = 2; + SType stype = 3; + string email = 4; + + Animal.Dog dog = 5; + Environment.House house = 6; +}