Files
rclcpp/rclcpp/test/rclcpp/test_create_subscription.cpp
William Woodall 1037822a63 refactor AnySubscriptionCallback and add/deprecate callback signatures (#1598)
* refactor AnySubscriptionCallback to...

use std::variant and make the dispatch functions constexpr,
avoiding runtime dispatching.

Also, deprecate the std::function<void (std::shared_ptr<MessageT>)> signature,
as it is unsafe to share one shared_ptr when multiple subscriptions take it,
because they could mutate MessageT while others are using it. So you'd have to
make a copy for each subscription, which is no different than the
std::unique_ptr<MessageT> signature or the user making their own copy in a
shared_ptr from the const MessageT & signature or the
std::shared_ptr<const MessageT> signature.

Added a std::function<void (const std::shared_ptr<const MessageT> &)> signature
to go along side the existing
std::function<void (std::shared_ptr<const MessageT>)> signature.

Removed redundant 'const' before pass-by-value signatures, e.g.
std::function<void (const shared_ptr<const MessageT>)> became
std::function<void (shared_ptr<const MessageT>)>.
This will not affect API or any users using the old style.

Signed-off-by: William Woodall <william@osrfoundation.org>

* fix use of std::bind, free functions, etc. using new function_traits::as_std_function<>

Signed-off-by: William Woodall <william@osrfoundation.org>

* fix use of const MessageT & callbacks by fixing subscriptin_traits

Signed-off-by: William Woodall <william@osrfoundation.org>

* fix deprecation warnings

Signed-off-by: William Woodall <william@osrfoundation.org>

* use target_compile_features to require c++17 for downstream users of rclcpp

Signed-off-by: William Woodall <william@osrfoundation.org>

* uncrustify

Signed-off-by: William Woodall <william@osrfoundation.org>

* cpplint

Signed-off-by: William Woodall <william@osrfoundation.org>

* use target_compile_features(... cxx_std_17)

Signed-off-by: William Woodall <william@osrfoundation.org>

* Keep both std::shared_ptr<const MessageT> and const std::shared_ptr<const MessageT> & signatures.

The const std::shared_ptr<const MessageT> & signature is being kept because it
can be more flexible and efficient than std::shared_ptr<const MessageT>, but
costs realtively little to support.

The std::shared_ptr<const MessageT> signature is being kept because we want to
avoid deprecating it and causing disruption, and because it is convenient to
write, and in most cases will not materially impact the performance.

Signed-off-by: William Woodall <william@osrfoundation.org>

* defer deprecation of the shared_ptr<MessageT> sub callbacks

Signed-off-by: William Woodall <william@osrfoundation.org>

* fix unused variable warning

Signed-off-by: William Woodall <william@osrfoundation.org>

* small fixups to AnySubscriptionCallback

Signed-off-by: William Woodall <william@osrfoundation.org>

* add check for unset AnySubscriptionCallback in dispatch methods

Signed-off-by: William Woodall <william@osrfoundation.org>

* update dispatch methods to handle all scenarios

Signed-off-by: William Woodall <william@osrfoundation.org>

* updated tests for AnySubscriptionCallback, include full parameterized i/o matrix

Signed-off-by: William Woodall <william@osrfoundation.org>

* fixup test with changed assumption

Signed-off-by: William Woodall <william@osrfoundation.org>

* remove use of std::unary_function, which was removed in c++17

Signed-off-by: William Woodall <william@osrfoundation.org>

* silence c++17 warnings on windows for now

Signed-off-by: William Woodall <william@osrfoundation.org>
2021-04-02 17:30:29 -07:00

96 lines
3.4 KiB
C++

// Copyright 2020 Open Source Robotics Foundation, Inc.
//
// 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 <gtest/gtest.h>
#include <chrono>
#include <memory>
#include "rclcpp/create_subscription.hpp"
#include "rclcpp/node.hpp"
#include "test_msgs/msg/empty.hpp"
#include "test_msgs/msg/empty.h"
using namespace std::chrono_literals;
class TestCreateSubscription : public ::testing::Test
{
public:
void SetUp() override
{
rclcpp::init(0, nullptr);
}
void TearDown() override
{
rclcpp::shutdown();
}
};
TEST_F(TestCreateSubscription, create) {
auto node = std::make_shared<rclcpp::Node>("my_node", "/ns");
const rclcpp::QoS qos(10);
auto options = rclcpp::SubscriptionOptions();
auto callback = [](test_msgs::msg::Empty::ConstSharedPtr) {};
auto subscription =
rclcpp::create_subscription<test_msgs::msg::Empty>(node, "topic_name", qos, callback, options);
ASSERT_NE(nullptr, subscription);
EXPECT_STREQ("/ns/topic_name", subscription->get_topic_name());
}
TEST_F(TestCreateSubscription, create_with_overriding_options) {
auto node = std::make_shared<rclcpp::Node>("my_node", "/ns");
const rclcpp::QoS qos(10);
auto options = rclcpp::SubscriptionOptions();
options.qos_overriding_options = rclcpp::QosOverridingOptions::with_default_policies();
auto callback = [](test_msgs::msg::Empty::ConstSharedPtr) {};
auto subscription =
rclcpp::create_subscription<test_msgs::msg::Empty>(node, "topic_name", qos, callback, options);
ASSERT_NE(nullptr, subscription);
EXPECT_STREQ("/ns/topic_name", subscription->get_topic_name());
}
TEST_F(TestCreateSubscription, create_separated_node_topics_and_parameters) {
auto node = std::make_shared<rclcpp::Node>("my_node", "/ns");
const rclcpp::QoS qos(10);
auto options = rclcpp::SubscriptionOptions();
auto callback = [](test_msgs::msg::Empty::ConstSharedPtr) {};
auto node_parameters = node->get_node_parameters_interface();
auto node_topics = node->get_node_topics_interface();
auto subscription = rclcpp::create_subscription<test_msgs::msg::Empty>(
node_parameters, node_topics, "topic_name", qos, callback, options);
ASSERT_NE(nullptr, subscription);
EXPECT_STREQ("/ns/topic_name", subscription->get_topic_name());
}
TEST_F(TestCreateSubscription, create_with_statistics) {
auto node = std::make_shared<rclcpp::Node>("my_node", "/ns");
const rclcpp::QoS qos(10);
auto options = rclcpp::SubscriptionOptions();
options.topic_stats_options.state = rclcpp::TopicStatisticsState::Enable;
options.topic_stats_options.publish_topic = "topic_statistics";
options.topic_stats_options.publish_period = 5min;
auto callback = [](test_msgs::msg::Empty::ConstSharedPtr) {};
auto subscription =
rclcpp::create_subscription<test_msgs::msg::Empty>(node, "topic_name", qos, callback, options);
ASSERT_NE(nullptr, subscription);
EXPECT_STREQ("/ns/topic_name", subscription->get_topic_name());
}