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
15
16// std
17#include <list>
18
19namespace sen
20{
21
24
27template <typename T>
29{
30public:
31 SEN_MOVE_ONLY(ObjectList)
32
33 static constexpr std::size_t defaultListSizeHint = 10U;
34
35public: // types
42
43 using TypedObjectList = std::list<T*>;
44 using UntypedObjectList = std::list<std::shared_ptr<Object>>;
45
46 struct Iterators
47 {
48 typename TypedObjectList::iterator typedBegin;
49 typename TypedObjectList::iterator typedEnd;
50 typename UntypedObjectList::iterator untypedBegin;
51 typename UntypedObjectList::iterator untypedEnd;
52 };
53
54 using Callback = std::function<void(const Iterators& iterators)>;
55
56public: // special members
60 explicit ObjectList(std::size_t sizeHint = defaultListSizeHint) { iteratorMap_.reserve(sizeHint); }
61
63 ObjectList(ObjectProvider& provider, std::size_t sizeHint): ObjectList(sizeHint) { provider.addListener(this, true); }
64
65 ~ObjectList() override = default;
66
67public:
71 [[nodiscard]] Callback onAdded(Callback&& function) noexcept;
72
76 [[nodiscard]] Callback onRemoved(Callback&& function) noexcept
77 {
78 return std::exchange(onRemoved_, std::move(function));
79 }
80
81public: // multiple object lookup
83 [[nodiscard]] const std::list<T*>& getObjects() const noexcept { return typedObjects_; }
84
86 [[nodiscard]] const std::list<std::shared_ptr<Object>>& getUntypedObjects() const noexcept { return untypedObjects_; }
87
88protected: // implements ObjectProviderListener
89 void onObjectsAdded(const ObjectAdditionList& additions) override;
90 void onObjectsRemoved(const ObjectRemovalList& removals) override;
91
92private:
93 [[nodiscard]] T* getCastedObject(Object* object);
94
95private:
96 struct IteratorPair
97 {
98 typename TypedObjectList::const_iterator typed;
99 typename UntypedObjectList::const_iterator untyped;
100 };
101
102private:
103 TypedObjectList typedObjects_;
104 UntypedObjectList untypedObjects_;
105 std::unordered_map<ObjectId, IteratorPair> iteratorMap_;
106 Callback onAdded_ = nullptr;
107 Callback onRemoved_ = nullptr;
108};
109
111
112//----------------------------------------------------------------------------------------------------------------------
113// Inline implementation
114//----------------------------------------------------------------------------------------------------------------------
115
116template <typename T>
117inline typename ObjectList<T>::Callback ObjectList<T>::onAdded(Callback&& function) noexcept
118{
119 auto previous = std::exchange(onAdded_, std::move(function));
120
121 if (onAdded_ && !untypedObjects_.empty())
122 {
123 onAdded_({typedObjects_.begin(), typedObjects_.end(), untypedObjects_.begin(), untypedObjects_.end()});
124 }
125
126 return previous;
127}
128
129template <typename T>
130inline T* ObjectList<T>::getCastedObject(Object* object)
131{
132 if constexpr (!std::is_same_v<T, Object>)
133 {
134 if (object == nullptr)
135 {
136 throwRuntimeError("Attempted to cast a null sen::Object pointer");
137 }
138
139 auto* castedObject = dynamic_cast<T*>(object);
140 if (castedObject == nullptr)
141 {
142 std::string err;
143 err.append("error casting object named '");
144 err.append(object->getName());
145 err.append("' of class '");
146 err.append(object->getClass()->getQualifiedName());
147 err.append("' to a native type '");
148 err.append(typeid(T).name());
149 err.append("' within an ObjectList");
151 }
152
153 return castedObject;
154 }
155 else
156 {
157 return object;
158 }
159}
160
161template <typename T>
163{
164 Iterators iterators;
165 bool added = false;
166
167 for (const auto& addition: additions)
168 {
169 // only react to discovered instances
170 auto* instance = getObjectInstance(addition);
171 if (instance == nullptr)
172 {
173 continue;
174 }
175
176 auto castedObject = getCastedObject(instance);
177 auto lastTyped = typedObjects_.insert(typedObjects_.end(), castedObject);
178 auto lastUntyped = untypedObjects_.insert(untypedObjects_.end(), instance->shared_from_this());
179
180 if (!added)
181 {
182 iterators.untypedBegin = lastUntyped;
183 iterators.typedBegin = lastTyped;
184 added = true;
185 }
186
187 // store the object
188 iteratorMap_.insert({instance->getId(), {lastTyped, lastUntyped}});
189 }
190
191 if (!added)
192 {
193 return;
194 }
195
196 if (onAdded_)
197 {
198 iterators.typedEnd = typedObjects_.end();
199 iterators.untypedEnd = untypedObjects_.end();
200 onAdded_(iterators);
201 }
202}
203
204template <typename T>
206{
207 TypedObjectList typedRemovals;
208 UntypedObjectList untypedRemovals;
209
210 for (const auto& removal: removals)
211 {
212 auto itr = iteratorMap_.find(removal.objectid);
213 if (itr != iteratorMap_.end())
214 {
215 auto castedObject = *(itr->second.typed);
216 auto nonCastedObject = *(itr->second.untyped);
217
218 untypedObjects_.erase(itr->second.untyped);
219 typedObjects_.erase(itr->second.typed);
220 iteratorMap_.erase(itr);
221
222 if (onRemoved_)
223 {
224 typedRemovals.push_back(castedObject);
225 untypedRemovals.push_back(nonCastedObject);
226 }
227 }
228 }
229
230 if (onRemoved_)
231 {
232 Iterators iterators;
233 iterators.typedBegin = typedRemovals.begin();
234 iterators.typedEnd = typedRemovals.end();
235 iterators.untypedBegin = untypedRemovals.begin();
236 iterators.untypedEnd = untypedRemovals.end();
237
238 onRemoved_(iterators);
239 }
240}
241
242} // namespace sen
243
244#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.
TypedObjectList::iterator typedBegin
Definition object_list.h:48
std::list< T * > TypedObjectList
Definition object_list.h:43
SearchMode
How to search for objects.
Definition object_list.h:38
@ ignoreSubClasses
Definition object_list.h:40
@ includeSubClasses
Definition object_list.h:39
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:117
const std::list< T * > & getObjects() const noexcept
Gets the list of currently-registered objects.
Definition object_list.h:83
static constexpr std::size_t defaultListSizeHint
Definition object_list.h:33
ObjectList(ObjectProvider &provider, std::size_t sizeHint)
Automatically adds itself as a listener to the provider.
Definition object_list.h:63
UntypedObjectList::iterator untypedEnd
Definition object_list.h:51
std::list< std::shared_ptr< Object > > UntypedObjectList
Definition object_list.h:44
std::function< void(const Iterators &iterators)> Callback
Definition object_list.h:54
void onObjectsRemoved(const ObjectRemovalList &removals) override
Called when objects will be removed from a source.
Definition object_list.h:205
const std::list< std::shared_ptr< Object > > & getUntypedObjects() const noexcept
Gets the list of currently-registered objects.
Definition object_list.h:86
UntypedObjectList::iterator untypedBegin
Definition object_list.h:50
void onObjectsAdded(const ObjectAdditionList &additions) override
Called when objects are been added to a source.
Definition object_list.h:162
~ObjectList() override=default
TypedObjectList::iterator typedEnd
Definition object_list.h:49
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:60
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:76
Definition object_list.h:47
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
Definition assert.h:17
STL namespace.