1515#ifndef RCLCPP__EXECUTORS__EXECUTOR_ENTITIES_COLLECTION_HPP_
1616#define RCLCPP__EXECUTORS__EXECUTOR_ENTITIES_COLLECTION_HPP_
1717
18+ #include " rclcpp/subscription_base.hpp"
1819#include < deque>
1920#include < unordered_map>
2021#include < vector>
2122
22- #include " rcpputils/thread_safety_annotations.hpp"
23-
2423#include < rclcpp/any_executable.hpp>
2524#include < rclcpp/node_interfaces/node_base.hpp>
2625#include < rclcpp/callback_group.hpp>
@@ -34,45 +33,82 @@ namespace rclcpp
3433namespace executors
3534{
3635
37- struct ExecutorEntitiesCollection
36+ template <typename EntityValueType>
37+ struct CollectionEntry {
38+ typename EntityValueType::WeakPtr entity;
39+ rclcpp::CallbackGroup::WeakPtr callback_group;
40+ };
41+
42+ template <typename CollectionType>
43+ void update_entities (
44+ const CollectionType & update_from,
45+ CollectionType update_to,
46+ std::function<void (typename CollectionType::mapped_type::EntitySharedPtr) > on_added,
47+ std::function<void (typename CollectionType::mapped_type::EntitySharedPtr) > on_removed
48+ )
3849{
39- struct TimerEntry
50+ for (auto it = update_to.begin (); it != update_to.end (); ) {
51+ if (update_from.count (it->first ) == 0 ) {
52+ auto entity = it->second .entity .lock ();
53+ if (entity) {
54+ on_removed (entity);
55+ }
56+ it = update_to.erase (it);
57+ } else {
58+ ++it;
59+ }
60+ }
61+ for (auto it = update_from.begin (); it != update_from.end (); ++it) {
62+ if (update_to.count (it->first ) == 0 ) {
63+ auto entity = it->entity .lock ();
64+ if (entity) {
65+ on_added (entity);
66+ }
67+ update_to.insert (*it);
68+ }
69+ }
70+ }
71+ template <typename EntityKeyType, typename EntityValueType>
72+ class EntityCollection :
73+ public std::unordered_map<const EntityKeyType *, CollectionEntry<EntityValueType>>
74+ {
75+ public:
76+ using Key = const EntityKeyType *;
77+ using EntityWeakPtr = typename EntityValueType::WeakPtr;
78+ using EntitySharedPtr = typename EntityValueType::SharedPtr;
79+
80+ void update (const EntityCollection<EntityKeyType, EntityValueType> & other,
81+ std::function<void (EntitySharedPtr)> on_added,
82+ std::function<void (EntitySharedPtr)> on_removed)
4083 {
41- rclcpp::TimerBase::WeakPtr timer;
42- rclcpp::CallbackGroup::WeakPtr callback_group;
43- };
44- using TimerCollection = std::unordered_map<const rcl_timer_t *, TimerEntry>;
84+ update_entities (*this , other, on_added, on_removed);
85+ }
86+ };
4587
46- struct SubscriptionEntry
47- {
48- rclcpp::SubscriptionBase::WeakPtr subscription;
49- rclcpp::CallbackGroup::WeakPtr callback_group;
50- };
51- using SubscriptionCollection = std::unordered_map<const rcl_subscription_t *, SubscriptionEntry>;
88+ // / Represent the total set of entities for a single executor
89+ /* *
90+ * This allows the entities to be stored from ExecutorEntitiesCollector.
91+ * The structure also makes in convenient to re-evaluate when entities have been added or removed.
92+ */
93+ struct ExecutorEntitiesCollection
94+ {
95+ // / Entity entries for timers
96+ using TimerCollection = EntityCollection<rcl_timer_t , rclcpp::TimerBase>;
5297
53- struct ClientEntry
54- {
55- rclcpp::ClientBase::WeakPtr client;
56- rclcpp::CallbackGroup::WeakPtr callback_group;
57- };
58- using ClientCollection = std::unordered_map<const rcl_client_t *, ClientEntry>;
98+ // / Entity entries for subscriptions
99+ using SubscriptionCollection = EntityCollection<rcl_subscription_t , rclcpp::SubscriptionBase>;
59100
60- struct ServiceEntry
61- {
62- rclcpp::ServiceBase::WeakPtr service;
63- rclcpp::CallbackGroup::WeakPtr callback_group;
64- };
65- using ServiceCollection = std::unordered_map<const rcl_service_t *, ServiceEntry>;
101+ // / Entity entries for clients
102+ using ClientCollection = EntityCollection<rcl_client_t , rclcpp::ClientBase>;
66103
67- struct WaitableEntry
68- {
69- rclcpp::Waitable::WeakPtr waitable;
70- rclcpp::CallbackGroup::WeakPtr callback_group;
71- };
72- using WaitableCollection = std::unordered_map<const rclcpp::Waitable *, WaitableEntry>;
104+ // / Entity entries for services
105+ using ServiceCollection = EntityCollection<rcl_service_t , rclcpp::ServiceBase>;
106+
107+ // / Entity entries for waitables
108+ using WaitableCollection = EntityCollection<rclcpp::Waitable, rclcpp::Waitable>;
73109
74- using GuardConditionCollection = std::unordered_map< const rcl_guard_condition_t *,
75- rclcpp::GuardCondition::WeakPtr >;
110+ // / Entity entries for guard conditions
111+ using GuardConditionCollection = EntityCollection< rcl_guard_condition_t , rclcpp::GuardCondition>;
76112
77113 TimerCollection timers;
78114 SubscriptionCollection subscriptions;
@@ -82,42 +118,6 @@ struct ExecutorEntitiesCollection
82118 WaitableCollection waitables;
83119
84120 void clear ();
85-
86- using TimerUpdatedFunc = std::function<void (rclcpp::TimerBase::SharedPtr)>;
87- void update_timers (
88- const ExecutorEntitiesCollection::TimerCollection & other,
89- TimerUpdatedFunc timer_added,
90- TimerUpdatedFunc timer_removed);
91-
92- using SubscriptionUpdatedFunc = std::function<void (rclcpp::SubscriptionBase::SharedPtr)>;
93- void update_subscriptions (
94- const ExecutorEntitiesCollection::SubscriptionCollection & other,
95- SubscriptionUpdatedFunc subscription_added,
96- SubscriptionUpdatedFunc subscription_removed);
97-
98- using ClientUpdatedFunc = std::function<void (rclcpp::ClientBase::SharedPtr)>;
99- void update_clients (
100- const ExecutorEntitiesCollection::ClientCollection & other,
101- ClientUpdatedFunc client_added,
102- ClientUpdatedFunc client_removed);
103-
104- using ServiceUpdatedFunc = std::function<void (rclcpp::ServiceBase::SharedPtr)>;
105- void update_services (
106- const ExecutorEntitiesCollection::ServiceCollection & other,
107- ServiceUpdatedFunc service_added,
108- ServiceUpdatedFunc service_removed);
109-
110- using GuardConditionUpdatedFunc = std::function<void (rclcpp::GuardCondition::SharedPtr)>;
111- void update_guard_conditions (
112- const ExecutorEntitiesCollection::GuardConditionCollection & other,
113- GuardConditionUpdatedFunc guard_condition_added,
114- GuardConditionUpdatedFunc guard_condition_removed);
115-
116- using WaitableUpdatedFunc = std::function<void (rclcpp::Waitable::SharedPtr)>;
117- void update_waitables (
118- const ExecutorEntitiesCollection::WaitableCollection & other,
119- WaitableUpdatedFunc waitable_added,
120- WaitableUpdatedFunc waitable_removed);
121121};
122122
123123void
0 commit comments