From ea8273115a78b31e00a0f842e6c4b2af7fdb2212 Mon Sep 17 00:00:00 2001 From: elianalf <62831776+elianalf@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:53:54 +0200 Subject: [PATCH] Example refactor: Custom payload pool (#4889) * Refs #21094: Change folder name and delete old folder Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Refactor of the main Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Add CLI Parser Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Publisher refactor Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Subscriber refactor Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Change example name and fix interval parsing Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Add test Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Update version.md Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Apply suggestions: Use HelloWOrld instead of CUstomPayloadPoolData Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Apply suggestions Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Update ReadMe file Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Uncrustify Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Split test Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> * Refs #21094: Fix compilation error in Windows Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> --------- Signed-off-by: elianalf <62831776+elianalf@users.noreply.github.com> --- examples/CMakeLists.txt | 1 + .../cpp/custom_payload_pool/Application.cpp | 58 +++ .../cpp/custom_payload_pool/Application.hpp | 56 +++ .../cpp/custom_payload_pool/CLIParser.hpp | 332 ++++++++++++++++++ .../CMakeLists.txt | 12 +- .../CustomPayloadPool.hpp | 6 +- .../HelloWorld.hpp} | 62 ++-- .../cpp/custom_payload_pool/HelloWorld.idl | 6 + .../HelloWorldCdrAux.hpp} | 16 +- .../HelloWorldCdrAux.ipp} | 18 +- .../HelloWorldPubSubTypes.cxx} | 56 +-- .../HelloWorldPubSubTypes.h} | 24 +- .../HelloWorldTypeObjectSupport.cxx | 243 +++++++++++++ .../HelloWorldTypeObjectSupport.hpp} | 14 +- .../cpp/custom_payload_pool/PublisherApp.cpp | 180 ++++++++++ .../cpp/custom_payload_pool/PublisherApp.hpp | 106 ++++++ examples/cpp/custom_payload_pool/README.md | 89 +++++ .../cpp/custom_payload_pool/SubscriberApp.cpp | 164 +++++++++ .../cpp/custom_payload_pool/SubscriberApp.hpp | 104 ++++++ examples/cpp/custom_payload_pool/main.cpp | 108 ++++++ examples/cpp/dds/CMakeLists.txt | 1 - .../CustomPayloadPoolData.idl | 5 - .../CustomPayloadPoolDataPublisher.cpp | 224 ------------ .../CustomPayloadPoolDataPublisher.h | 115 ------ .../CustomPayloadPoolDataSubscriber.cpp | 189 ---------- .../CustomPayloadPoolDataSubscriber.h | 95 ----- ...CustomPayloadPoolDataTypeObjectSupport.cxx | 236 ------------- .../CustomPayloadPool_main.cpp | 317 ----------------- .../dds/CustomPayloadPoolExample/README.md | 13 - test/examples/custom_payload_pool.compose.yml | 29 ++ test/examples/test_custom_payload_pool.py | 39 ++ versions.md | 1 + 32 files changed, 1620 insertions(+), 1299 deletions(-) create mode 100644 examples/cpp/custom_payload_pool/Application.cpp create mode 100644 examples/cpp/custom_payload_pool/Application.hpp create mode 100644 examples/cpp/custom_payload_pool/CLIParser.hpp rename examples/cpp/{dds/CustomPayloadPoolExample => custom_payload_pool}/CMakeLists.txt (75%) rename examples/cpp/{dds/CustomPayloadPoolExample => custom_payload_pool}/CustomPayloadPool.hpp (95%) rename examples/cpp/{dds/CustomPayloadPoolExample/CustomPayloadPoolData.hpp => custom_payload_pool/HelloWorld.hpp} (70%) create mode 100644 examples/cpp/custom_payload_pool/HelloWorld.idl rename examples/cpp/{dds/CustomPayloadPoolExample/CustomPayloadPoolDataCdrAux.hpp => custom_payload_pool/HelloWorldCdrAux.hpp} (68%) rename examples/cpp/{dds/CustomPayloadPoolExample/CustomPayloadPoolDataCdrAux.ipp => custom_payload_pool/HelloWorldCdrAux.ipp} (89%) rename examples/cpp/{dds/CustomPayloadPoolExample/CustomPayloadPoolDataPubSubTypes.cxx => custom_payload_pool/HelloWorldPubSubTypes.cxx} (78%) rename examples/cpp/{dds/CustomPayloadPoolExample/CustomPayloadPoolDataPubSubTypes.h => custom_payload_pool/HelloWorldPubSubTypes.h} (81%) create mode 100644 examples/cpp/custom_payload_pool/HelloWorldTypeObjectSupport.cxx rename examples/cpp/{dds/CustomPayloadPoolExample/CustomPayloadPoolDataTypeObjectSupport.hpp => custom_payload_pool/HelloWorldTypeObjectSupport.hpp} (79%) create mode 100644 examples/cpp/custom_payload_pool/PublisherApp.cpp create mode 100644 examples/cpp/custom_payload_pool/PublisherApp.hpp create mode 100644 examples/cpp/custom_payload_pool/README.md create mode 100644 examples/cpp/custom_payload_pool/SubscriberApp.cpp create mode 100644 examples/cpp/custom_payload_pool/SubscriberApp.hpp create mode 100644 examples/cpp/custom_payload_pool/main.cpp delete mode 100644 examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolData.idl delete mode 100644 examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPublisher.cpp delete mode 100644 examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPublisher.h delete mode 100644 examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataSubscriber.cpp delete mode 100644 examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataSubscriber.h delete mode 100644 examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataTypeObjectSupport.cxx delete mode 100644 examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPool_main.cpp delete mode 100644 examples/cpp/dds/CustomPayloadPoolExample/README.md create mode 100644 test/examples/custom_payload_pool.compose.yml create mode 100644 test/examples/test_custom_payload_pool.py diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d837be602f..84ef0d3d6d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -14,6 +14,7 @@ set(fastdds_FOUND TRUE) add_subdirectory(cpp/configuration) +add_subdirectory(cpp/custom_payload_pool) add_subdirectory(cpp/dds) add_subdirectory(cpp/hello_world) add_subdirectory(cpp/rtps) diff --git a/examples/cpp/custom_payload_pool/Application.cpp b/examples/cpp/custom_payload_pool/Application.cpp new file mode 100644 index 0000000000..c4c059fb0f --- /dev/null +++ b/examples/cpp/custom_payload_pool/Application.cpp @@ -0,0 +1,58 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +/** + * @file Application.cpp + * + */ + +#include "Application.hpp" + +#include "CLIParser.hpp" +#include "PublisherApp.hpp" +#include "SubscriberApp.hpp" + +using namespace eprosima::fastdds::dds; + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace custom_payload_pool { + +//! Factory method to create a publisher or subscriber +std::shared_ptr Application::make_app( + const CLIParser::custom_payload_pool_config& config, + const std::string& topic_name) +{ + std::shared_ptr entity; + switch (config.entity) + { + case CLIParser::EntityKind::PUBLISHER: + entity = std::make_shared(config.pub_config, topic_name); + break; + case CLIParser::EntityKind::SUBSCRIBER: + entity = std::make_shared(config.sub_config, topic_name); + break; + case CLIParser::EntityKind::UNDEFINED: + default: + throw std::runtime_error("Entity initialization failed"); + break; + } + return entity; +} + +} // namespace custom_payload_pool +} // namespace examples +} // namespace fastdds +} // namespace eprosima diff --git a/examples/cpp/custom_payload_pool/Application.hpp b/examples/cpp/custom_payload_pool/Application.hpp new file mode 100644 index 0000000000..3a78297c96 --- /dev/null +++ b/examples/cpp/custom_payload_pool/Application.hpp @@ -0,0 +1,56 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +/** + * @file Application.hpp + * + */ + +#ifndef _FASTDDS_CUSTOM_PAYLOAD_POOL_APPLICATION_HPP_ +#define _FASTDDS_CUSTOM_PAYLOAD_POOL_APPLICATION_HPP_ + +#include + +#include "CLIParser.hpp" + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace custom_payload_pool { + +class Application +{ +public: + + //! Virtual destructor + virtual ~Application() = default; + + //! Run application + virtual void run() = 0; + + //! Trigger the end of execution + virtual void stop() = 0; + + //! Factory method to create applications based on configuration + static std::shared_ptr make_app( + const CLIParser::custom_payload_pool_config& config, + const std::string& topic_name); +}; + +} // namespace custom_payload_pool +} // namespace examples +} // namespace fastdds +} // namespace eprosima + +#endif /* _FASTDDS_CUSTOM_PAYLOAD_POOL_APPLICATION_HPP_ */ diff --git a/examples/cpp/custom_payload_pool/CLIParser.hpp b/examples/cpp/custom_payload_pool/CLIParser.hpp new file mode 100644 index 0000000000..42c81d781e --- /dev/null +++ b/examples/cpp/custom_payload_pool/CLIParser.hpp @@ -0,0 +1,332 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +#include +#include +#include + +#include + +#ifndef _FASTDDS_CUSTOM_PAYLOAD_POOL_CLI_PARSER_HPP_ +#define _FASTDDS_CUSTOM_PAYLOAD_POOL_CLI_PARSER_HPP_ + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace custom_payload_pool { + +using dds::Log; + +class CLIParser +{ +public: + + CLIParser() = delete; + + //! Entity kind enumeration + enum class EntityKind : uint8_t + { + PUBLISHER, + SUBSCRIBER, + UNDEFINED + }; + + //! Subscriber configuration structure (shared for both publisher and subscriber applications) + struct subscriber_config + { + uint16_t samples = 0; + uint16_t domain = 0; + }; + + //! Publisher application configuration structure + struct publisher_config : public subscriber_config + { + uint16_t interval = 100; + }; + + //! Configuration structure for the application + struct custom_payload_pool_config + { + CLIParser::EntityKind entity = CLIParser::EntityKind::UNDEFINED; + publisher_config pub_config; + subscriber_config sub_config; + }; + + /** + * @brief Print usage help message and exit with the given return code + * + * @param return_code return code to exit with + * + * @warning This method finishes the execution of the program with the input return code + */ + static void print_help( + uint8_t return_code) + { + std::cout << "Usage: custom_payload_pool [options]" << std::endl; + std::cout << "" << std::endl; + std::cout << "Entities:" << std::endl; + std::cout << " publisher Run a publisher entity" << std::endl; + std::cout << " subscriber Run a subscriber entity" << std::endl; + std::cout << "" << std::endl; + std::cout << "Common options:" << std::endl; + std::cout << " -h, --help Print this help message" << std::endl; + std::cout << " -s , --samples Number of samples to send or receive" << std::endl; + std::cout << " [0 <= <= 65535]" << std::endl; + std::cout << " (Default: 0 [unlimited])" << std::endl; + std::cout << " -d , --domain Domain ID number [0 <= <= 232]" << std::endl; + std::cout << " (Default: 0)" << std::endl; + std::cout << "Publisher options:" << std::endl; + std::cout << " -i, --interval Time between samples in milliseconds " << std::endl; + std::cout << " (Default: 100)" << std::endl; + + std::exit(return_code); + } + + /** + * @brief Parse the command line options and return the custom_payload_pool_config object + * + * @param argc number of arguments + * @param argv array of arguments + * @return custom_payload_pool_config object with the parsed options + * + * @warning This method finishes the execution of the program if the input arguments are invalid + */ + static custom_payload_pool_config parse_cli_options( + int argc, + char* argv[]) + { + custom_payload_pool_config config; + + if (argc < 2) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "missing entity argument"); + print_help(EXIT_FAILURE); + } + + std::string first_argument = argv[1]; + + if (first_argument == "publisher" ) + { + config.entity = CLIParser::EntityKind::PUBLISHER; + } + else if (first_argument == "subscriber") + { + config.entity = CLIParser::EntityKind::SUBSCRIBER; + } + else if (first_argument == "-h" || first_argument == "--help") + { + print_help(EXIT_SUCCESS); + } + else + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "parsing entity argument " + first_argument); + print_help(EXIT_FAILURE); + } + + for (int i = 2; i < argc; ++i) + { + std::string arg = argv[i]; + if (arg == "-h" || arg == "--help") + { + print_help(EXIT_SUCCESS); + } + else if (arg == "-s" || arg == "--samples") + { + if (i + 1 < argc) + { + try + { + int input = std::stoi(argv[++i]); + if (input < std::numeric_limits::min() || + input > std::numeric_limits::max()) + { + throw std::out_of_range("sample argument out of range"); + } + else + { + if (config.entity == CLIParser::EntityKind::PUBLISHER) + { + config.pub_config.samples = static_cast(input); + } + else if (config.entity == CLIParser::EntityKind::SUBSCRIBER) + { + config.sub_config.samples = static_cast(input); + } + else + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "entity not specified for --sample argument"); + print_help(EXIT_FAILURE); + } + } + } + catch (const std::invalid_argument& e) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "invalid sample argument for " + arg + ": " + e.what()); + print_help(EXIT_FAILURE); + } + catch (const std::out_of_range& e) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "sample argument out of range for " + arg + ": " + e.what()); + print_help(EXIT_FAILURE); + } + } + else + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "missing argument for " + arg); + print_help(EXIT_FAILURE); + } + } + else if (arg == "-d" || arg == "--domain") + { + if (i + 1 < argc) + { + try + { + int input = std::stoi(argv[++i]); + if (input < 0 || input > 232) + { + throw std::out_of_range("domain argument out of range"); + } + else + { + if (config.entity == CLIParser::EntityKind::PUBLISHER) + { + config.pub_config.domain = static_cast(input); + } + else if (config.entity == CLIParser::EntityKind::SUBSCRIBER) + { + config.sub_config.domain = static_cast(input); + } + else + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "entity not specified for --domain argument"); + print_help(EXIT_FAILURE); + } + } + } + catch (const std::invalid_argument& e) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "invalid domain argument for " + arg + ": " + e.what()); + print_help(EXIT_FAILURE); + } + catch (const std::out_of_range& e) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "domain argument out of range for " + arg + ": " + e.what()); + print_help(EXIT_FAILURE); + } + } + else + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "missing argument for " + arg); + print_help(EXIT_FAILURE); + } + } + else if (arg == "-i" || arg == "--interval") + { + if (i + 1 < argc) + { + try + { + if (config.entity == CLIParser::EntityKind::PUBLISHER) + { + config.pub_config.interval = static_cast(std::stoi(argv[++i])); + } + else + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "interval can only be used with the publisher entity"); + print_help(EXIT_FAILURE); + } + } + catch (const std::invalid_argument& e) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "invalid interval argument for " + arg + ": " + e.what()); + print_help(EXIT_FAILURE); + } + catch (const std::out_of_range& e) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "interval argument out of range for " + arg + ": " + e.what()); + print_help(EXIT_FAILURE); + } + } + else + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "missing argument for " + arg); + print_help(EXIT_FAILURE); + } + } + else + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "unknown option " + arg); + print_help(EXIT_FAILURE); + } + } + + return config; + } + + /** + * @brief Parse the signal number into the signal name + * + * @param signum signal number + * @return std::string signal name + */ + static std::string parse_signal( + const int& signum) + { + switch (signum) + { + case SIGINT: + return "SIGINT"; + case SIGTERM: + return "SIGTERM"; +#ifndef _WIN32 + case SIGQUIT: + return "SIGQUIT"; + case SIGHUP: + return "SIGHUP"; +#endif // _WIN32 + default: + return "UNKNOWN SIGNAL"; + } + } + + /** + * @brief Parse the entity kind into std::string + * + * @param entity entity kind + * @return std::string entity kind + */ + static std::string parse_entity_kind( + const EntityKind& entity) + { + switch (entity) + { + case EntityKind::PUBLISHER: + return "Publisher"; + case EntityKind::SUBSCRIBER: + return "Subscriber"; + case EntityKind::UNDEFINED: + default: + return "Undefined entity"; + } + } + +}; + +} // namespace custom_payload_pool +} // namespace examples +} // namespace fastdds +} // namespace eprosima + +#endif // _FASTDDS_CUSTOM_PAYLOAD_POOL_CLI_PARSER_HPP_ diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CMakeLists.txt b/examples/cpp/custom_payload_pool/CMakeLists.txt similarity index 75% rename from examples/cpp/dds/CustomPayloadPoolExample/CMakeLists.txt rename to examples/cpp/custom_payload_pool/CMakeLists.txt index adecbdaeb2..5ea259d1c2 100644 --- a/examples/cpp/dds/CustomPayloadPoolExample/CMakeLists.txt +++ b/examples/cpp/custom_payload_pool/CMakeLists.txt @@ -14,7 +14,7 @@ cmake_minimum_required(VERSION 3.20) -project(CustomPayloadPoolExample VERSION 1 LANGUAGES CXX) +project(custom_payload_pool VERSION 1 LANGUAGES CXX) # Find requirements if(NOT fastcdr_FOUND) @@ -38,11 +38,11 @@ message(STATUS "Configuring custom payload pool example...") file(GLOB CUSTOM_PAYLOAD_POOL_DATA_EXAMPLE_SOURCES_CXX "*.cxx") file(GLOB CUSTOM_PAYLOAD_POOL_DATA_EXAMPLE_SOURCES_CPP "*.cpp") -add_executable(CustomPayloadPoolExample ${CUSTOM_PAYLOAD_POOL_DATA_EXAMPLE_SOURCES_CXX} ${CUSTOM_PAYLOAD_POOL_DATA_EXAMPLE_SOURCES_CPP}) -target_compile_definitions(CustomPayloadPoolExample PRIVATE +add_executable(custom_payload_pool ${CUSTOM_PAYLOAD_POOL_DATA_EXAMPLE_SOURCES_CXX} ${CUSTOM_PAYLOAD_POOL_DATA_EXAMPLE_SOURCES_CPP}) +target_compile_definitions(custom_payload_pool PRIVATE $<$>,$>:__DEBUG> $<$:__INTERNALDEBUG> # Internal debug activated. ) -target_link_libraries(CustomPayloadPoolExample fastdds fastcdr fastdds::optionparser) -install(TARGETS CustomPayloadPoolExample - RUNTIME DESTINATION examples/cpp/dds/CustomPayloadPoolExample/${BIN_INSTALL_DIR}) +target_link_libraries(custom_payload_pool fastdds fastcdr fastdds::optionparser) +install(TARGETS custom_payload_pool + RUNTIME DESTINATION examples/cpp/dds/custom_payload_pool/${BIN_INSTALL_DIR}) diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPool.hpp b/examples/cpp/custom_payload_pool/CustomPayloadPool.hpp similarity index 95% rename from examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPool.hpp rename to examples/cpp/custom_payload_pool/CustomPayloadPool.hpp index d0d02bcda0..0b762d9eb1 100644 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPool.hpp +++ b/examples/cpp/custom_payload_pool/CustomPayloadPool.hpp @@ -16,8 +16,8 @@ * @file CustomPayloadPool.hpp */ -#ifndef DDS_CUSTOM_PAYLOAD_POOL_DATA_HPP -#define DDS_CUSTOM_PAYLOAD_POOL_DATA_HPP +#ifndef _FASTDDS_CUSTOM_PAYLOAD_POOL_HPP_ +#define _FASTDDS_CUSTOM_PAYLOAD_POOL_HPP_ #include #include @@ -97,4 +97,4 @@ class CustomPayloadPool : public eprosima::fastrtps::rtps::IPayloadPool }; -#endif // DDS_CUSTOM_PAYLOAD_POOL_DATA_HPP +#endif // _FASTDDS_CUSTOM_PAYLOAD_POOL_HPP_ diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolData.hpp b/examples/cpp/custom_payload_pool/HelloWorld.hpp similarity index 70% rename from examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolData.hpp rename to examples/cpp/custom_payload_pool/HelloWorld.hpp index 19136a331f..971fea8d92 100644 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolData.hpp +++ b/examples/cpp/custom_payload_pool/HelloWorld.hpp @@ -13,14 +13,14 @@ // limitations under the License. /*! - * @file CustomPayloadPoolData.hpp + * @file HelloWorld.hpp * This header file contains the declaration of the described types in the IDL file. * * This file was generated by the tool fastddsgen. */ -#ifndef _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATA_HPP_ -#define _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATA_HPP_ +#ifndef _FAST_DDS_GENERATED_HELLOWORLD_HPP_ +#define _FAST_DDS_GENERATED_HELLOWORLD_HPP_ #include #include @@ -39,46 +39,46 @@ #if defined(_WIN32) #if defined(EPROSIMA_USER_DLL_EXPORT) -#if defined(CUSTOMPAYLOADPOOLDATA_SOURCE) -#define CUSTOMPAYLOADPOOLDATA_DllAPI __declspec( dllexport ) +#if defined(HELLOWORLD_SOURCE) +#define HELLOWORLD_DllAPI __declspec( dllexport ) #else -#define CUSTOMPAYLOADPOOLDATA_DllAPI __declspec( dllimport ) -#endif // CUSTOMPAYLOADPOOLDATA_SOURCE +#define HELLOWORLD_DllAPI __declspec( dllimport ) +#endif // HELLOWORLD_SOURCE #else -#define CUSTOMPAYLOADPOOLDATA_DllAPI +#define HELLOWORLD_DllAPI #endif // EPROSIMA_USER_DLL_EXPORT #else -#define CUSTOMPAYLOADPOOLDATA_DllAPI +#define HELLOWORLD_DllAPI #endif // _WIN32 /*! - * @brief This class represents the structure CustomPayloadPoolData defined by the user in the IDL file. - * @ingroup CustomPayloadPoolData + * @brief This class represents the structure HelloWorld defined by the user in the IDL file. + * @ingroup HelloWorld */ -class CustomPayloadPoolData +class HelloWorld { public: /*! * @brief Default constructor. */ - eProsima_user_DllExport CustomPayloadPoolData() + eProsima_user_DllExport HelloWorld() { } /*! * @brief Default destructor. */ - eProsima_user_DllExport ~CustomPayloadPoolData() + eProsima_user_DllExport ~HelloWorld() { } /*! * @brief Copy constructor. - * @param x Reference to the object CustomPayloadPoolData that will be copied. + * @param x Reference to the object HelloWorld that will be copied. */ - eProsima_user_DllExport CustomPayloadPoolData( - const CustomPayloadPoolData& x) + eProsima_user_DllExport HelloWorld( + const HelloWorld& x) { m_index = x.m_index; @@ -88,10 +88,10 @@ class CustomPayloadPoolData /*! * @brief Move constructor. - * @param x Reference to the object CustomPayloadPoolData that will be copied. + * @param x Reference to the object HelloWorld that will be copied. */ - eProsima_user_DllExport CustomPayloadPoolData( - CustomPayloadPoolData&& x) noexcept + eProsima_user_DllExport HelloWorld( + HelloWorld&& x) noexcept { m_index = x.m_index; m_message = std::move(x.m_message); @@ -99,10 +99,10 @@ class CustomPayloadPoolData /*! * @brief Copy assignment. - * @param x Reference to the object CustomPayloadPoolData that will be copied. + * @param x Reference to the object HelloWorld that will be copied. */ - eProsima_user_DllExport CustomPayloadPoolData& operator =( - const CustomPayloadPoolData& x) + eProsima_user_DllExport HelloWorld& operator =( + const HelloWorld& x) { m_index = x.m_index; @@ -114,10 +114,10 @@ class CustomPayloadPoolData /*! * @brief Move assignment. - * @param x Reference to the object CustomPayloadPoolData that will be copied. + * @param x Reference to the object HelloWorld that will be copied. */ - eProsima_user_DllExport CustomPayloadPoolData& operator =( - CustomPayloadPoolData&& x) noexcept + eProsima_user_DllExport HelloWorld& operator =( + HelloWorld&& x) noexcept { m_index = x.m_index; @@ -127,10 +127,10 @@ class CustomPayloadPoolData /*! * @brief Comparison operator. - * @param x CustomPayloadPoolData object to compare. + * @param x HelloWorld object to compare. */ eProsima_user_DllExport bool operator ==( - const CustomPayloadPoolData& x) const + const HelloWorld& x) const { return (m_index == x.m_index && m_message == x.m_message); @@ -138,10 +138,10 @@ class CustomPayloadPoolData /*! * @brief Comparison operator. - * @param x CustomPayloadPoolData object to compare. + * @param x HelloWorld object to compare. */ eProsima_user_DllExport bool operator !=( - const CustomPayloadPoolData& x) const + const HelloWorld& x) const { return !(*this == x); } @@ -222,6 +222,6 @@ class CustomPayloadPoolData }; -#endif // _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATA_HPP_ +#endif // _FAST_DDS_GENERATED_HELLOWORLD_HPP_ diff --git a/examples/cpp/custom_payload_pool/HelloWorld.idl b/examples/cpp/custom_payload_pool/HelloWorld.idl new file mode 100644 index 0000000000..192f8f9d48 --- /dev/null +++ b/examples/cpp/custom_payload_pool/HelloWorld.idl @@ -0,0 +1,6 @@ +@extensibility(APPENDABLE) +struct HelloWorld +{ + unsigned long index; + string message; +}; diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataCdrAux.hpp b/examples/cpp/custom_payload_pool/HelloWorldCdrAux.hpp similarity index 68% rename from examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataCdrAux.hpp rename to examples/cpp/custom_payload_pool/HelloWorldCdrAux.hpp index 926bf7ea3d..6feb8a9da1 100644 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataCdrAux.hpp +++ b/examples/cpp/custom_payload_pool/HelloWorldCdrAux.hpp @@ -13,19 +13,19 @@ // limitations under the License. /*! - * @file CustomPayloadPoolDataCdrAux.hpp + * @file HelloWorldCdrAux.hpp * This source file contains some definitions of CDR related functions. * * This file was generated by the tool fastddsgen. */ -#ifndef _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATACDRAUX_HPP_ -#define _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATACDRAUX_HPP_ +#ifndef _FAST_DDS_GENERATED_HELLOWORLDCDRAUX_HPP_ +#define _FAST_DDS_GENERATED_HELLOWORLDCDRAUX_HPP_ -#include "CustomPayloadPoolData.hpp" +#include "HelloWorld.hpp" -constexpr uint32_t CustomPayloadPoolData_max_cdr_typesize {268UL}; -constexpr uint32_t CustomPayloadPoolData_max_key_cdr_typesize {0UL}; +constexpr uint32_t HelloWorld_max_cdr_typesize {268UL}; +constexpr uint32_t HelloWorld_max_key_cdr_typesize {0UL}; namespace eprosima { @@ -36,11 +36,11 @@ class CdrSizeCalculator; eProsima_user_DllExport void serialize_key( eprosima::fastcdr::Cdr& scdr, - const CustomPayloadPoolData& data); + const HelloWorld& data); } // namespace fastcdr } // namespace eprosima -#endif // _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATACDRAUX_HPP_ +#endif // _FAST_DDS_GENERATED_HELLOWORLDCDRAUX_HPP_ diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataCdrAux.ipp b/examples/cpp/custom_payload_pool/HelloWorldCdrAux.ipp similarity index 89% rename from examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataCdrAux.ipp rename to examples/cpp/custom_payload_pool/HelloWorldCdrAux.ipp index 89f2aaad27..97df3fe9d9 100644 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataCdrAux.ipp +++ b/examples/cpp/custom_payload_pool/HelloWorldCdrAux.ipp @@ -13,16 +13,16 @@ // limitations under the License. /*! - * @file CustomPayloadPoolDataCdrAux.ipp + * @file HelloWorldCdrAux.ipp * This source file contains some declarations of CDR related functions. * * This file was generated by the tool fastddsgen. */ -#ifndef _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATACDRAUX_IPP_ -#define _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATACDRAUX_IPP_ +#ifndef _FAST_DDS_GENERATED_HELLOWORLDCDRAUX_IPP_ +#define _FAST_DDS_GENERATED_HELLOWORLDCDRAUX_IPP_ -#include "CustomPayloadPoolDataCdrAux.hpp" +#include "HelloWorldCdrAux.hpp" #include #include @@ -37,7 +37,7 @@ namespace fastcdr { template<> eProsima_user_DllExport size_t calculate_serialized_size( eprosima::fastcdr::CdrSizeCalculator& calculator, - const CustomPayloadPoolData& data, + const HelloWorld& data, size_t& current_alignment) { static_cast(data); @@ -65,7 +65,7 @@ eProsima_user_DllExport size_t calculate_serialized_size( template<> eProsima_user_DllExport void serialize( eprosima::fastcdr::Cdr& scdr, - const CustomPayloadPoolData& data) + const HelloWorld& data) { eprosima::fastcdr::Cdr::state current_state(scdr); scdr.begin_serialize_type(current_state, @@ -83,7 +83,7 @@ eProsima_user_DllExport void serialize( template<> eProsima_user_DllExport void deserialize( eprosima::fastcdr::Cdr& cdr, - CustomPayloadPoolData& data) + HelloWorld& data) { cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : @@ -111,7 +111,7 @@ eProsima_user_DllExport void deserialize( void serialize_key( eprosima::fastcdr::Cdr& scdr, - const CustomPayloadPoolData& data) + const HelloWorld& data) { static_cast(scdr); static_cast(data); @@ -122,5 +122,5 @@ void serialize_key( } // namespace fastcdr } // namespace eprosima -#endif // _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATACDRAUX_IPP_ +#endif // _FAST_DDS_GENERATED_HELLOWORLDCDRAUX_IPP_ diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPubSubTypes.cxx b/examples/cpp/custom_payload_pool/HelloWorldPubSubTypes.cxx similarity index 78% rename from examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPubSubTypes.cxx rename to examples/cpp/custom_payload_pool/HelloWorldPubSubTypes.cxx index 3133c1d0b6..db018e6978 100644 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPubSubTypes.cxx +++ b/examples/cpp/custom_payload_pool/HelloWorldPubSubTypes.cxx @@ -13,42 +13,42 @@ // limitations under the License. /*! - * @file CustomPayloadPoolDataPubSubTypes.cpp + * @file HelloWorldPubSubTypes.cpp * This header file contains the implementation of the serialization functions. * * This file was generated by the tool fastddsgen. */ -#include "CustomPayloadPoolDataPubSubTypes.h" +#include "HelloWorldPubSubTypes.h" #include #include -#include "CustomPayloadPoolDataCdrAux.hpp" -#include "CustomPayloadPoolDataTypeObjectSupport.hpp" +#include "HelloWorldCdrAux.hpp" +#include "HelloWorldTypeObjectSupport.hpp" using SerializedPayload_t = eprosima::fastrtps::rtps::SerializedPayload_t; using InstanceHandle_t = eprosima::fastrtps::rtps::InstanceHandle_t; using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t; -CustomPayloadPoolDataPubSubType::CustomPayloadPoolDataPubSubType() +HelloWorldPubSubType::HelloWorldPubSubType() { - setName("CustomPayloadPoolData"); + setName("HelloWorld"); uint32_t type_size = #if FASTCDR_VERSION_MAJOR == 1 - static_cast(CustomPayloadPoolData::getMaxCdrSerializedSize()); + static_cast(HelloWorld::getMaxCdrSerializedSize()); #else - CustomPayloadPoolData_max_cdr_typesize; + HelloWorld_max_cdr_typesize; #endif type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ m_typeSize = type_size + 4; /*encapsulation*/ m_isGetKeyDefined = false; - uint32_t keyLength = CustomPayloadPoolData_max_key_cdr_typesize > 16 ? CustomPayloadPoolData_max_key_cdr_typesize : 16; + uint32_t keyLength = HelloWorld_max_key_cdr_typesize > 16 ? HelloWorld_max_key_cdr_typesize : 16; m_keyBuffer = reinterpret_cast(malloc(keyLength)); memset(m_keyBuffer, 0, keyLength); } -CustomPayloadPoolDataPubSubType::~CustomPayloadPoolDataPubSubType() +HelloWorldPubSubType::~HelloWorldPubSubType() { if (m_keyBuffer != nullptr) { @@ -56,12 +56,12 @@ CustomPayloadPoolDataPubSubType::~CustomPayloadPoolDataPubSubType() } } -bool CustomPayloadPoolDataPubSubType::serialize( +bool HelloWorldPubSubType::serialize( void* data, SerializedPayload_t* payload, DataRepresentationId_t data_representation) { - CustomPayloadPoolData* p_type = static_cast(data); + HelloWorld* p_type = static_cast(data); // Object that manages the raw buffer. eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->max_size); @@ -98,14 +98,14 @@ bool CustomPayloadPoolDataPubSubType::serialize( return true; } -bool CustomPayloadPoolDataPubSubType::deserialize( +bool HelloWorldPubSubType::deserialize( SerializedPayload_t* payload, void* data) { try { // Convert DATA to pointer of your type - CustomPayloadPoolData* p_type = static_cast(data); + HelloWorld* p_type = static_cast(data); // Object that manages the raw buffer. eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->length); @@ -132,7 +132,7 @@ bool CustomPayloadPoolDataPubSubType::deserialize( return true; } -std::function CustomPayloadPoolDataPubSubType::getSerializedSizeProvider( +std::function HelloWorldPubSubType::getSerializedSizeProvider( void* data, DataRepresentationId_t data_representation) { @@ -140,7 +140,7 @@ std::function CustomPayloadPoolDataPubSubType::getSerializedSizeProv { #if FASTCDR_VERSION_MAJOR == 1 static_cast(data_representation); - return static_cast(type::getCdrSerializedSize(*static_cast(data))) + + return static_cast(type::getCdrSerializedSize(*static_cast(data))) + 4u /*encapsulation*/; #else try @@ -150,7 +150,7 @@ std::function CustomPayloadPoolDataPubSubType::getSerializedSizeProv eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); size_t current_alignment {0}; return static_cast(calculator.calculate_serialized_size( - *static_cast(data), current_alignment)) + + *static_cast(data), current_alignment)) + 4u /*encapsulation*/; } catch (eprosima::fastcdr::exception::Exception& /*exception*/) @@ -161,18 +161,18 @@ std::function CustomPayloadPoolDataPubSubType::getSerializedSizeProv }; } -void* CustomPayloadPoolDataPubSubType::createData() +void* HelloWorldPubSubType::createData() { - return reinterpret_cast(new CustomPayloadPoolData()); + return reinterpret_cast(new HelloWorld()); } -void CustomPayloadPoolDataPubSubType::deleteData( +void HelloWorldPubSubType::deleteData( void* data) { - delete(reinterpret_cast(data)); + delete(reinterpret_cast(data)); } -bool CustomPayloadPoolDataPubSubType::getKey( +bool HelloWorldPubSubType::getKey( void* data, InstanceHandle_t* handle, bool force_md5) @@ -182,11 +182,11 @@ bool CustomPayloadPoolDataPubSubType::getKey( return false; } - CustomPayloadPoolData* p_type = static_cast(data); + HelloWorld* p_type = static_cast(data); // Object that manages the raw buffer. eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(m_keyBuffer), - CustomPayloadPoolData_max_key_cdr_typesize); + HelloWorld_max_key_cdr_typesize); // Object that serializes the data. eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); @@ -195,7 +195,7 @@ bool CustomPayloadPoolDataPubSubType::getKey( #else eprosima::fastcdr::serialize_key(ser, *p_type); #endif // FASTCDR_VERSION_MAJOR == 1 - if (force_md5 || CustomPayloadPoolData_max_key_cdr_typesize > 16) + if (force_md5 || HelloWorld_max_key_cdr_typesize > 16) { m_md5.init(); #if FASTCDR_VERSION_MAJOR == 1 @@ -219,11 +219,11 @@ bool CustomPayloadPoolDataPubSubType::getKey( return true; } -void CustomPayloadPoolDataPubSubType::register_type_object_representation() const +void HelloWorldPubSubType::register_type_object_representation() const { - register_CustomPayloadPoolData_type_objects(); + register_HelloWorld_type_objects(); } // Include auxiliary functions like for serializing/deserializing. -#include "CustomPayloadPoolDataCdrAux.ipp" +#include "HelloWorldCdrAux.ipp" diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPubSubTypes.h b/examples/cpp/custom_payload_pool/HelloWorldPubSubTypes.h similarity index 81% rename from examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPubSubTypes.h rename to examples/cpp/custom_payload_pool/HelloWorldPubSubTypes.h index 92ce3732be..a9b4ac119e 100644 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPubSubTypes.h +++ b/examples/cpp/custom_payload_pool/HelloWorldPubSubTypes.h @@ -13,15 +13,15 @@ // limitations under the License. /*! - * @file CustomPayloadPoolDataPubSubTypes.h + * @file HelloWorldPubSubTypes.h * This header file contains the declaration of the serialization functions. * * This file was generated by the tool fastddsgen. */ -#ifndef _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATA_PUBSUBTYPES_H_ -#define _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATA_PUBSUBTYPES_H_ +#ifndef _FAST_DDS_GENERATED_HELLOWORLD_PUBSUBTYPES_H_ +#define _FAST_DDS_GENERATED_HELLOWORLD_PUBSUBTYPES_H_ #include #include @@ -29,28 +29,28 @@ #include #include -#include "CustomPayloadPoolData.hpp" +#include "HelloWorld.hpp" #if !defined(GEN_API_VER) || (GEN_API_VER != 2) #error \ - Generated CustomPayloadPoolData is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. + Generated HelloWorld is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. #endif // GEN_API_VER /*! - * @brief This class represents the TopicDataType of the type CustomPayloadPoolData defined by the user in the IDL file. - * @ingroup CustomPayloadPoolData + * @brief This class represents the TopicDataType of the type HelloWorld defined by the user in the IDL file. + * @ingroup HelloWorld */ -class CustomPayloadPoolDataPubSubType : public eprosima::fastdds::dds::TopicDataType +class HelloWorldPubSubType : public eprosima::fastdds::dds::TopicDataType { public: - typedef CustomPayloadPoolData type; + typedef HelloWorld type; - eProsima_user_DllExport CustomPayloadPoolDataPubSubType(); + eProsima_user_DllExport HelloWorldPubSubType(); - eProsima_user_DllExport ~CustomPayloadPoolDataPubSubType() override; + eProsima_user_DllExport ~HelloWorldPubSubType() override; eProsima_user_DllExport bool serialize( void* data, @@ -129,5 +129,5 @@ class CustomPayloadPoolDataPubSubType : public eprosima::fastdds::dds::TopicData }; -#endif // _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATA_PUBSUBTYPES_H_ +#endif // _FAST_DDS_GENERATED_HELLOWORLD_PUBSUBTYPES_H_ diff --git a/examples/cpp/custom_payload_pool/HelloWorldTypeObjectSupport.cxx b/examples/cpp/custom_payload_pool/HelloWorldTypeObjectSupport.cxx new file mode 100644 index 0000000000..fedf539c3f --- /dev/null +++ b/examples/cpp/custom_payload_pool/HelloWorldTypeObjectSupport.cxx @@ -0,0 +1,243 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +/*! + * @file HelloWorldTypeObjectSupport.cxx + * Source file containing the implementation to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen. + */ + +#include "HelloWorldTypeObjectSupport.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "HelloWorld.hpp" + + +using namespace eprosima::fastdds::dds::xtypes; + +void register_HelloWorld_type_objects() +{ + static std::once_flag once_flag; + std::call_once(once_flag, []() + { + TypeIdentifier type_id; + register_HelloWorld_type_identifier(type_id); + + }); +} + +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_HelloWorld_type_identifier( + TypeIdentifier& type_id) +{ + { + StructTypeFlag struct_flags_HelloWorld = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + ReturnCode_t return_code_HelloWorld; + TypeIdentifierPair type_ids_HelloWorld; + QualifiedTypeName type_name_HelloWorld = "HelloWorld"; + eprosima::fastcdr::optional type_ann_builtin_HelloWorld; + eprosima::fastcdr::optional ann_custom_HelloWorld; + AppliedAnnotationSeq tmp_ann_custom_HelloWorld; + eprosima::fastcdr::optional verbatim_HelloWorld; + if (!tmp_ann_custom_HelloWorld.empty()) + { + ann_custom_HelloWorld = tmp_ann_custom_HelloWorld; + } + + CompleteTypeDetail detail_HelloWorld = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_HelloWorld, ann_custom_HelloWorld, type_name_HelloWorld.to_string()); + CompleteStructHeader header_HelloWorld; + header_HelloWorld = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_HelloWorld); + CompleteStructMemberSeq member_seq_HelloWorld; + { + return_code_HelloWorld = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_uint32_t", type_ids_HelloWorld); + + if (return_code_HelloWorld != eprosima::fastdds::dds::RETCODE_OK) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "index Structure member TypeIdentifier unknown to TypeObjectRegistry."); + type_id = TypeIdentifier(); + return; + } + StructMemberFlag member_flags_index = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructKind::NOT_APPLIED, + false, false, false, false); + CommonStructMember common_index; + MemberId member_id_index = 0x00000000; + if (EK_COMPLETE == type_ids_HelloWorld.type_identifier1()._d() || TK_NONE == type_ids_HelloWorld.type_identifier2()._d() || + (TI_PLAIN_SEQUENCE_SMALL == type_ids_HelloWorld.type_identifier1()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().seq_sdefn().header().equiv_kind()) || + (TI_PLAIN_SEQUENCE_LARGE == type_ids_HelloWorld.type_identifier1()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().seq_ldefn().header().equiv_kind()) || + (TI_PLAIN_ARRAY_SMALL == type_ids_HelloWorld.type_identifier1()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().array_sdefn().header().equiv_kind()) || + (TI_PLAIN_ARRAY_LARGE == type_ids_HelloWorld.type_identifier1()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().array_ldefn().header().equiv_kind()) || + (TI_PLAIN_MAP_SMALL == type_ids_HelloWorld.type_identifier1()._d() && + (EK_COMPLETE == type_ids_HelloWorld.type_identifier1().map_sdefn().header().equiv_kind() || + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().map_sdefn().key_identifier()->_d())) || + (TI_PLAIN_MAP_LARGE == type_ids_HelloWorld.type_identifier1()._d() && + (EK_COMPLETE == type_ids_HelloWorld.type_identifier1().map_ldefn().header().equiv_kind() || + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().map_ldefn().key_identifier()->_d()))) + { + common_index = TypeObjectUtils::build_common_struct_member(member_id_index, member_flags_index, type_ids_HelloWorld.type_identifier1()); + } + else if (EK_COMPLETE == type_ids_HelloWorld.type_identifier2()._d() || + (TI_PLAIN_SEQUENCE_SMALL == type_ids_HelloWorld.type_identifier2()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().seq_sdefn().header().equiv_kind()) || + (TI_PLAIN_SEQUENCE_LARGE == type_ids_HelloWorld.type_identifier2()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().seq_ldefn().header().equiv_kind()) || + (TI_PLAIN_ARRAY_SMALL == type_ids_HelloWorld.type_identifier2()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().array_sdefn().header().equiv_kind()) || + (TI_PLAIN_ARRAY_LARGE == type_ids_HelloWorld.type_identifier2()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().array_ldefn().header().equiv_kind()) || + (TI_PLAIN_MAP_SMALL == type_ids_HelloWorld.type_identifier2()._d() && + (EK_COMPLETE == type_ids_HelloWorld.type_identifier2().map_sdefn().header().equiv_kind() || + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().map_sdefn().key_identifier()->_d())) || + (TI_PLAIN_MAP_LARGE == type_ids_HelloWorld.type_identifier2()._d() && + (EK_COMPLETE == type_ids_HelloWorld.type_identifier2().map_ldefn().header().equiv_kind() || + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().map_ldefn().key_identifier()->_d()))) + { + common_index = TypeObjectUtils::build_common_struct_member(member_id_index, member_flags_index, type_ids_HelloWorld.type_identifier2()); + } + else + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "Structure index member TypeIdentifier inconsistent."); + type_id = TypeIdentifier(); + return; + } + MemberName name_index = "index"; + eprosima::fastcdr::optional member_ann_builtin_index; + ann_custom_HelloWorld.reset(); + CompleteMemberDetail detail_index = TypeObjectUtils::build_complete_member_detail(name_index, member_ann_builtin_index, ann_custom_HelloWorld); + CompleteStructMember member_index = TypeObjectUtils::build_complete_struct_member(common_index, detail_index); + TypeObjectUtils::add_complete_struct_member(member_seq_HelloWorld, member_index); + } + { + return_code_HelloWorld = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_HelloWorld); + + if (return_code_HelloWorld != eprosima::fastdds::dds::RETCODE_OK) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded")) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + return_code_HelloWorld = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_HelloWorld); + if (return_code_HelloWorld != eprosima::fastdds::dds::RETCODE_OK) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded: Given String TypeIdentifier unknown to TypeObjectRegistry."); + type_id = TypeIdentifier(); + return; + } + } + StructMemberFlag member_flags_message = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructKind::NOT_APPLIED, + false, false, false, false); + CommonStructMember common_message; + MemberId member_id_message = 0x00000001; + if (EK_COMPLETE == type_ids_HelloWorld.type_identifier1()._d() || TK_NONE == type_ids_HelloWorld.type_identifier2()._d() || + (TI_PLAIN_SEQUENCE_SMALL == type_ids_HelloWorld.type_identifier1()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().seq_sdefn().header().equiv_kind()) || + (TI_PLAIN_SEQUENCE_LARGE == type_ids_HelloWorld.type_identifier1()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().seq_ldefn().header().equiv_kind()) || + (TI_PLAIN_ARRAY_SMALL == type_ids_HelloWorld.type_identifier1()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().array_sdefn().header().equiv_kind()) || + (TI_PLAIN_ARRAY_LARGE == type_ids_HelloWorld.type_identifier1()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().array_ldefn().header().equiv_kind()) || + (TI_PLAIN_MAP_SMALL == type_ids_HelloWorld.type_identifier1()._d() && + (EK_COMPLETE == type_ids_HelloWorld.type_identifier1().map_sdefn().header().equiv_kind() || + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().map_sdefn().key_identifier()->_d())) || + (TI_PLAIN_MAP_LARGE == type_ids_HelloWorld.type_identifier1()._d() && + (EK_COMPLETE == type_ids_HelloWorld.type_identifier1().map_ldefn().header().equiv_kind() || + EK_COMPLETE == type_ids_HelloWorld.type_identifier1().map_ldefn().key_identifier()->_d()))) + { + common_message = TypeObjectUtils::build_common_struct_member(member_id_message, member_flags_message, type_ids_HelloWorld.type_identifier1()); + } + else if (EK_COMPLETE == type_ids_HelloWorld.type_identifier2()._d() || + (TI_PLAIN_SEQUENCE_SMALL == type_ids_HelloWorld.type_identifier2()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().seq_sdefn().header().equiv_kind()) || + (TI_PLAIN_SEQUENCE_LARGE == type_ids_HelloWorld.type_identifier2()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().seq_ldefn().header().equiv_kind()) || + (TI_PLAIN_ARRAY_SMALL == type_ids_HelloWorld.type_identifier2()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().array_sdefn().header().equiv_kind()) || + (TI_PLAIN_ARRAY_LARGE == type_ids_HelloWorld.type_identifier2()._d() && + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().array_ldefn().header().equiv_kind()) || + (TI_PLAIN_MAP_SMALL == type_ids_HelloWorld.type_identifier2()._d() && + (EK_COMPLETE == type_ids_HelloWorld.type_identifier2().map_sdefn().header().equiv_kind() || + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().map_sdefn().key_identifier()->_d())) || + (TI_PLAIN_MAP_LARGE == type_ids_HelloWorld.type_identifier2()._d() && + (EK_COMPLETE == type_ids_HelloWorld.type_identifier2().map_ldefn().header().equiv_kind() || + EK_COMPLETE == type_ids_HelloWorld.type_identifier2().map_ldefn().key_identifier()->_d()))) + { + common_message = TypeObjectUtils::build_common_struct_member(member_id_message, member_flags_message, type_ids_HelloWorld.type_identifier2()); + } + else + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "Structure message member TypeIdentifier inconsistent."); + type_id = TypeIdentifier(); + return; + } + MemberName name_message = "message"; + eprosima::fastcdr::optional member_ann_builtin_message; + ann_custom_HelloWorld.reset(); + CompleteMemberDetail detail_message = TypeObjectUtils::build_complete_member_detail(name_message, member_ann_builtin_message, ann_custom_HelloWorld); + CompleteStructMember member_message = TypeObjectUtils::build_complete_struct_member(common_message, detail_message); + TypeObjectUtils::add_complete_struct_member(member_seq_HelloWorld, member_message); + } + CompleteStructType struct_type_HelloWorld = TypeObjectUtils::build_complete_struct_type(struct_flags_HelloWorld, header_HelloWorld, member_seq_HelloWorld); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_HelloWorld, type_name_HelloWorld.to_string(), type_id)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "HelloWorld already registered in TypeObjectRegistry for a different type."); + } + return_code_HelloWorld = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "HelloWorld", type_ids_HelloWorld); + if (return_code_HelloWorld != eprosima::fastdds::dds::RETCODE_OK) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "HelloWorld: Given Struct TypeIdentifier unknown to TypeObjectRegistry."); + type_id = TypeIdentifier(); + return; + } + } +} + diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataTypeObjectSupport.hpp b/examples/cpp/custom_payload_pool/HelloWorldTypeObjectSupport.hpp similarity index 79% rename from examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataTypeObjectSupport.hpp rename to examples/cpp/custom_payload_pool/HelloWorldTypeObjectSupport.hpp index 2af1ef2fd3..4d5de07cbd 100644 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataTypeObjectSupport.hpp +++ b/examples/cpp/custom_payload_pool/HelloWorldTypeObjectSupport.hpp @@ -13,14 +13,14 @@ // limitations under the License. /*! - * @file CustomPayloadPoolDataTypeObjectSupport.hpp + * @file HelloWorldTypeObjectSupport.hpp * Header file containing the API required to register the TypeObject representation of the described types in the IDL file * * This file was generated by the tool fastddsgen. */ -#ifndef _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATA_TYPE_OBJECT_SUPPORT_HPP_ -#define _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATA_TYPE_OBJECT_SUPPORT_HPP_ +#ifndef _FAST_DDS_GENERATED_HELLOWORLD_TYPE_OBJECT_SUPPORT_HPP_ +#define _FAST_DDS_GENERATED_HELLOWORLD_TYPE_OBJECT_SUPPORT_HPP_ #include @@ -38,12 +38,12 @@ /** * @brief Register every TypeObject representation defined in the IDL file in Fast DDS TypeObjectRegistry. */ -eProsima_user_DllExport void register_CustomPayloadPoolData_type_objects(); +eProsima_user_DllExport void register_HelloWorld_type_objects(); #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC /** - * @brief Register CustomPayloadPoolData related TypeIdentifier. + * @brief Register HelloWorld related TypeIdentifier. * Fully-descriptive TypeIdentifiers are directly registered. * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is * indirectly registered as well. @@ -52,10 +52,10 @@ eProsima_user_DllExport void register_CustomPayloadPoolData_type_objects(); * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. * Invalid TypeIdentifier is returned in case of error. */ -eProsima_user_DllExport void register_CustomPayloadPoolData_type_identifier( +eProsima_user_DllExport void register_HelloWorld_type_identifier( eprosima::fastdds::dds::xtypes::TypeIdentifier& type_id); #endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC -#endif // _FAST_DDS_GENERATED_CUSTOMPAYLOADPOOLDATA_TYPE_OBJECT_SUPPORT_HPP_ +#endif // _FAST_DDS_GENERATED_HELLOWORLD_TYPE_OBJECT_SUPPORT_HPP_ diff --git a/examples/cpp/custom_payload_pool/PublisherApp.cpp b/examples/cpp/custom_payload_pool/PublisherApp.cpp new file mode 100644 index 0000000000..3f80c9ae66 --- /dev/null +++ b/examples/cpp/custom_payload_pool/PublisherApp.cpp @@ -0,0 +1,180 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +/** + * @file PublisherApp.cpp + * + */ + +#include "PublisherApp.hpp" + +#include +#include + +#include +#include +#include +#include +#include + +using namespace eprosima::fastdds::dds; +using namespace eprosima::fastdds::rtps; + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace custom_payload_pool { + +PublisherApp::PublisherApp( + const CLIParser::publisher_config& config, + const std::string& topic_name) + : participant_(nullptr) + , publisher_(nullptr) + , topic_(nullptr) + , writer_(nullptr) + , type_(new HelloWorldPubSubType()) + , matched_(0) + , samples_(config.samples) + , stop_(false) + , period_ms_(config.interval) +{ + // Set up the data type with initial values + hello_.index(0); + hello_.message("HelloWorld"); + + payload_pool_ = std::make_shared(); + + // Create the participant + DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT; + auto factory = DomainParticipantFactory::get_instance(); + participant_ = factory->create_participant(config.domain, pqos); + if (participant_ == nullptr) + { + throw std::runtime_error("Participant initialization failed"); + } + + // Register the type + type_.register_type(participant_); + + // Create the publisher + PublisherQos pub_qos = PUBLISHER_QOS_DEFAULT; + participant_->get_default_publisher_qos(pub_qos); + publisher_ = participant_->create_publisher(pub_qos, nullptr, StatusMask::none()); + if (publisher_ == nullptr) + { + throw std::runtime_error("Publisher initialization failed"); + } + + // Create the topic + TopicQos topic_qos = TOPIC_QOS_DEFAULT; + participant_->get_default_topic_qos(topic_qos); + topic_ = participant_->create_topic(topic_name, type_.get_type_name(), topic_qos); + if (topic_ == nullptr) + { + throw std::runtime_error("Topic initialization failed"); + } + + // Create the data writer + DataWriterQos writer_qos = DATAWRITER_QOS_DEFAULT; + publisher_->get_default_datawriter_qos(writer_qos); + writer_ = publisher_->create_datawriter(topic_, writer_qos, this, StatusMask::all(), payload_pool_); + if (writer_ == nullptr) + { + throw std::runtime_error("DataWriter initialization failed"); + } +} + +PublisherApp::~PublisherApp() +{ + if (participant_ != nullptr) + { + participant_->delete_contained_entities(); + DomainParticipantFactory::get_instance()->delete_participant(participant_); + } +} + +void PublisherApp::on_publication_matched( + DataWriter*, + const PublicationMatchedStatus& info) +{ + if (info.current_count_change == 1) + { + matched_ = static_cast(info.current_count); + std::cout << "Publisher matched." << std::endl; + cv_.notify_one(); + } + else if (info.current_count_change == -1) + { + matched_ = static_cast(info.current_count); + std::cout << "Publisher unmatched." << std::endl; + } + else + { + std::cout << info.current_count_change + << " is not a valid value for PublicationMatchedStatus current count change" << std::endl; + } +} + +void PublisherApp::run() +{ + while (!is_stopped() && ((samples_ == 0) || (hello_.index() < samples_))) + { + if (publish()) + { + std::cout << "Message: '" << hello_.message() << "' with index: '" << hello_.index() + << "' SENT" << std::endl; + } + // Wait for period or stop event + std::unique_lock period_lock(mutex_); + cv_.wait_for(period_lock, std::chrono::milliseconds(period_ms_), [&]() + { + return is_stopped(); + }); + } +} + +bool PublisherApp::publish() +{ + bool ret = false; + // Wait for the data endpoints discovery + std::unique_lock matched_lock(mutex_); + cv_.wait(matched_lock, [&]() + { + // at least one has been discovered + return ((matched_ > 0) || is_stopped()); + }); + + if (!is_stopped()) + { + hello_.index(hello_.index() + 1); + ret = writer_->write(&hello_); + } + return ret; +} + +bool PublisherApp::is_stopped() +{ + return stop_.load(); +} + +void PublisherApp::stop() +{ + stop_.store(true); + cv_.notify_one(); +} + +} // namespace custom_payload_pool +} // namespace examples +} // namespace fastdds +} // namespace eprosima diff --git a/examples/cpp/custom_payload_pool/PublisherApp.hpp b/examples/cpp/custom_payload_pool/PublisherApp.hpp new file mode 100644 index 0000000000..f65898d348 --- /dev/null +++ b/examples/cpp/custom_payload_pool/PublisherApp.hpp @@ -0,0 +1,106 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +/** + * @file PublisherApp.hpp + * + */ + +#ifndef _FASTDDS_CUSTOM_PAYLOAD_POOL_PUBLISHER_HPP_ +#define _FASTDDS_CUSTOM_PAYLOAD_POOL_PUBLISHER_HPP_ + +#include +#include + +#include +#include +#include + +#include "Application.hpp" +#include "CLIParser.hpp" +#include "CustomPayloadPool.hpp" +#include "HelloWorldPubSubTypes.h" + +using namespace eprosima::fastdds::dds; + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace custom_payload_pool { + +class PublisherApp : public Application, public DataWriterListener +{ +public: + + PublisherApp( + const CLIParser::publisher_config& config, + const std::string& topic_name); + + virtual ~PublisherApp(); + + //! Publisher matched method + void on_publication_matched( + DataWriter* writer, + const PublicationMatchedStatus& info) override; + + //! Run for number samples, publish every sleep seconds + void run() override; + + //! Stop publisher + void stop() override; + +private: + + //! Publish a sample + bool publish(); + + //! Return the current state of execution + bool is_stopped(); + + //! Unblock the thread so publication of samples begins/resumes + static void awake(); + + HelloWorld hello_; + + std::shared_ptr payload_pool_; + + DomainParticipant* participant_; + + Publisher* publisher_; + + Topic* topic_; + + DataWriter* writer_; + + TypeSupport type_; + + int16_t matched_; + + uint16_t samples_; + + std::mutex mutex_; + + std::condition_variable cv_; + + std::atomic stop_; + + uint16_t period_ms_ = 100; // in ms +}; + +} // namespace custom_payload_pool +} // namespace examples +} // namespace fastdds +} // namespace eprosima + +#endif /* _FASTDDS_CUSTOM_PAYLOAD_POOL_PUBLISHER_H_ */ diff --git a/examples/cpp/custom_payload_pool/README.md b/examples/cpp/custom_payload_pool/README.md new file mode 100644 index 0000000000..a6c5a558fc --- /dev/null +++ b/examples/cpp/custom_payload_pool/README.md @@ -0,0 +1,89 @@ +# Custom Payload Pool example + +The *eProsima Fast DDS Custom payload pool* example is a simple application intended to demonstrate how to set the endpoints' payload pool from the DDS layer. + +This example is part of the suite of examples designed by eProsima that aims to illustrate the features and possible configurations of DDS deployments through *eProsima Fast DDS*. + +In this example, a custom payload pool is implemented instead of the default one, and passed to the endpoints in the publisher and subscriber implementations. + +* [Description of the example](#description-of-the-example) +* [Run the example](#run-the-example) + +## Description of the example +A Payload is the data the user wants to transmit between a DataWriter and a DataReader. In order to manage the lifecycle of the Payloads, DataReaders and DataWriters use a pool object, an implementation of the `IPayloadPool` interface. The user can define different pool implementations, to obtain different kind of optimizations to manage the Payloads. A custom Payload pool can be given to `create_datawriter()` and `create_datareader()` functions, and DataWriters and DataReaders will use the provided pool when a new change in their history is requested or released. The example provides a simple payload pool that reserves and frees memory each time. + +## Run the example + +To launch this example, two different terminals are required. +One of them will run the publisher example application, and the other will run the subscriber application. + +### Custom payload pool publisher + +* Ubuntu ( / MacOS ) + + ```shell + user@machine:example_path$ ./custom_payload_pool publisher + Publisher running. Please press Ctrl+C to stop the Publisher at any time. + ``` + +* Windows + + ```powershell + example_path> custom_payload_pool.exe publisher + Publisher running. Please press Ctrl+C to stop the Publisher at any time. + ``` + +### Custom payload pool subscriber + +* Ubuntu ( / MacOS ) + + ```shell + user@machine:example_path$ ./custom_payload_pool subscriber + Subscriber running. Please press Ctrl+C to stop the Subscriber at any time. + ``` + +* Windows + + ```powershell + example_path> custom_payload_pool.exe subscriber + Subscriber running. Please press Ctrl+C to stop the Subscriber at any time. + ``` + +All the example available flags can be queried running the executable with the ``-h`` or ``--help`` flag. + +### Expected output + +Regardless of which application is run first, since the publisher will not start sending data until a subscriber is discovered, the expected output both for publishers and subscribers is a first displayed message acknowledging the match, followed by the amount of samples sent or received until Ctrl+C is pressed. + +### Custom payload pool publisher + +```shell +Publisher running. Please press Ctrl+C to stop the Publisher at any time. +Publisher matched. +Message: 'Hello world' with index: '1' SENT +Message: 'Hello world' with index: '2' SENT +Message: 'Hello world' with index: '3' SENT +... +``` + +### Custom payload pool subscriber + +```shell +Subscriber running. Please press Ctrl+C to stop the Subscriber at any time. +Subscriber matched. +Message: 'Hello world' with index: '1' RECEIVED +Message: 'Hello world' with index: '2' RECEIVED +Message: 'Hello world' with index: '3' RECEIVED +... +``` + +When Ctrl+C is pressed to stop one of the applications, the other one will show the unmatched status, displaying an informative message, and it will stop sending / receiving messages. +The following is a possible output of the publisher application when stopping the subscriber app. + +```shell +... +Message: 'Hello world' with index: '9' SENT +Message: 'Hello world' with index: '10' SENT +Message: 'Hello world' with index: '11' SENT +Publisher unmatched. +``` diff --git a/examples/cpp/custom_payload_pool/SubscriberApp.cpp b/examples/cpp/custom_payload_pool/SubscriberApp.cpp new file mode 100644 index 0000000000..9bd398cffc --- /dev/null +++ b/examples/cpp/custom_payload_pool/SubscriberApp.cpp @@ -0,0 +1,164 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +/** + * @file SubscriberApp.cpp + * + */ + +#include "SubscriberApp.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace eprosima::fastdds::dds; +namespace eprosima { +namespace fastdds { +namespace examples { +namespace custom_payload_pool { + +SubscriberApp::SubscriberApp( + const CLIParser::subscriber_config& config, + const std::string& topic_name) + : participant_(nullptr) + , subscriber_(nullptr) + , topic_(nullptr) + , reader_(nullptr) + , type_(new HelloWorldPubSubType()) + , samples_(config.samples) + , received_samples_(0) + , stop_(false) +{ + payload_pool_ = std::make_shared(); + + // Create the participant + DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT; + auto factory = DomainParticipantFactory::get_instance(); + participant_ = factory->create_participant(config.domain, pqos); + if (participant_ == nullptr) + { + throw std::runtime_error("Participant initialization failed"); + } + + // Register the type + type_.register_type(participant_); + + // Create the subscriber + SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT; + participant_->get_default_subscriber_qos(sub_qos); + subscriber_ = participant_->create_subscriber(sub_qos, nullptr, StatusMask::none()); + if (subscriber_ == nullptr) + { + throw std::runtime_error("Subscriber initialization failed"); + } + + // Create the topic + TopicQos topic_qos = TOPIC_QOS_DEFAULT; + participant_->get_default_topic_qos(topic_qos); + topic_ = participant_->create_topic(topic_name, type_.get_type_name(), topic_qos); + if (topic_ == nullptr) + { + throw std::runtime_error("Topic initialization failed"); + } + + // Create the reader + DataReaderQos reader_qos = DATAREADER_QOS_DEFAULT; + subscriber_->get_default_datareader_qos(reader_qos); + reader_ = subscriber_->create_datareader(topic_, reader_qos, this, StatusMask::all(), payload_pool_); + if (reader_ == nullptr) + { + throw std::runtime_error("DataReader initialization failed"); + } +} + +SubscriberApp::~SubscriberApp() +{ + if (participant_ != nullptr) + { + participant_->delete_contained_entities(); + DomainParticipantFactory::get_instance()->delete_participant(participant_); + } +} + +void SubscriberApp::on_subscription_matched( + DataReader*, + const SubscriptionMatchedStatus& info) +{ + if (info.current_count_change == 1) + { + std::cout << "Subscriber matched." << std::endl; + } + else if (info.current_count_change == -1) + { + std::cout << "Subscriber unmatched." << std::endl; + } + else + { + std::cout << info.current_count_change + << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; + } +} + +void SubscriberApp::on_data_available( + DataReader* reader) +{ + SampleInfo info; + while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&hello_, &info))) + { + if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) + { + received_samples_++; + // Print Hello world message data + std::cout << "Message: '" << hello_.message() << "' with index: '" << hello_.index() + << "' RECEIVED" << std::endl; + if (samples_ > 0 && (received_samples_ >= samples_)) + { + stop(); + } + } + } +} + +void SubscriberApp::run() +{ + std::unique_lock lck(terminate_cv_mtx_); + terminate_cv_.wait(lck, [&] + { + return is_stopped(); + }); +} + +bool SubscriberApp::is_stopped() +{ + return stop_.load(); +} + +void SubscriberApp::stop() +{ + stop_.store(true); + terminate_cv_.notify_all(); +} + +} // namespace custom_payload_pool +} // namespace examples +} // namespace fastdds +} // namespace eprosima diff --git a/examples/cpp/custom_payload_pool/SubscriberApp.hpp b/examples/cpp/custom_payload_pool/SubscriberApp.hpp new file mode 100644 index 0000000000..345c4c0582 --- /dev/null +++ b/examples/cpp/custom_payload_pool/SubscriberApp.hpp @@ -0,0 +1,104 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +/** + * @file SubscriberApp.hpp + * + */ + +#ifndef _FASTDDS_CUSTOM_PAYLOAD_POOL_SUBSCRIBER_HPP_ +#define _FASTDDS_CUSTOM_PAYLOAD_POOL_SUBSCRIBER_HPP_ + +#include +#include + +#include +#include +#include +#include + +#include "Application.hpp" +#include "CLIParser.hpp" +#include "CustomPayloadPool.hpp" +#include "HelloWorldPubSubTypes.h" + +using namespace eprosima::fastdds::dds; +namespace eprosima { +namespace fastdds { +namespace examples { +namespace custom_payload_pool { +class SubscriberApp : public Application, public DataReaderListener +{ +public: + + SubscriberApp( + const CLIParser::subscriber_config& config, + const std::string& topic_name); + + virtual ~SubscriberApp(); + + //! Subscription callback + void on_data_available( + DataReader* reader) override; + + //! Subscriber matched method + void on_subscription_matched( + DataReader* reader, + const SubscriptionMatchedStatus& info) override; + + //!Run the subscriber until all samples have been received. + void run() override; + + //! Trigger the end of execution + void stop() override; + +private: + + //! Return the current state of execution + bool is_stopped(); + + HelloWorld hello_; + + std::shared_ptr payload_pool_; + + DomainParticipant* participant_; + + Subscriber* subscriber_; + + Topic* topic_; + + DataReader* reader_; + + TypeSupport type_; + + uint16_t samples_; + + uint16_t received_samples_; + + //! Member used for control flow purposes + std::atomic stop_; + + //! Protects terminate condition variable + mutable std::mutex terminate_cv_mtx_; + + //! Waits during execution until SIGINT or max_messages_ samples are received + std::condition_variable terminate_cv_; +}; + +} // namespace custom_payload_pool +} // namespace examples +} // namespace fastdds +} // namespace eprosima + +#endif /* _FASTDDS_CUSTOM_PAYLOAD_POOL_SUBSCRIBER_HPP_ */ diff --git a/examples/cpp/custom_payload_pool/main.cpp b/examples/cpp/custom_payload_pool/main.cpp new file mode 100644 index 0000000000..9a56d7e999 --- /dev/null +++ b/examples/cpp/custom_payload_pool/main.cpp @@ -0,0 +1,108 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +/** + * @file main.cpp + * + */ + +#include +#include +#include + +#include +#include + +#include "Application.hpp" +#include "CLIParser.hpp" + +using eprosima::fastdds::dds::Log; +using namespace eprosima::fastdds::examples::custom_payload_pool; + +std::function stop_app_handler; +void signal_handler( + int signum) +{ + stop_app_handler(signum); +} + +int main( + int argc, + char** argv) +{ + + auto ret = EXIT_SUCCESS; + const std::string topic_name = "hello_world_topic"; + CLIParser::custom_payload_pool_config config = CLIParser::parse_cli_options(argc, argv); + uint16_t samples = 0; + switch (config.entity) + { + case CLIParser::EntityKind::PUBLISHER: + samples = config.pub_config.samples; + break; + case CLIParser::EntityKind::SUBSCRIBER: + samples = config.sub_config.samples; + break; + default: + break; + } + + std::string app_name = CLIParser::parse_entity_kind(config.entity); + std::shared_ptr app; + + try + { + app = Application::make_app(config, topic_name); + } + catch (const std::runtime_error& e) + { + EPROSIMA_LOG_ERROR(app_name, e.what()); + ret = EXIT_FAILURE; + } + + if (EXIT_FAILURE != ret) + { + std::thread thread(&Application::run, app); + + if (samples == 0) + { + std::cout << app_name << " running. Please press Ctrl+C to stop the " + << app_name << " at any time." << std::endl; + } + else + { + std::cout << app_name << " running for " << samples << " samples. Please press Ctrl+C to stop the " + << app_name << " at any time." << std::endl; + } + + stop_app_handler = [&](int signum) + { + std::cout << "\n" << CLIParser::parse_signal(signum) << " received, stopping " << app_name + << " execution." << std::endl; + app->stop(); + }; + + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + #ifndef _WIN32 + signal(SIGQUIT, signal_handler); + signal(SIGHUP, signal_handler); + #endif // _WIN32 + + thread.join(); + } + + Log::Reset(); + return ret; +} diff --git a/examples/cpp/dds/CMakeLists.txt b/examples/cpp/dds/CMakeLists.txt index ebdcf50e78..f0dc65eec9 100644 --- a/examples/cpp/dds/CMakeLists.txt +++ b/examples/cpp/dds/CMakeLists.txt @@ -13,7 +13,6 @@ # limitations under the License. add_subdirectory(ContentFilteredTopicExample) -add_subdirectory(CustomPayloadPoolExample) add_subdirectory(DiscoveryServerExample) add_subdirectory(DynamicHelloWorldExample) add_subdirectory(FlowControlExample) diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolData.idl b/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolData.idl deleted file mode 100644 index f135778941..0000000000 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolData.idl +++ /dev/null @@ -1,5 +0,0 @@ -struct CustomPayloadPoolData -{ - unsigned long index; - string message; -}; diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPublisher.cpp b/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPublisher.cpp deleted file mode 100644 index 4fa276efbf..0000000000 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPublisher.cpp +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// 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. - -/** - * @file CustomPayloadPoolDataPublisher.cpp - * - */ - -#include "CustomPayloadPoolDataPublisher.h" - -#include -#include - -#include -#include -#include -#include -#include - -using namespace eprosima::fastdds::dds; -using namespace eprosima::fastdds::rtps; - -std::atomic CustomPayloadPoolDataPublisher::stop_(false); -std::mutex CustomPayloadPoolDataPublisher::wait_matched_cv_mtx_; -std::condition_variable CustomPayloadPoolDataPublisher::wait_matched_cv_; - -CustomPayloadPoolDataPublisher::CustomPayloadPoolDataPublisher( - std::shared_ptr payload_pool) - : payload_pool_(payload_pool) - , participant_(nullptr) - , publisher_(nullptr) - , topic_(nullptr) - , writer_(nullptr) - , type_(new CustomPayloadPoolDataPubSubType()) - , matched_(0) - , has_stopped_for_unexpected_error_(false) -{ -} - -bool CustomPayloadPoolDataPublisher::is_stopped() -{ - return stop_; -} - -void CustomPayloadPoolDataPublisher::stop() -{ - stop_ = true; - awake(); -} - -bool CustomPayloadPoolDataPublisher::init() -{ - hello_.index(0); - hello_.message("CustomPayloadPool"); - DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT; - pqos.name("CustomPayloadPoolDataPublisher"); - auto factory = DomainParticipantFactory::get_instance(); - - participant_ = factory->create_participant(0, pqos); - - if (participant_ == nullptr) - { - return false; - } - - /* Register the type */ - type_.register_type(participant_); - - /* Create the publisher */ - publisher_ = participant_->create_publisher( - PUBLISHER_QOS_DEFAULT, - nullptr); - - if (publisher_ == nullptr) - { - return false; - } - - /* Create the topic */ - topic_ = participant_->create_topic( - "CustomPayloadPoolTopic", - type_.get_type_name(), - TOPIC_QOS_DEFAULT); - - if (topic_ == nullptr) - { - return false; - } - - /* Create the writer */ - writer_ = publisher_->create_datawriter( - topic_, - DATAWRITER_QOS_DEFAULT, - this, - StatusMask::all(), - payload_pool_); - - if (writer_ == nullptr) - { - return false; - } - - // Register SIGINT signal handler to stop thread execution - signal(SIGINT, [](int /*signum*/) - { - std::cout << "SIGINT received, stopping Publisher execution." << std::endl; - CustomPayloadPoolDataPublisher::stop(); - }); - - return true; -} - -CustomPayloadPoolDataPublisher::~CustomPayloadPoolDataPublisher() -{ - if (participant_ != nullptr) - { - participant_->delete_contained_entities(); - DomainParticipantFactory::get_instance()->delete_participant(participant_); - } -} - -void CustomPayloadPoolDataPublisher::on_publication_matched( - eprosima::fastdds::dds::DataWriter*, - const eprosima::fastdds::dds::PublicationMatchedStatus& info) -{ - if (info.current_count_change == 1) - { - matched_ = info.current_count; - std::cout << "Publisher matched." << std::endl; - if (matched_ > 0) - { - awake(); - } - } - else if (info.current_count_change == -1) - { - matched_ = info.current_count; - std::cout << "Publisher unmatched." << std::endl; - } - else - { - std::cout << info.current_count_change - << " is not a valid value for PublicationMatchedStatus current count change" << std::endl; - } -} - -void CustomPayloadPoolDataPublisher::wait() -{ - std::unique_lock lck(wait_matched_cv_mtx_); - wait_matched_cv_.wait(lck, [this] - { - return matched_ > 0 || is_stopped(); - }); -} - -void CustomPayloadPoolDataPublisher::awake() -{ - wait_matched_cv_.notify_all(); -} - -void CustomPayloadPoolDataPublisher::run_thread( - uint32_t samples, - uint32_t sleep) -{ - while (!is_stopped() && (samples == 0 || hello_.index() < samples)) - { - if (matched_ > 0) - { - if (publish()) - { - std::cout << "Message: " << hello_.message().data() << " with index: " << hello_.index() - << " SENT" << std::endl; - std::this_thread::sleep_for(std::chrono::milliseconds(sleep)); - } - // something went wrong writing - else - { - has_stopped_for_unexpected_error_ = true; - CustomPayloadPoolDataPublisher::stop(); - } - } - else - { - wait(); - } - } -} - -bool CustomPayloadPoolDataPublisher::run( - uint32_t samples, - uint32_t sleep) -{ - stop_ = false; - std::thread thread(&CustomPayloadPoolDataPublisher::run_thread, this, samples, sleep); - if (samples == 0) - { - std::cout << "Publisher running. Please press CTRL+C to stop the Publisher at any time." << std::endl; - } - else - { - std::cout << "Publisher running " << samples << " samples." << std::endl; - } - - thread.join(); - return has_stopped_for_unexpected_error_; -} - -bool CustomPayloadPoolDataPublisher::publish() -{ - hello_.index(hello_.index() + 1); - stop_ = !writer_->write(&hello_); - return !stop_; -} diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPublisher.h b/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPublisher.h deleted file mode 100644 index 9e4c0d8026..0000000000 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataPublisher.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// 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. - -/** - * @file CustomPayloadPoolDataPublisher.h - * - */ - -#ifndef CUSTOM_PAYLOAD_POOL_DATA_PUBLISHER_H_ -#define CUSTOM_PAYLOAD_POOL_DATA_PUBLISHER_H_ - -#include -#include - -#include "CustomPayloadPool.hpp" -#include "CustomPayloadPoolDataPubSubTypes.h" - -#include -#include -#include - -/** - * Class used to group into a single working unit a Publisher with a DataWriter, its listener, and a TypeSupport member - * corresponding to the HelloWorld datatype - */ -class CustomPayloadPoolDataPublisher : private eprosima::fastdds::dds::DataWriterListener -{ -public: - - CustomPayloadPoolDataPublisher( - std::shared_ptr payload_pool); - - virtual ~CustomPayloadPoolDataPublisher(); - - //! Initialize the publisher - bool init(); - - //! Run for number samples, publish every sleep seconds - bool run( - uint32_t number, - uint32_t sleep); - -private: - - //! Publish a sample - bool publish(); - - //! Run thread for number samples, publish every sleep seconds - void run_thread( - uint32_t number, - uint32_t sleep); - - //! Return the current state of execution - static bool is_stopped(); - - //! Trigger the end of execution - static void stop(); - - //! Callback executed when a DataReader is matched or unmatched - void on_publication_matched( - eprosima::fastdds::dds::DataWriter* writer, - const eprosima::fastdds::dds::PublicationMatchedStatus& info) override; - - //! Return true if there are at least 1 matched DataReaders - bool enough_matched(); - - //! Block the thread until enough DataReaders are matched - void wait(); - - //! Unblock the thread so publication of samples begins/resumes - static void awake(); - - CustomPayloadPoolData hello_; - - std::shared_ptr payload_pool_; - - eprosima::fastdds::dds::DomainParticipant* participant_; - - eprosima::fastdds::dds::Publisher* publisher_; - - eprosima::fastdds::dds::Topic* topic_; - - eprosima::fastdds::dds::DataWriter* writer_; - - eprosima::fastdds::dds::TypeSupport type_; - - //! Number of DataReaders matched to the associated DataWriter - std::atomic matched_; - - //! Member used for control flow purposes - std::atomic has_stopped_for_unexpected_error_; - - //! Member used for control flow purposes - static std::atomic stop_; - - //! Protects wait_matched condition variable - static std::mutex wait_matched_cv_mtx_; - - //! Waits until enough DataReaders are matched - static std::condition_variable wait_matched_cv_; -}; - - -#endif /* CUSTOM_PAYLOAD_POOL_DATA_PUBLISHER_H_ */ diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataSubscriber.cpp b/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataSubscriber.cpp deleted file mode 100644 index ab35a8684e..0000000000 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataSubscriber.cpp +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// 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. - -/** - * @file CustomPayloadPoolDataSubscriber.cpp - * - */ - -#include "CustomPayloadPoolDataSubscriber.h" - -#include - -#include -#include -#include -#include -#include - -using namespace eprosima::fastdds::dds; - -std::atomic CustomPayloadPoolDataSubscriber::stop_(false); -std::mutex CustomPayloadPoolDataSubscriber::terminate_cv_mtx_; -std::condition_variable CustomPayloadPoolDataSubscriber::terminate_cv_; - -CustomPayloadPoolDataSubscriber::CustomPayloadPoolDataSubscriber( - std::shared_ptr payload_pool) - : payload_pool_(payload_pool) - , participant_(nullptr) - , subscriber_(nullptr) - , topic_(nullptr) - , reader_(nullptr) - , type_(new CustomPayloadPoolDataPubSubType()) - , matched_(0) - , samples_(0) - , max_samples_(0) -{ - -} - -bool CustomPayloadPoolDataSubscriber::is_stopped() -{ - return stop_; -} - -void CustomPayloadPoolDataSubscriber::stop() -{ - stop_ = true; - terminate_cv_.notify_all(); -} - -bool CustomPayloadPoolDataSubscriber::init() -{ - DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT; - pqos.name("CustomPayloadPoolDataSubscriber"); - auto factory = DomainParticipantFactory::get_instance(); - - participant_ = factory->create_participant(0, pqos); - - if (participant_ == nullptr) - { - return false; - } - - /* Register the type */ - type_.register_type(participant_); - - /* Create the subscriber */ - subscriber_ = participant_->create_subscriber(SUBSCRIBER_QOS_DEFAULT, nullptr); - - if (subscriber_ == nullptr) - { - return false; - } - - /* Create the topic */ - topic_ = participant_->create_topic( - "CustomPayloadPoolTopic", - type_.get_type_name(), - TOPIC_QOS_DEFAULT); - - if (topic_ == nullptr) - { - return false; - } - - /* Create the reader */ - DataReaderQos rqos = DATAREADER_QOS_DEFAULT; - rqos.reliability().kind = RELIABLE_RELIABILITY_QOS; - - reader_ = subscriber_->create_datareader(topic_, rqos, this, StatusMask::all(), payload_pool_); - - if (reader_ == nullptr) - { - return false; - } - - // Register SIGINT signal handler to stop thread execution - signal(SIGINT, [](int /*signum*/) - { - std::cout << "SIGINT received, stopping subscriber execution." << std::endl; - CustomPayloadPoolDataSubscriber::stop(); - }); - - return true; -} - -CustomPayloadPoolDataSubscriber::~CustomPayloadPoolDataSubscriber() -{ - if (participant_ != nullptr) - { - participant_->delete_contained_entities(); - DomainParticipantFactory::get_instance()->delete_participant(participant_); - } -} - -void CustomPayloadPoolDataSubscriber::on_subscription_matched( - DataReader*, - const SubscriptionMatchedStatus& info) -{ - if (info.current_count_change == 1) - { - matched_ = info.total_count; - std::cout << "Subscriber matched." << std::endl; - } - else if (info.current_count_change == -1) - { - matched_ = info.total_count; - std::cout << "Subscriber unmatched." << std::endl; - } - else - { - std::cout << info.current_count_change - << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; - } -} - -void CustomPayloadPoolDataSubscriber::on_data_available( - DataReader* reader) -{ - SampleInfo info; - if (reader->take_next_sample(&hello_, &info) == RETCODE_OK) - { - if (info.instance_state == ALIVE_INSTANCE_STATE) - { - samples_++; - // Print your structure data here. - std::cout << "Message [" << samples_ << "] of " << hello_.message() << " " << hello_.index() - << " RECEIVED" << std::endl; - - if (max_samples_ > 0 && (samples_ >= max_samples_)) - { - stop(); - } - } - } -} - -bool CustomPayloadPoolDataSubscriber::run( - uint32_t samples) -{ - max_samples_ = samples; - stop_ = false; - if (samples == 0) - { - std::cout << "Subscriber running. Please press Ctrl+C to stop the Subscriber at any time." << std::endl; - } - else - { - std::cout << "Subscriber running until " << samples << " samples have been received" << std::endl; - } - - std::unique_lock lck(terminate_cv_mtx_); - terminate_cv_.wait(lck, [] - { - return is_stopped(); - }); - return is_stopped(); -} diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataSubscriber.h b/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataSubscriber.h deleted file mode 100644 index 7179f216fb..0000000000 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataSubscriber.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// 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. - -/** - * @file CustomPayloadPoolDataSubscriber.h - * - */ - -#ifndef CUSTOM_PAYLOAD_POOL_DATA_SUBSCRIBER_H_ -#define CUSTOM_PAYLOAD_POOL_DATA_SUBSCRIBER_H_ - -#include -#include - -#include -#include -#include -#include - -#include "CustomPayloadPool.hpp" -#include "CustomPayloadPoolDataPubSubTypes.h" - -class CustomPayloadPoolDataSubscriber : private eprosima::fastdds::dds::DataReaderListener -{ -public: - - CustomPayloadPoolDataSubscriber( - std::shared_ptr payload_pool); - - virtual ~CustomPayloadPoolDataSubscriber(); - - //!Initialize the subscriber - bool init(); - - //!Run the subscriber until all samples have been received. - bool run( - uint32_t samples); - -private: - - void on_data_available( - eprosima::fastdds::dds::DataReader* reader) override; - - void on_subscription_matched( - eprosima::fastdds::dds::DataReader* reader, - const eprosima::fastdds::dds::SubscriptionMatchedStatus& info) override; - - //! Return the current state of execution - static bool is_stopped(); - - //! Trigger the end of execution - static void stop(); - - CustomPayloadPoolData hello_; - - std::shared_ptr payload_pool_; - - eprosima::fastdds::dds::DomainParticipant* participant_; - - eprosima::fastdds::dds::Subscriber* subscriber_; - - eprosima::fastdds::dds::Topic* topic_; - - eprosima::fastdds::dds::DataReader* reader_; - - eprosima::fastdds::dds::TypeSupport type_; - - int32_t matched_; - - uint32_t samples_; - - uint32_t max_samples_; - - //! Member used for control flow purposes - static std::atomic stop_; - - //! Protects terminate condition variable - static std::mutex terminate_cv_mtx_; - - //! Waits during execution until SIGINT or max_messages_ samples are received - static std::condition_variable terminate_cv_; -}; - -#endif /* CUSTOM_PAYLOAD_POOL_DATA_SUBSCRIBER_H_ */ diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataTypeObjectSupport.cxx b/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataTypeObjectSupport.cxx deleted file mode 100644 index ed6a4c1966..0000000000 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPoolDataTypeObjectSupport.cxx +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// 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. - -/*! - * @file CustomPayloadPoolDataTypeObjectSupport.cxx - * Source file containing the implementation to register the TypeObject representation of the described types in the IDL file - * - * This file was generated by the tool fastddsgen. - */ - -#include "CustomPayloadPoolDataTypeObjectSupport.hpp" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "CustomPayloadPoolData.hpp" - - -using namespace eprosima::fastdds::dds::xtypes; - -void register_CustomPayloadPoolData_type_objects() -{ - static std::once_flag once_flag; - std::call_once(once_flag, []() - { - TypeIdentifier type_id; - register_CustomPayloadPoolData_type_identifier(type_id); - - }); -} - -// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method -void register_CustomPayloadPoolData_type_identifier( - TypeIdentifier& type_id) -{ - { - StructTypeFlag struct_flags_CustomPayloadPoolData = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::NOT_APPLIED, - false, false); - ReturnCode_t return_code_CustomPayloadPoolData; - TypeIdentifierPair type_ids_CustomPayloadPoolData; - QualifiedTypeName type_name_CustomPayloadPoolData = "CustomPayloadPoolData"; - eprosima::fastcdr::optional type_ann_builtin_CustomPayloadPoolData; - eprosima::fastcdr::optional ann_custom_CustomPayloadPoolData; - CompleteTypeDetail detail_CustomPayloadPoolData = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_CustomPayloadPoolData, ann_custom_CustomPayloadPoolData, type_name_CustomPayloadPoolData.to_string()); - CompleteStructHeader header_CustomPayloadPoolData; - header_CustomPayloadPoolData = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_CustomPayloadPoolData); - CompleteStructMemberSeq member_seq_CustomPayloadPoolData; - { - return_code_CustomPayloadPoolData = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "_uint32_t", type_ids_CustomPayloadPoolData); - - if (return_code_CustomPayloadPoolData != eprosima::fastdds::dds::RETCODE_OK) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "index Structure member TypeIdentifier unknown to TypeObjectRegistry."); - type_id = TypeIdentifier(); - return; - } - StructMemberFlag member_flags_index = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructKind::NOT_APPLIED, - false, false, false, false); - CommonStructMember common_index; - MemberId member_id_index = 0x00000000; - if (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1()._d() || TK_NONE == type_ids_CustomPayloadPoolData.type_identifier2()._d() || - (TI_PLAIN_SEQUENCE_SMALL == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().seq_sdefn().header().equiv_kind()) || - (TI_PLAIN_SEQUENCE_LARGE == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().seq_ldefn().header().equiv_kind()) || - (TI_PLAIN_ARRAY_SMALL == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().array_sdefn().header().equiv_kind()) || - (TI_PLAIN_ARRAY_LARGE == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().array_ldefn().header().equiv_kind()) || - (TI_PLAIN_MAP_SMALL == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().map_sdefn().header().equiv_kind() || - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().map_sdefn().key_identifier()->_d())) || - (TI_PLAIN_MAP_LARGE == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().map_ldefn().header().equiv_kind() || - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().map_ldefn().key_identifier()->_d()))) - { - common_index = TypeObjectUtils::build_common_struct_member(member_id_index, member_flags_index, type_ids_CustomPayloadPoolData.type_identifier1()); - } - else if (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2()._d() || - (TI_PLAIN_SEQUENCE_SMALL == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().seq_sdefn().header().equiv_kind()) || - (TI_PLAIN_SEQUENCE_LARGE == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().seq_ldefn().header().equiv_kind()) || - (TI_PLAIN_ARRAY_SMALL == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().array_sdefn().header().equiv_kind()) || - (TI_PLAIN_ARRAY_LARGE == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().array_ldefn().header().equiv_kind()) || - (TI_PLAIN_MAP_SMALL == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().map_sdefn().header().equiv_kind() || - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().map_sdefn().key_identifier()->_d())) || - (TI_PLAIN_MAP_LARGE == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().map_ldefn().header().equiv_kind() || - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().map_ldefn().key_identifier()->_d()))) - { - common_index = TypeObjectUtils::build_common_struct_member(member_id_index, member_flags_index, type_ids_CustomPayloadPoolData.type_identifier2()); - } - else - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "Structure index member TypeIdentifier inconsistent."); - type_id = TypeIdentifier(); - return; - } - MemberName name_index = "index"; - eprosima::fastcdr::optional member_ann_builtin_index; - ann_custom_CustomPayloadPoolData.reset(); - CompleteMemberDetail detail_index = TypeObjectUtils::build_complete_member_detail(name_index, member_ann_builtin_index, ann_custom_CustomPayloadPoolData); - CompleteStructMember member_index = TypeObjectUtils::build_complete_struct_member(common_index, detail_index); - TypeObjectUtils::add_complete_struct_member(member_seq_CustomPayloadPoolData, member_index); - } - { - return_code_CustomPayloadPoolData = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "anonymous_string_unbounded", type_ids_CustomPayloadPoolData); - - if (return_code_CustomPayloadPoolData != eprosima::fastdds::dds::RETCODE_OK) - { - { - SBound bound = 0; - StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); - if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, - "anonymous_string_unbounded")) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); - } - } - return_code_CustomPayloadPoolData = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "anonymous_string_unbounded", type_ids_CustomPayloadPoolData); - if (return_code_CustomPayloadPoolData != eprosima::fastdds::dds::RETCODE_OK) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "anonymous_string_unbounded: Given String TypeIdentifier unknown to TypeObjectRegistry."); - type_id = TypeIdentifier(); - return; - } - } - StructMemberFlag member_flags_message = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructKind::NOT_APPLIED, - false, false, false, false); - CommonStructMember common_message; - MemberId member_id_message = 0x00000001; - if (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1()._d() || TK_NONE == type_ids_CustomPayloadPoolData.type_identifier2()._d() || - (TI_PLAIN_SEQUENCE_SMALL == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().seq_sdefn().header().equiv_kind()) || - (TI_PLAIN_SEQUENCE_LARGE == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().seq_ldefn().header().equiv_kind()) || - (TI_PLAIN_ARRAY_SMALL == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().array_sdefn().header().equiv_kind()) || - (TI_PLAIN_ARRAY_LARGE == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().array_ldefn().header().equiv_kind()) || - (TI_PLAIN_MAP_SMALL == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().map_sdefn().header().equiv_kind() || - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().map_sdefn().key_identifier()->_d())) || - (TI_PLAIN_MAP_LARGE == type_ids_CustomPayloadPoolData.type_identifier1()._d() && - (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().map_ldefn().header().equiv_kind() || - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier1().map_ldefn().key_identifier()->_d()))) - { - common_message = TypeObjectUtils::build_common_struct_member(member_id_message, member_flags_message, type_ids_CustomPayloadPoolData.type_identifier1()); - } - else if (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2()._d() || - (TI_PLAIN_SEQUENCE_SMALL == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().seq_sdefn().header().equiv_kind()) || - (TI_PLAIN_SEQUENCE_LARGE == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().seq_ldefn().header().equiv_kind()) || - (TI_PLAIN_ARRAY_SMALL == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().array_sdefn().header().equiv_kind()) || - (TI_PLAIN_ARRAY_LARGE == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().array_ldefn().header().equiv_kind()) || - (TI_PLAIN_MAP_SMALL == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().map_sdefn().header().equiv_kind() || - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().map_sdefn().key_identifier()->_d())) || - (TI_PLAIN_MAP_LARGE == type_ids_CustomPayloadPoolData.type_identifier2()._d() && - (EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().map_ldefn().header().equiv_kind() || - EK_COMPLETE == type_ids_CustomPayloadPoolData.type_identifier2().map_ldefn().key_identifier()->_d()))) - { - common_message = TypeObjectUtils::build_common_struct_member(member_id_message, member_flags_message, type_ids_CustomPayloadPoolData.type_identifier2()); - } - else - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "Structure message member TypeIdentifier inconsistent."); - type_id = TypeIdentifier(); - return; - } - MemberName name_message = "message"; - eprosima::fastcdr::optional member_ann_builtin_message; - ann_custom_CustomPayloadPoolData.reset(); - CompleteMemberDetail detail_message = TypeObjectUtils::build_complete_member_detail(name_message, member_ann_builtin_message, ann_custom_CustomPayloadPoolData); - CompleteStructMember member_message = TypeObjectUtils::build_complete_struct_member(common_message, detail_message); - TypeObjectUtils::add_complete_struct_member(member_seq_CustomPayloadPoolData, member_message); - } - CompleteStructType struct_type_CustomPayloadPoolData = TypeObjectUtils::build_complete_struct_type(struct_flags_CustomPayloadPoolData, header_CustomPayloadPoolData, member_seq_CustomPayloadPoolData); - if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_struct_type_object(struct_type_CustomPayloadPoolData, type_name_CustomPayloadPoolData.to_string(), type_id)) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "CustomPayloadPoolData already registered in TypeObjectRegistry for a different type."); - } - return_code_CustomPayloadPoolData = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "CustomPayloadPoolData", type_ids_CustomPayloadPoolData); - if (return_code_CustomPayloadPoolData != eprosima::fastdds::dds::RETCODE_OK) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "CustomPayloadPoolData: Given Struct TypeIdentifier unknown to TypeObjectRegistry."); - type_id = TypeIdentifier(); - return; - } - } -} - diff --git a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPool_main.cpp b/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPool_main.cpp deleted file mode 100644 index fd9f9db33a..0000000000 --- a/examples/cpp/dds/CustomPayloadPoolExample/CustomPayloadPool_main.cpp +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// 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. - -/** - * @file CustomPayloadPool_main.cpp - * - */ - -#include -#include - -#include -#include -#include - -#include "CustomPayloadPoolDataPublisher.h" -#include "CustomPayloadPoolDataSubscriber.h" - -using eprosima::fastdds::dds::Log; - -namespace option = eprosima::option; - -enum ApplicationRole : uint8_t -{ - PUBLISHER, - SUBSCRIBER -}; - -struct Arg : public option::Arg -{ - static void print_error( - const char* msg1, - const option::Option& opt, - const char* msg2) - { - fprintf(stderr, "%s", msg1); - fwrite(opt.name, opt.namelen, 1, stderr); - fprintf(stderr, "%s", msg2); - } - - static option::ArgStatus Unknown( - const option::Option& option, - bool msg) - { - if (msg) - { - print_error("Unknown option '", option, "'\n"); - } - return option::ARG_ILLEGAL; - } - - static option::ArgStatus Required( - const option::Option& option, - bool msg) - { - if (option.arg != 0 && option.arg[0] != 0) - { - return option::ARG_OK; - } - - if (msg) - { - print_error("Option '", option, "' requires an argument\n"); - } - return option::ARG_ILLEGAL; - } - - static option::ArgStatus Numeric( - const option::Option& option, - bool msg) - { - char* endptr = 0; - if ( option.arg != nullptr ) - { - strtol(option.arg, &endptr, 10); - if (endptr != option.arg && *endptr == 0) - { - return option::ARG_OK; - } - } - - if (msg) - { - print_error("Option '", option, "' requires a numeric argument\n"); - } - return option::ARG_ILLEGAL; - } - - template::max()> - static option::ArgStatus NumericRange( - const option::Option& option, - bool msg) - { - static_assert(min <= max, "NumericRange: invalid range provided."); - - char* endptr = 0; - if ( option.arg != nullptr ) - { - long value = strtol(option.arg, &endptr, 10); - if ( endptr != option.arg && *endptr == 0 && - value >= min && value <= max) - { - return option::ARG_OK; - } - } - - if (msg) - { - std::ostringstream os; - os << "' requires a numeric argument in range [" - << min << ", " << max << "]" << std::endl; - print_error("Option '", option, os.str().c_str()); - } - - return option::ARG_ILLEGAL; - } - - static option::ArgStatus String( - const option::Option& option, - bool msg) - { - if (option.arg != 0) - { - return option::ARG_OK; - } - if (msg) - { - print_error("Option '", option, "' requires an argument\n"); - } - return option::ARG_ILLEGAL; - } - -}; - -enum optionIndex -{ - UNKNOWN_OPT, - HELP, - SAMPLES, - INTERVAL -}; - -const option::Descriptor usage[] = { - { UNKNOWN_OPT, 0, "", "", Arg::None, - "Usage: CustomPayloadPoolExample \n\nGeneral options:" }, - { HELP, 0, "h", "help", Arg::None, " -h \t--help \tProduce help message." }, - { SAMPLES, 0, "s", "samples", Arg::NumericRange<>, - " -s , \t--samples= \tNumber of samples (0, default, infinite)." }, - { UNKNOWN_OPT, 0, "", "", Arg::None, "\nPublisher options:"}, - { INTERVAL, 0, "i", "interval", Arg::NumericRange<>, - " -i , \t--interval= \tTime between samples in milliseconds (Default: 100)." }, - { 0, 0, 0, 0, 0, 0 } -}; - -int main( - int argc, - char** argv) -{ - int columns; - -#if defined(_WIN32) - char* buf = nullptr; - size_t sz = 0; - if (_dupenv_s(&buf, &sz, "COLUMNS") == 0 && buf != nullptr) - { - columns = strtol(buf, nullptr, 10); - free(buf); - } - else - { - columns = 80; - } -#else - columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 80; -#endif // if defined(_WIN32) - - std::cout << "Starting " << std::endl; - - int type = ApplicationRole::PUBLISHER; - uint32_t count = 0; - uint32_t sleep = 100; - - argc -= (argc > 0); - argv += (argc > 0); // skip program name argv[0] if present - option::Stats stats(true, usage, argc, argv); - std::vector options(stats.options_max); - std::vector buffer(stats.buffer_max); - option::Parser parse(true, usage, argc, argv, &options[0], &buffer[0]); - - try - { - if (parse.error()) - { - throw 1; - } - - if (options[HELP] || options[UNKNOWN_OPT]) - { - throw 1; - } - - if (parse.nonOptionsCount() < 1) - { - throw 2; - } - - // Decide between publisher or subscriber - const char* type_name = parse.nonOption(0); - - // make sure is the first option. - // type_name and buffer[0].name reference the original command line char array - // type_name must precede any other arguments in the array. - // Note buffer[0].arg may be null for non-valued options and is not reliable for - // testing purposes. - if (parse.optionsCount() && type_name >= buffer[0].name) - { - throw 2; - } - - if (strcmp(type_name, "publisher") == 0) - { - type = ApplicationRole::PUBLISHER; - } - else if (strcmp(type_name, "subscriber") == 0) - { - type = ApplicationRole::SUBSCRIBER; - } - else - { - throw 2; - } - } - catch (int error) - { - if ( error == 2 ) - { - std::cerr << "ERROR: first argument must be " << std::endl; - } - option::printUsage(fwrite, stdout, usage, columns); - return error; - } - - // Decide between the old and new syntax - if (parse.nonOptionsCount() > 1) - { - // old syntax, only affects publishers - // old and new syntax cannot be mixed - if (type != ApplicationRole::PUBLISHER || parse.optionsCount() >= 0) - { - option::printUsage(fwrite, stdout, usage, columns); - return 1; - } - } - else - { - // new syntax - option::Option* opt = options[SAMPLES]; - if (opt) - { - count = strtol(opt->arg, nullptr, 10); - } - - opt = options[INTERVAL]; - if (opt) - { - sleep = strtol(opt->arg, nullptr, 10); - } - } - - // Create custom payload pool - std::shared_ptr payload_pool = std::make_shared(); - - bool execution_status = false; - - switch (type) - { - case ApplicationRole::PUBLISHER: - { - CustomPayloadPoolDataPublisher mypub(payload_pool); - if (mypub.init()) - { - execution_status = !mypub.run(count, sleep); - } - else - { - return 1; - } - break; - } - case ApplicationRole::SUBSCRIBER: - { - CustomPayloadPoolDataSubscriber mysub(payload_pool); - if (mysub.init()) - { - execution_status = !mysub.run(count); - } - else - { - return 1; - } - break; - } - } - Log::Reset(); - return execution_status; -} diff --git a/examples/cpp/dds/CustomPayloadPoolExample/README.md b/examples/cpp/dds/CustomPayloadPoolExample/README.md deleted file mode 100644 index ee32ace9a4..0000000000 --- a/examples/cpp/dds/CustomPayloadPoolExample/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Objetive - -This example has been developed to allow setting the endpoints' payload pool from the DDS layer. -In that way, a custom payload pool is mandatory to be implemented, and passed to the endpoints in the publisher and subscriber implementations. - -# Launch - -To launch this test open two different consoles: - -In the first one launch: `./CustomPayloadPoolExample publisher` (or `CustomPayloadPoolExample.exe publisher` on Windows). -In the second one: `./CustomPayloadPoolExample subscriber` (or `CustomPayloadPoolExample.exe subscriber` on Windows). - -The endpoints will match and communicate with the custom payload pool. diff --git a/test/examples/custom_payload_pool.compose.yml b/test/examples/custom_payload_pool.compose.yml new file mode 100644 index 0000000000..51255be654 --- /dev/null +++ b/test/examples/custom_payload_pool.compose.yml @@ -0,0 +1,29 @@ +# FASTDDS_TODO_BEFORE(3, 0, "This compose file should be used for the future configuration example"); +version: "3" + +services: + subscriber: + image: @DOCKER_IMAGE_NAME@ + volumes: + - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ + - @fastcdr_LIB_DIR@:@fastcdr_LIB_DIR@ + @TINYXML2_LIB_DIR_COMPOSE_VOLUME@ + environment: + # TODO(eduponz): LD_LIBRARY_PATH is not the correct variable for Windows + LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ + EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/custom_payload_pool + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/custom_payload_pool@FILE_EXTENSION@ subscriber --samples 10" + + publisher: + image: @DOCKER_IMAGE_NAME@ + volumes: + - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ + - @fastcdr_LIB_DIR@:@fastcdr_LIB_DIR@ + @TINYXML2_LIB_DIR_COMPOSE_VOLUME@ + environment: + # TODO(eduponz): LD_LIBRARY_PATH is not the correct variable for Windows + LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ + EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/custom_payload_pool + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/custom_payload_pool@FILE_EXTENSION@ publisher --samples 10" + depends_on: + - subscriber diff --git a/test/examples/test_custom_payload_pool.py b/test/examples/test_custom_payload_pool.py new file mode 100644 index 0000000000..d0173bf28e --- /dev/null +++ b/test/examples/test_custom_payload_pool.py @@ -0,0 +1,39 @@ +import subprocess +import pytest +def test_custom_payload_pool(): + """.""" + ret = False + out = '' + try: + out = subprocess.check_output( + '@DOCKER_EXECUTABLE@ compose -f custom_payload_pool.compose.yml up', + stderr=subprocess.STDOUT, + shell=True, + timeout=30 + ).decode().split('\n') + + sent = 0 + received = 0 + for line in out: + if 'SENT' in line: + sent += 1 + continue + + if 'RECEIVED' in line: + received += 1 + continue + + if sent != 0 and received != 0 and sent == received: + ret = True + else: + print('ERROR: sent: ' + str(sent) + ', but received: ' + str(received)) + raise subprocess.CalledProcessError(1, '') + + except subprocess.CalledProcessError: + for l in out: + print(l) + except subprocess.TimeoutExpired: + print('TIMEOUT') + print(out) + + assert(ret) diff --git a/versions.md b/versions.md index 53b1199237..40807c0068 100644 --- a/versions.md +++ b/versions.md @@ -41,6 +41,7 @@ Forthcoming * Refactor examples: * Hello world example with wait-sets and environment XML profiles. * Configuration example that condenses multiple QoS examples. Multiple configurations allowed through argument parsing. + * Custom payload pool example that uses a user-defined payload pool instead of the default * Removed `TypeConsistencyQos` from DataReader, and included `TypeConsistencyEnforcementQosPolicy` and `DataRepresentationQosPolicy` * Added new `flow_controller_descriptor_list` XML configuration, remove `ThroughtputController`. * Migrate `#define`s within `BuiltinEndpoints.hpp` to namespaced `constexpr` variables.