Sen API
Sen Libraries
Loading...
Searching...
No Matches
object_list.h
Go to the documentation of this file.
1// === object_list.h ===================================================================================================
2// Sen Infrastructure
3// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
4// See the LICENSE.txt file for more information.
5// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
6// =====================================================================================================================
7
8#ifndef SEN_CORE_OBJ_OBJECT_LIST_H
9#define SEN_CORE_OBJ_OBJECT_LIST_H
10
11// sen
16
17// std
18#include <list>
19
20namespace sen
21{
22
25
28template <typename T>
30{
31public:
32 SEN_MOVE_ONLY(ObjectList)
33
34 static constexpr std::size_t defaultListSizeHint = 10U;
35
36public: // types
43
44 using TypedObjectList = std::list<T*>;
45 using UntypedObjectList = std::list<std::shared_ptr<Object>>;
46
47 // Plain aggregate carrying the four range endpoints; the member functions are only
48 // range-for sugar over them, so the public members are the point of the type.
49 // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
50 struct Iterators
51 {
52 typename TypedObjectList::iterator typedBegin;
53 typename TypedObjectList::iterator typedEnd;
54 typename UntypedObjectList::iterator untypedBegin;
55 typename UntypedObjectList::iterator untypedEnd;
56
57 // NOLINTEND(misc-non-private-member-variables-in-classes)
58
60 [[nodiscard]] typename TypedObjectList::iterator begin() const { return typedBegin; }
61 [[nodiscard]] typename TypedObjectList::iterator end() const { return typedEnd; }
62
64 [[nodiscard]] auto untyped() const { return sen::util::makeRange(untypedBegin, untypedEnd); }
65
67 [[nodiscard]] auto typed() const { return sen::util::makeRange(typedBegin, typedEnd); }
68 };
69
70 using Callback = std::function<void(const Iterators& iterators)>;
71
72public: // special members
76 explicit ObjectList(std::size_t sizeHint = defaultListSizeHint) { iteratorMap_.reserve(sizeHint); }
77
79 ObjectList(ObjectProvider& provider, std::size_t sizeHint): ObjectList(sizeHint) { provider.addListener(this, true); }
80
81 ~ObjectList() override = default;
82
83public:
87 [[nodiscard]] Callback onAdded(Callback&& function) noexcept;
88
92 [[nodiscard]] Callback onRemoved(Callback&& function) noexcept
93 {
94 return std::exchange(onRemoved_, std::move(function));
95 }
96
97public: // multiple object lookup
99 [[nodiscard]] const std::list<T*>& getObjects() const noexcept { return typedObjects_; }
100
102 [[nodiscard]] const std::list<std::shared_ptr<Object>>& getUntypedObjects() const noexcept { return untypedObjects_; }
103
104protected: // implements ObjectProviderListener
105 void onObjectsAdded(const ObjectAdditionList& additions) override;
106 void onObjectsRemoved(const ObjectRemovalList& removals) override;
107
108private:
109 [[nodiscard]] T* getCastedObject(Object* object);
110
111private:
112 struct IteratorPair
113 {
114 typename TypedObjectList::const_iterator typed;
115 typename UntypedObjectList::const_iterator untyped;
116 };
117
118private:
119 TypedObjectList typedObjects_;
120 UntypedObjectList untypedObjects_;
121 std::unordered_map<ObjectId, IteratorPair> iteratorMap_;
122 Callback onAdded_ = nullptr;
123 Callback onRemoved_ = nullptr;
124};
125
127
128//----------------------------------------------------------------------------------------------------------------------
129// Inline implementation
130//----------------------------------------------------------------------------------------------------------------------
131
132template <typename T>
133inline typename ObjectList<T>::Callback ObjectList<T>::onAdded(Callback&& function) noexcept
134{
135 auto previous = std::exchange(onAdded_, std::move(function));
136
137 if (onAdded_ && !untypedObjects_.empty())
138 {
139 onAdded_({typedObjects_.begin(), typedObjects_.end(), untypedObjects_.begin(), untypedObjects_.end()});
140 }
141
142 return previous;
143}
144
145template <typename T>
146inline T* ObjectList<T>::getCastedObject(Object* object)
147{
148 if constexpr (!std::is_same_v<T, Object>)
149 {
150 auto* castedObject = dynamic_cast<T*>(object);
151 if (castedObject == nullptr)
152 {
153 std::string err;
154 err.append("error casting object named '");
155 err.append(object->getName());
156 err.append("' of class '");
157 err.append(object->getClass()->getQualifiedName());
158 err.append("' to a native type '");
159 err.append(typeid(T).name());
160 err.append("' within an ObjectList");
162 }
163
164 return castedObject;
165 }
166 else
167 {
168 return object;
169 }
170}
171
172template <typename T>
174{
175 Iterators iterators;
176 bool added = false;
177
178 for (const auto& addition: additions)
179 {
180 // only react to discovered instances
181 auto* instance = getObjectInstance(addition);
182 if (instance == nullptr)
183 {
184 continue;
185 }
186
187 auto castedObject = getCastedObject(instance);
188 auto lastTyped = typedObjects_.insert(typedObjects_.end(), castedObject);
189 auto lastUntyped = untypedObjects_.insert(untypedObjects_.end(), instance->shared_from_this());
190
191 if (!added)
192 {
193 iterators.untypedBegin = lastUntyped;
194 iterators.typedBegin = lastTyped;
195 added = true;
196 }
197
198 // store the object
199 iteratorMap_.insert({instance->getId(), {lastTyped, lastUntyped}});
200 }
201
202 if (!added)
203 {
204 return;
205 }
206
207 if (onAdded_)
208 {
209 iterators.typedEnd = typedObjects_.end();
210 iterators.untypedEnd = untypedObjects_.end();
211 onAdded_(iterators);
212 }
213}
214
215template <typename T>
217{
218 TypedObjectList typedRemovals;
219 UntypedObjectList untypedRemovals;
220
221 for (const auto& removal: removals)
222 {
223 auto itr = iteratorMap_.find(removal.objectid);
224 if (itr != iteratorMap_.end())
225 {
226 auto castedObject = *(itr->second.typed);
227 auto nonCastedObject = *(itr->second.untyped);
228
229 untypedObjects_.erase(itr->second.untyped);
230 typedObjects_.erase(itr->second.typed);
231 iteratorMap_.erase(itr);
232
233 if (onRemoved_)
234 {
235 typedRemovals.push_back(castedObject);
236 untypedRemovals.push_back(nonCastedObject);
237 }
238 }
239 }
240
241 if (onRemoved_ && !typedRemovals.empty())
242 {
243 Iterators iterators;
244 iterators.typedBegin = typedRemovals.begin();
245 iterators.typedEnd = typedRemovals.end();
246 iterators.untypedBegin = untypedRemovals.begin();
247 iterators.untypedEnd = untypedRemovals.end();
248
249 onRemoved_(iterators);
250 }
251}
252
253} // namespace sen
254
255#endif // SEN_CORE_OBJ_OBJECT_LIST_H
The following macros implement a replacement of assert that is connected to the overall fault handlin...
Base class for event or method callbacks. It stores the queue where to push the response....
Definition callback.h:146
A sen object.
Definition object.h:76
virtual const std::string & getName() const noexcept=0
The name given to the object upon construction.
virtual ConstTypeHandle< ClassType > getClass() const noexcept=0
Reflection information.
std::list< T * > TypedObjectList
Definition object_list.h:44
SearchMode
How to search for objects.
Definition object_list.h:39
@ ignoreSubClasses
Definition object_list.h:41
@ includeSubClasses
Definition object_list.h:40
Callback onAdded(Callback &&function) noexcept
Installs a function to be called when objects are added / discovered. This function will be called du...
Definition object_list.h:133
const std::list< T * > & getObjects() const noexcept
Gets the list of currently-registered objects.
Definition object_list.h:99
static constexpr std::size_t defaultListSizeHint
Definition object_list.h:34
ObjectList(ObjectProvider &provider, std::size_t sizeHint)
Automatically adds itself as a listener to the provider.
Definition object_list.h:79
std::list< std::shared_ptr< Object > > UntypedObjectList
Definition object_list.h:45
std::function< void(const Iterators &iterators)> Callback
Definition object_list.h:70
void onObjectsRemoved(const ObjectRemovalList &removals) override
Called when objects will be removed from a source.
Definition object_list.h:216
const std::list< std::shared_ptr< Object > > & getUntypedObjects() const noexcept
Gets the list of currently-registered objects.
Definition object_list.h:102
void onObjectsAdded(const ObjectAdditionList &additions) override
Called when objects are been added to a source.
Definition object_list.h:173
~ObjectList() override=default
ObjectList(std::size_t sizeHint=defaultListSizeHint)
The sizeHint reserves space the internal containers to prevent memory reallocation in the initial ite...
Definition object_list.h:76
Callback onRemoved(Callback &&function) noexcept
Installs a function to be called when objects are added / discovered. This function will be called du...
Definition object_list.h:92
virtual void addListener(ObjectProviderListener *listener, bool notifyAboutExistingObjects)
Registers an event listener.
friend class ObjectProvider
Definition object_provider.h:128
void throwRuntimeError(const std::string &err)
Throws std::exception that attempts to collect the stack trace. We also wrap it to avoid including st...
Object * getObjectInstance(const ObjectAddition &discovery)
Definition object_provider.h:97
std::vector< ObjectAddition > ObjectAdditionList
Sequence of object additions.
Definition object_provider.h:71
std::vector< ObjectRemoval > ObjectRemovalList
Sequence of object removals.
Definition object_provider.h:74
IteratorRange< IteratorType > makeRange(IteratorType begin, IteratorType end)
Create a simple range for the two iterators.
Definition iterator_adapters.h:52
Definition assert.h:17
STL namespace.
Definition object_list.h:51
TypedObjectList::iterator typedBegin
Definition object_list.h:52
UntypedObjectList::iterator untypedEnd
Definition object_list.h:55
auto untyped() const
Range-for support iterates over untyped objects.
Definition object_list.h:64
TypedObjectList::iterator begin() const
Range-for support iterates over typed objects.
Definition object_list.h:60
UntypedObjectList::iterator untypedBegin
Definition object_list.h:54
TypedObjectList::iterator end() const
Definition object_list.h:61
TypedObjectList::iterator typedEnd
Definition object_list.h:53
auto typed() const
Range-for support iterates over untype objects (here for simmetry with untyped()).
Definition object_list.h:67