diff --git a/examples/cpp/hello_world/CLIParser.hpp b/examples/cpp/hello_world/CLIParser.hpp index 231cd14b86b..b4fec827d6a 100644 --- a/examples/cpp/hello_world/CLIParser.hpp +++ b/examples/cpp/hello_world/CLIParser.hpp @@ -28,6 +28,13 @@ class CLIParser CLIParser() = delete; + enum entity_kind + { + PUBLISHER, + SUBSCRIBER, + UNDEFINED + }; + struct publisher_config { uint16_t samples = 0; @@ -40,7 +47,7 @@ class CLIParser struct hello_world_config { - std::string entity = ""; + entity_kind entity = entity_kind::UNDEFINED; publisher_config pub_config; subscriber_config sub_config; }; @@ -71,9 +78,13 @@ class CLIParser std::string first_argument = argv[1]; - if (first_argument == "publisher" || first_argument == "subscriber") + if (first_argument == "publisher" ) + { + config.entity = entity_kind::PUBLISHER; + } + else if ( first_argument == "subscriber") { - config.entity = first_argument; + config.entity = entity_kind::SUBSCRIBER; } else { @@ -102,11 +113,11 @@ class CLIParser try { uint16_t samples = static_cast(std::stoi(argv[++i])); - if (config.entity == "publisher") + if (config.entity == entity_kind::PUBLISHER) { config.pub_config.samples = samples; } - else if (config.entity == "subscriber") + else if (config.entity == entity_kind::SUBSCRIBER) { config.sub_config.samples = samples; } @@ -136,7 +147,7 @@ class CLIParser } else if (arg == "-w" || arg == "--waitset") { - if (config.entity == "subscriber") + if (config.entity == entity_kind::SUBSCRIBER) { config.sub_config.use_waitset = true; } diff --git a/examples/cpp/hello_world/CMakeLists.txt b/examples/cpp/hello_world/CMakeLists.txt index 33b21dad5a1..34588413662 100644 --- a/examples/cpp/hello_world/CMakeLists.txt +++ b/examples/cpp/hello_world/CMakeLists.txt @@ -46,7 +46,7 @@ target_compile_definitions(hello_world PRIVATE ) target_link_libraries(hello_world fastdds fastcdr) install(TARGETS hello_world - RUNTIME DESTINATION examples/cpp/hello_world/${BIN_INSTALL_DIR}) + RUNTIME DESTINATION fastdds/examples/cpp/hello_world/${BIN_INSTALL_DIR}) # Copy the XML files over to the build directory file(GLOB_RECURSE XML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.xml) diff --git a/examples/cpp/hello_world/HelloWorld_main.cpp b/examples/cpp/hello_world/HelloWorld_main.cpp index 46f69b0e0bb..25b124f0a4c 100644 --- a/examples/cpp/hello_world/HelloWorld_main.cpp +++ b/examples/cpp/hello_world/HelloWorld_main.cpp @@ -17,7 +17,9 @@ * */ +#include #include +#include #include #include @@ -29,61 +31,172 @@ using eprosima::fastdds::dds::Log; +std::function signal_handler; + int main( int argc, char** argv) { auto ret = EXIT_SUCCESS; + HelloWorldPublisher* publisher = nullptr; + HelloWorldSubscriber* subscriber = nullptr; + HelloWorldSubscriberWaitset* subscriber_waitset = nullptr; + std::thread* thread = nullptr; const std::string topic_name = "hello_world_topic"; + std::string entity_name = "undefined"; + uint16_t samples = 0; CLIParser::hello_world_config config = CLIParser::parse_cli_options(argc, argv); - if (config.entity == "publisher") + switch (config.entity) { - try - { - HelloWorldPublisher hello_world_publisher(config.pub_config, topic_name); - hello_world_publisher.run(); - } - catch (const std::runtime_error& e) - { - EPROSIMA_LOG_ERROR(PUBLISHER, e.what()); - ret = EXIT_FAILURE; - } - } - else if (config.entity == "subscriber") - { - if (config.sub_config.use_waitset) - { + case CLIParser::entity_kind::PUBLISHER: + entity_name = "Publisher"; + samples = config.pub_config.samples; try { - HelloWorldSubscriberWaitset hello_world_subscriber_waitset(config.sub_config, topic_name); - hello_world_subscriber_waitset.run(); + publisher = new HelloWorldPublisher(config.pub_config, topic_name); + thread = new std::thread(&HelloWorldPublisher::run, publisher); } catch (const std::runtime_error& e) { - EPROSIMA_LOG_ERROR(SUBSCRIBER, e.what()); + EPROSIMA_LOG_ERROR(PUBLISHER, e.what()); ret = EXIT_FAILURE; } - } - else - { - try + break; + case CLIParser::entity_kind::SUBSCRIBER: + samples = config.sub_config.samples; + if (config.sub_config.use_waitset) { - HelloWorldSubscriber hello_world_subscriber(config.sub_config, topic_name); - hello_world_subscriber.run(); + entity_name = "Waitset Subscriber"; + try + { + subscriber_waitset = new HelloWorldSubscriberWaitset(config.sub_config, topic_name); + thread = new std::thread(&HelloWorldSubscriberWaitset::run, subscriber_waitset); + } + catch (const std::runtime_error& e) + { + EPROSIMA_LOG_ERROR(SUBSCRIBER, e.what()); + ret = EXIT_FAILURE; + } } - catch (const std::runtime_error& e) + else { - EPROSIMA_LOG_ERROR(SUBSCRIBER_WAITSET, e.what()); - ret = EXIT_FAILURE; + entity_name = "Subscriber"; + try + { + subscriber = new HelloWorldSubscriber(config.sub_config, topic_name); + thread = new std::thread(&HelloWorldSubscriber::run, subscriber); + } + catch (const std::runtime_error& e) + { + EPROSIMA_LOG_ERROR(SUBSCRIBER_WAITSET, e.what()); + ret = EXIT_FAILURE; + } } - } + break; + default: + EPROSIMA_LOG_ERROR(CLI_PARSER, "unknown entity"); + CLIParser::print_help(EXIT_FAILURE); + break; + } + + if (samples == 0) + { + std::cout << entity_name << " running. Please press Ctrl+C to stop the " + << entity_name << " at any time." << std::endl; } - // example should never reach this point else { - EPROSIMA_LOG_ERROR(CLI_PARSER, "unknown entity " + config.entity); - CLIParser::print_help(EXIT_FAILURE); + switch (config.entity) + { + case CLIParser::entity_kind::PUBLISHER: + std::cout << entity_name << " running " << samples << " samples. Please press Ctrl+C to stop the " + << entity_name << " at any time." << std::endl; + break; + case CLIParser::entity_kind::SUBSCRIBER: + default: + std::cout << entity_name << " running until " << samples << " samples have been received. Please press " + << "Ctrl+C to stop the " << entity_name << " at any time." << std::endl; + break; + } + } + + signal_handler = [&](std::string signal) + { + std::cout << "\n" << signal << " received, stopping " << entity_name << " execution." << std::endl; + switch (config.entity) + { + case CLIParser::entity_kind::PUBLISHER: + if (nullptr != publisher) + { + publisher->stop(); + } + break; + case CLIParser::entity_kind::SUBSCRIBER: + default: + if (config.sub_config.use_waitset) + { + if (nullptr != subscriber_waitset) + { + subscriber_waitset->stop(); + } + } + else + { + if (nullptr != subscriber) + { + subscriber->stop(); + } + } + break; + } + }; + signal(SIGINT, [](int /*signum*/) + { + signal_handler("SIGINT"); + }); + signal(SIGTERM, [](int /*signum*/) + { + signal_handler("SIGTERM"); + }); +#ifndef _WIN32 + signal(SIGQUIT, [](int /*signum*/) + { + signal_handler("SIGQUIT"); + }); + signal(SIGHUP, [](int /*signum*/) + { + signal_handler("SIGHUP"); + }); +#endif // _WIN32 + + thread->join(); + delete thread; + switch (config.entity) + { + case CLIParser::entity_kind::PUBLISHER: + if (nullptr != publisher) + { + delete publisher; + } + break; + case CLIParser::entity_kind::SUBSCRIBER: + default: + if (config.sub_config.use_waitset) + { + if (nullptr != subscriber_waitset) + { + delete subscriber_waitset; + } + } + else + { + if (nullptr != subscriber) + { + delete subscriber; + } + } + break; } Log::Reset(); diff --git a/examples/cpp/hello_world/Publisher.cpp b/examples/cpp/hello_world/Publisher.cpp index 2f5530220af..e133862a9d5 100644 --- a/examples/cpp/hello_world/Publisher.cpp +++ b/examples/cpp/hello_world/Publisher.cpp @@ -49,7 +49,7 @@ HelloWorldPublisher::HelloWorldPublisher( // Set up the data type with initial values hello_.index(0); hello_.message("Hello world"); - + // Create the participant auto factory = DomainParticipantFactory::get_instance(); participant_ = factory->create_participant_with_default_profile(nullptr, StatusMask::none()); @@ -125,50 +125,15 @@ void HelloWorldPublisher::on_publication_matched( void HelloWorldPublisher::run() { - std::thread pub_thread([&] - { - while (!is_stopped() && (samples_ == 0 || hello_.index() < samples_)) - { - if (publish()) - { - std::cout << "Message: '" << hello_.message() << "' with index: '" << hello_.index() - << "' SENT" << std::endl; - } - std::this_thread::sleep_for(std::chrono::milliseconds(period_ms_)); - } - }); - if (samples_ == 0) + while (!is_stopped() && (samples_ == 0 || hello_.index() < samples_)) { - std::cout << "Publisher running. Please press Ctrl+C to stop the Publisher at any time." << std::endl; + if (publish()) + { + std::cout << "Message: '" << hello_.message() << "' with index: '" << hello_.index() + << "' SENT" << std::endl; + } + std::this_thread::sleep_for(std::chrono::milliseconds(period_ms_)); } - else - { - std::cout << "Publisher running " << samples_ << - " samples. Please press Ctrl+C to stop the Publisher at any time." << std::endl; - } - signal(SIGINT, [](int /*signum*/) - { - std::cout << "\nSIGINT received, stopping Publisher execution." << std::endl; - HelloWorldPublisher::stop(); - }); - signal(SIGTERM, [](int /*signum*/) - { - std::cout << "\nSIGTERM received, stopping Publisher execution." << std::endl; - HelloWorldPublisher::stop(); - }); -#ifndef _WIN32 - signal(SIGQUIT, [](int /*signum*/) - { - std::cout << "\nSIGQUIT received, stopping Publisher execution." << std::endl; - HelloWorldPublisher::stop(); - }); - signal(SIGHUP, [](int /*signum*/) - { - std::cout << "\nSIGHUP received, stopping Publisher execution." << std::endl; - HelloWorldPublisher::stop(); - }); -#endif // _WIN32 - pub_thread.join(); } bool HelloWorldPublisher::publish() diff --git a/examples/cpp/hello_world/Subscriber.cpp b/examples/cpp/hello_world/Subscriber.cpp index b02a4f1d749..8dcb156eec1 100644 --- a/examples/cpp/hello_world/Subscriber.cpp +++ b/examples/cpp/hello_world/Subscriber.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -140,38 +139,6 @@ void HelloWorldSubscriber::on_data_available( void HelloWorldSubscriber::run() { - 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. Please press Ctrl+C to stop the Subscriber at any time." << std::endl; - } - - signal(SIGINT, [](int /*signum*/) - { - std::cout << "\nSIGINT received, stopping Subscriber execution." << std::endl; - HelloWorldSubscriber::stop(); - }); - signal(SIGTERM, [](int /*signum*/) - { - std::cout << "\nSIGTERM received, stopping Subscriber execution." << std::endl; - HelloWorldSubscriber::stop(); - }); -#ifndef _WIN32 - signal(SIGQUIT, [](int /*signum*/) - { - std::cout << "\nSIGQUIT received, stopping Subscriber execution." << std::endl; - HelloWorldSubscriber::stop(); - }); - signal(SIGHUP, [](int /*signum*/) - { - std::cout << "\nSIGHUP received, stopping Subscriber execution." << std::endl; - HelloWorldSubscriber::stop(); - }); -#endif // _WIN32 std::unique_lock lck(terminate_cv_mtx_); terminate_cv_.wait(lck, [] { diff --git a/examples/cpp/hello_world/SubscriberWaitset.cpp b/examples/cpp/hello_world/SubscriberWaitset.cpp index e0ae1bba4a1..8b1718a8865 100644 --- a/examples/cpp/hello_world/SubscriberWaitset.cpp +++ b/examples/cpp/hello_world/SubscriberWaitset.cpp @@ -107,100 +107,63 @@ HelloWorldSubscriberWaitset::~HelloWorldSubscriberWaitset() void HelloWorldSubscriberWaitset::run() { - std::thread sub_thread([&] + while (!is_stopped()) + { + ConditionSeq triggered_conditions; + ReturnCode_t ret_code = wait_set_.wait(triggered_conditions, eprosima::fastrtps::c_TimeInfinite); + if (ReturnCode_t::RETCODE_OK != ret_code) + { + EPROSIMA_LOG_ERROR(SUBSCRIBER_WAITSET, "Error waiting for conditions"); + continue; + } + for (Condition* cond : triggered_conditions) + { + StatusCondition* status_cond = dynamic_cast(cond); + if (nullptr != status_cond) { - while (!is_stopped()) + Entity* entity = status_cond->get_entity(); + StatusMask changed_statuses = entity->get_status_changes(); + if (changed_statuses.is_active(StatusMask::subscription_matched())) { - ConditionSeq triggered_conditions; - ReturnCode_t ret_code = wait_set_.wait(triggered_conditions, eprosima::fastrtps::c_TimeInfinite); - if (ReturnCode_t::RETCODE_OK != ret_code) + SubscriptionMatchedStatus status_; + reader_->get_subscription_matched_status(status_); + if (status_.current_count_change == 1) + { + std::cout << "Waitset Subscriber matched." << std::endl; + } + else if (status_.current_count_change == -1) { - EPROSIMA_LOG_ERROR(SUBSCRIBER_WAITSET, "Error waiting for conditions"); - continue; + std::cout << "Waitset Subscriber unmatched." << std::endl; } - for (Condition* cond : triggered_conditions) + else { - StatusCondition* status_cond = dynamic_cast(cond); - if (nullptr != status_cond) + std::cout << status_.current_count_change << + " is not a valid value for SubscriptionMatchedStatus current count change" << + std::endl; + } + } + if (changed_statuses.is_active(StatusMask::data_available())) + { + SampleInfo info; + while ((!is_stopped()) && + (ReturnCode_t::RETCODE_OK == reader_->take_next_sample(&hello_, &info))) + { + if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) { - Entity* entity = status_cond->get_entity(); - StatusMask changed_statuses = entity->get_status_changes(); - if (changed_statuses.is_active(StatusMask::subscription_matched())) - { - SubscriptionMatchedStatus status_; - reader_->get_subscription_matched_status(status_); - if (status_.current_count_change == 1) - { - std::cout << "Waitset Subscriber matched." << std::endl; - } - else if (status_.current_count_change == -1) - { - std::cout << "Waitset Subscriber unmatched." << std::endl; - } - else - { - std::cout << status_.current_count_change << - " is not a valid value for SubscriptionMatchedStatus current count change" << - std::endl; - } - } - if (changed_statuses.is_active(StatusMask::data_available())) + 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_)) { - SampleInfo info; - while ((!is_stopped()) && - (ReturnCode_t::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(); - } - } - } + stop(); } } } } - }); - - if (samples_ == 0) - { - std::cout << "Waitset Subscriber running. Please press Ctrl+C to stop the Waitset Subscriber at any time." - << std::endl; - } - else - { - std::cout << "Waitset Subscriber running until " << samples_ << - " samples have been received. Please press Ctrl+C to stop the Waitset Subscriber at any time." << std::endl; + } + } } - signal(SIGINT, [](int /*signum*/) - { - std::cout << "\nSIGINT received, stopping Waitset Subscriber execution." << std::endl; - HelloWorldSubscriberWaitset::stop(); - }); - signal(SIGTERM, [](int /*signum*/) - { - std::cout << "\nSIGTERM received, stopping Waitset Subscriber execution." << std::endl; - HelloWorldSubscriberWaitset::stop(); - }); -#ifndef _WIN32 - signal(SIGQUIT, [](int /*signum*/) - { - std::cout << "\nSIGQUIT received, stopping Waitset Subscriber execution." << std::endl; - HelloWorldSubscriberWaitset::stop(); - }); - signal(SIGHUP, [](int /*signum*/) - { - std::cout << "\nSIGHUP received, stopping Waitset Subscriber execution." << std::endl; - HelloWorldSubscriberWaitset::stop(); - }); -#endif // _WIN32 - sub_thread.join(); } bool HelloWorldSubscriberWaitset::is_stopped()