@@ -68,44 +68,74 @@ CallbackGroup::size() const
6868 waitable_ptrs_.size ();
6969}
7070
71- namespace
72- {
73- // / Iterate a vector of weak pointers, call func for each live entry,
74- // / and compact expired entries out of the vector in a single pass.
75- template <typename T, typename Func>
76- void collect_and_compact (
77- std::vector<typename T::WeakPtr> & ptrs,
78- const Func & func)
79- {
80- size_t write_idx = 0 ;
81- for (size_t read_idx = 0 ; read_idx < ptrs.size (); ++read_idx) {
82- auto ref_ptr = ptrs[read_idx].lock ();
83- if (ref_ptr) {
84- func (ref_ptr);
85- if (write_idx != read_idx) {
86- ptrs[write_idx] = std::move (ptrs[read_idx]);
87- }
88- ++write_idx;
89- }
90- }
91- ptrs.resize (write_idx);
92- }
93- } // namespace
94-
9571void CallbackGroup::collect_all_ptrs (
9672 const std::function<void (const rclcpp::SubscriptionBase::SharedPtr &)> & sub_func,
9773 const std::function<void(const rclcpp::ServiceBase::SharedPtr &)> & service_func,
9874 const std::function<void(const rclcpp::ClientBase::SharedPtr &)> & client_func,
9975 const std::function<void(const rclcpp::TimerBase::SharedPtr &)> & timer_func,
100- const std::function<void(const rclcpp::Waitable::SharedPtr &)> & waitable_func) const
76+ const std::function<void(const rclcpp::Waitable::SharedPtr &)> & waitable_func)
10177{
10278 std::lock_guard<std::mutex> lock (mutex_);
10379
104- collect_and_compact<rclcpp::SubscriptionBase>(subscription_ptrs_, sub_func);
105- collect_and_compact<rclcpp::ServiceBase>(service_ptrs_, service_func);
106- collect_and_compact<rclcpp::ClientBase>(client_ptrs_, client_func);
107- collect_and_compact<rclcpp::TimerBase>(timer_ptrs_, timer_func);
108- collect_and_compact<rclcpp::Waitable>(waitable_ptrs_, waitable_func);
80+ for (const auto & weak_ptr : subscription_ptrs_) {
81+ auto ref_ptr = weak_ptr.lock ();
82+ if (ref_ptr) {
83+ sub_func (ref_ptr);
84+ }
85+ }
86+ subscription_ptrs_.erase (
87+ std::remove_if (
88+ subscription_ptrs_.begin (), subscription_ptrs_.end (),
89+ [](const auto & w) {return w.expired ();}),
90+ subscription_ptrs_.end ());
91+
92+ for (const auto & weak_ptr : service_ptrs_) {
93+ auto ref_ptr = weak_ptr.lock ();
94+ if (ref_ptr) {
95+ service_func (ref_ptr);
96+ }
97+ }
98+ service_ptrs_.erase (
99+ std::remove_if (
100+ service_ptrs_.begin (), service_ptrs_.end (),
101+ [](const auto & w) {return w.expired ();}),
102+ service_ptrs_.end ());
103+
104+ for (const auto & weak_ptr : client_ptrs_) {
105+ auto ref_ptr = weak_ptr.lock ();
106+ if (ref_ptr) {
107+ client_func (ref_ptr);
108+ }
109+ }
110+ client_ptrs_.erase (
111+ std::remove_if (
112+ client_ptrs_.begin (), client_ptrs_.end (),
113+ [](const auto & w) {return w.expired ();}),
114+ client_ptrs_.end ());
115+
116+ for (const auto & weak_ptr : timer_ptrs_) {
117+ auto ref_ptr = weak_ptr.lock ();
118+ if (ref_ptr) {
119+ timer_func (ref_ptr);
120+ }
121+ }
122+ timer_ptrs_.erase (
123+ std::remove_if (
124+ timer_ptrs_.begin (), timer_ptrs_.end (),
125+ [](const auto & w) {return w.expired ();}),
126+ timer_ptrs_.end ());
127+
128+ for (const auto & weak_ptr : waitable_ptrs_) {
129+ auto ref_ptr = weak_ptr.lock ();
130+ if (ref_ptr) {
131+ waitable_func (ref_ptr);
132+ }
133+ }
134+ waitable_ptrs_.erase (
135+ std::remove_if (
136+ waitable_ptrs_.begin (), waitable_ptrs_.end (),
137+ [](const auto & w) {return w.expired ();}),
138+ waitable_ptrs_.end ());
109139}
110140
111141std::atomic_bool &
0 commit comments