15 #ifndef RCLCPP__WAIT_RESULT_HPP_
16 #define RCLCPP__WAIT_RESULT_HPP_
26 #include "rclcpp/macros.hpp"
27 #include "rclcpp/wait_result_kind.hpp"
29 #include "rclcpp/client.hpp"
30 #include "rclcpp/service.hpp"
31 #include "rclcpp/subscription_base.hpp"
32 #include "rclcpp/timer.hpp"
60 template<
class WaitSetT>
74 return WaitResult(WaitResultKind::Ready, wait_set);
97 return wait_result_kind_;
108 if (this->
kind() != WaitResultKind::Ready) {
109 throw std::runtime_error(
"cannot access wait set when the result was not ready");
112 assert(wait_set_pointer_);
113 return *wait_set_pointer_;
124 if (this->
kind() != WaitResultKind::Ready) {
125 throw std::runtime_error(
"cannot access wait set when the result was not ready");
128 assert(wait_set_pointer_);
129 return *wait_set_pointer_;
133 : wait_result_kind_(other.wait_result_kind_),
134 wait_set_pointer_(std::exchange(other.wait_set_pointer_,
nullptr))
139 if (wait_set_pointer_) {
140 wait_set_pointer_->wait_result_release();
166 std::pair<std::shared_ptr<rclcpp::TimerBase>,
size_t>
169 check_wait_result_dirty();
170 auto ret = std::shared_ptr<rclcpp::TimerBase>{
nullptr};
171 size_t ii = start_index;
172 if (this->
kind() == WaitResultKind::Ready) {
174 auto & rcl_wait_set = wait_set.storage_get_rcl_wait_set();
175 for (; ii < wait_set.size_of_timers(); ++ii) {
176 if (rcl_wait_set.timers[ii] !=
nullptr) {
177 ret = wait_set.timers(ii);
201 auto & rcl_wait_set = wait_set.storage_get_rcl_wait_set();
202 if (index >= wait_set.size_of_timers()) {
203 throw std::out_of_range(
"given timer index is out of range");
205 rcl_wait_set.timers[index] =
nullptr;
209 std::shared_ptr<rclcpp::SubscriptionBase>
212 check_wait_result_dirty();
213 auto ret = std::shared_ptr<rclcpp::SubscriptionBase>{
nullptr};
214 if (this->
kind() == WaitResultKind::Ready) {
216 auto & rcl_wait_set = wait_set.storage_get_rcl_wait_set();
217 for (
size_t ii = 0; ii < wait_set.size_of_subscriptions(); ++ii) {
218 if (rcl_wait_set.subscriptions[ii] !=
nullptr) {
219 ret = wait_set.subscriptions(ii);
220 rcl_wait_set.subscriptions[ii] =
nullptr;
231 std::shared_ptr<rclcpp::ServiceBase>
234 check_wait_result_dirty();
235 auto ret = std::shared_ptr<rclcpp::ServiceBase>{
nullptr};
236 if (this->
kind() == WaitResultKind::Ready) {
238 auto & rcl_wait_set = wait_set.storage_get_rcl_wait_set();
239 for (
size_t ii = 0; ii < wait_set.size_of_services(); ++ii) {
240 if (rcl_wait_set.services[ii] !=
nullptr) {
241 ret = wait_set.services(ii);
242 rcl_wait_set.services[ii] =
nullptr;
253 std::shared_ptr<rclcpp::ClientBase>
256 check_wait_result_dirty();
257 auto ret = std::shared_ptr<rclcpp::ClientBase>{
nullptr};
258 if (this->
kind() == WaitResultKind::Ready) {
260 auto & rcl_wait_set = wait_set.storage_get_rcl_wait_set();
261 for (
size_t ii = 0; ii < wait_set.size_of_clients(); ++ii) {
262 if (rcl_wait_set.clients[ii] !=
nullptr) {
263 ret = wait_set.clients(ii);
264 rcl_wait_set.clients[ii] =
nullptr;
275 std::shared_ptr<rclcpp::Waitable>
278 check_wait_result_dirty();
279 auto waitable = std::shared_ptr<rclcpp::Waitable>{
nullptr};
280 auto data = std::shared_ptr<void>{
nullptr};
282 if (this->
kind() == WaitResultKind::Ready) {
284 auto & rcl_wait_set = wait_set.get_rcl_wait_set();
285 while (next_waitable_index_ < wait_set.size_of_waitables()) {
286 auto cur_waitable = wait_set.waitables(next_waitable_index_++);
287 if (cur_waitable !=
nullptr && cur_waitable->is_ready(rcl_wait_set)) {
288 waitable = cur_waitable;
300 explicit WaitResult(WaitResultKind wait_result_kind)
301 : wait_result_kind_(wait_result_kind)
304 assert(WaitResultKind::Ready != wait_result_kind);
307 WaitResult(WaitResultKind wait_result_kind, WaitSetT & wait_set)
308 : wait_result_kind_(wait_result_kind),
309 wait_set_pointer_(&wait_set)
312 assert(WaitResultKind::Ready == wait_result_kind);
319 check_wait_result_dirty()
323 if (wait_set_pointer_ && this->
get_wait_set().wait_result_dirty_) {
324 this->wait_result_kind_ = WaitResultKind::Invalid;
328 WaitResultKind wait_result_kind_;
330 WaitSetT * wait_set_pointer_ =
nullptr;
332 size_t next_waitable_index_ = 0;
Interface for introspecting a wait set after waiting on it.
std::shared_ptr< rclcpp::SubscriptionBase > next_ready_subscription()
Get the next ready subscription, clearing it from the wait result.
std::pair< std::shared_ptr< rclcpp::TimerBase >, size_t > peek_next_ready_timer(size_t start_index=0)
Get the next ready timer and its index in the wait result, but do not clear it.
static WaitResult from_ready_wait_result_kind(WaitSetT &wait_set)
Create WaitResult from a "ready" result.
static WaitResult from_empty_wait_result_kind()
Create WaitResult from a "empty" result.
static WaitResult from_timeout_wait_result_kind()
Create WaitResult from a "timeout" result.
std::shared_ptr< rclcpp::ServiceBase > next_ready_service()
Get the next ready service, clearing it from the wait result.
const WaitSetT & get_wait_set() const
Return the rcl wait set.
WaitResultKind kind() const
Return the kind of the WaitResult.
void clear_timer_with_index(size_t index)
Clear the timer at the given index.
std::shared_ptr< rclcpp::ClientBase > next_ready_client()
Get the next ready client, clearing it from the wait result.
WaitSetT & get_wait_set()
Return the rcl wait set.
std::shared_ptr< rclcpp::Waitable > next_ready_waitable()
Get the next ready waitable, clearing it from the wait result.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.