ProviderSegmentBase.h
Go to the documentation of this file.
1#pragma once
2
3#include <map>
4#include <string>
5
7
8#include "EntityBase.h"
9#include "detail/AronTyped.h"
11#include "detail/Predictive.h"
14
15namespace armarx::armem::base
16{
17
18 /**
19 * @brief Data of a provider segment containing multiple entities.
20 */
21 template <class _EntityT, class _Derived>
23 public detail::MemoryContainerBase<std::map<std::string, _EntityT>, _Derived>,
24 public detail::AronTyped,
25 public detail::Predictive<_Derived>,
28 public detail::GetFindInstanceMixin<_Derived>,
29 public detail::GetFindSnapshotMixin<_Derived>
30 {
32
33 public:
34 using typename Base::ContainerT;
35 using typename Base::DerivedT;
36
37 using EntityT = _EntityT;
38 using EntitySnapshotT = typename EntityT::EntitySnapshotT;
39 using EntityInstanceT = typename EntitySnapshotT::EntityInstanceT;
40
41 using ChildT = EntityT;
42
61
62
63 public:
67
68 explicit ProviderSegmentBase(const std::string& name,
70 const std::vector<PredictionEngine>& predictionEngines = {}) :
72 {
73 }
74
75 explicit ProviderSegmentBase(const std::string& name,
76 const MemoryID parentID,
78 const std::vector<PredictionEngine>& predictionEngines = {}) :
79 ProviderSegmentBase(parentID.withProviderSegmentName(name), aronType, predictionEngines)
80 {
81 }
82
83 explicit ProviderSegmentBase(const MemoryID id,
85 const std::vector<PredictionEngine>& predictionEngines = {}) :
87 {
88 }
89
94
95 // READ ACCESS
96
97 // Get key
98 inline std::string&
100 {
101 return this->id().providerSegmentName;
102 }
103
104 inline const std::string&
105 name() const
106 {
107 return this->id().providerSegmentName;
108 }
109
110 // Has child by key
111 bool
112 hasEntity(const std::string& name) const
113 {
114 return this->findEntity(name) != nullptr;
115 }
116
117 // Has child by ID
118 bool
119 hasEntity(const MemoryID& entityID) const
120 {
121 return this->findEntity(entityID) != nullptr;
122 }
123
124 // Find child by key
125 EntityT*
126 findEntity(const std::string& name)
127 {
129 }
130
131 const EntityT*
132 findEntity(const std::string& name) const
133 {
135 }
136
137 // Get child by key
138 EntityT&
139 getEntity(const std::string& name)
140 {
141 return detail::getChildByKey(name, this->_container, *this);
142 }
143
144 const EntityT&
145 getEntity(const std::string& name) const
146 {
147 return detail::getChildByKey(name, this->_container, *this);
148 }
149
150 // Find child by MemoryID
151 EntityT*
152 findEntity(const MemoryID& entityID)
153 {
155 return this->findEntity(entityID.entityName);
156 }
157
158 const EntityT*
159 findEntity(const MemoryID& entityID) const
160 {
162 return this->findEntity(entityID.entityName);
163 }
164
165 // Get child by MemoryID
166 EntityT&
167 getEntity(const MemoryID& entityID)
168 {
170 return this->getEntity(entityID.entityName);
171 }
172
173 const EntityT&
174 getEntity(const MemoryID& entityID) const
175 {
177 return this->getEntity(entityID.entityName);
178 }
179
180 // get/findInstance are provided by GetFindInstanceMixin
181 // get/findSnapshot are provided by GetFindSnapshotMixin
182
183
184 // ITERATION
185
186 // All functors are taken as universal reference (F&&).
187
188 /**
189 * @param func Function like: bool process(EntityT& entity)
190 */
191 template <class EntityFunctionT>
192 bool
193 forEachEntity(EntityFunctionT&& func)
194 {
195 return this->forEachChild(func);
196 }
197
198 /**
199 * @param func Function like: bool process(const EntityT& entity)
200 */
201 template <class EntityFunctionT>
202 bool
203 forEachEntity(EntityFunctionT&& func) const
204 {
205 return this->forEachChild(func);
206 }
207
208 // forEachSnapshot() is provided by ForEachEntitySnapshotMixin
209 // forEachInstance() is provided by ForEachEntityInstanceMixin
210
211 /**
212 * @param func Function like void process(EntityInstanceT& instance)>
213 */
214 template <class InstanceFunctionT>
215 bool
216 forEachInstanceIn(const MemoryID& id, InstanceFunctionT&& func)
217 {
219 func,
220 *this,
221 id.hasEntityName(),
222 id.hasEntityName() ? this->findEntity(id.entityName)
223 : nullptr);
224 }
225
226 /**
227 * @param func Function like void process(EntityInstanceT& instance)>
228 */
229 template <class InstanceFunctionT>
230 bool
231 forEachInstanceIn(const MemoryID& id, InstanceFunctionT&& func) const
232 {
234 func,
235 *this,
236 id.hasEntityName(),
237 id.hasEntityName() ? this->findEntity(id.entityName)
238 : nullptr);
239 }
240
241 // Get child keys
242 std::vector<std::string>
244 {
245 return simox::alg::get_keys(this->_container);
246 }
247
248 // MODIFICATION
249
250 /**
251 * @brief Updates an entity's history.
252 *
253 * Missing entity entries are added before updating.
254 */
255 UpdateResult
257 {
258 this->_checkContainerName(update.entityID.providerSegmentName, this->name());
259
260 EntityT* entity;
262
263 const bool isUpdate = this->hasEntity(update.entityID);
264 if (!isUpdate)
265 {
266 // Add entity entry.
267 entity = &addEntity(update.entityID.entityName);
268 updateType = UpdateType::InsertedNew;
269 }
270 else
271 {
272 entity = &getEntity(update.entityID);
273 updateType = UpdateType::UpdatedExisting;
274 }
275 // Update entity.
276 UpdateResult ret(entity->update(update));
277 ret.providerSegmentUpdateType = updateType;
278 return ret;
279 }
280
281 template <class OtherDerivedT>
282 void
283 append(const OtherDerivedT& other)
284 {
285 other.forEachEntity(
286 [this](const auto& entity)
287 {
288 auto it = this->_container.find(entity.name());
289 if (it == this->_container.end())
290 {
291 it = this->_container
292 .emplace(entity.name(), this->id().withEntityName(entity.name()))
293 .first;
294 }
295 it->second.append(entity);
296 return true;
297 });
298 }
299
300 /// Add an empty entity with the given name.
301 EntityT&
302 addEntity(const std::string& name)
303 {
304 return this->_derived().addEntity(name, name);
305 }
306
307 /// Copy and insert an entity.
308 EntityT&
309 addEntity(const EntityT& entity)
310 {
311 return this->_derived().addEntity(entity.name(), EntityT(entity));
312 }
313
314 /// Move and insert an entity.
315 EntityT&
317 {
318 const std::string name = entity.name(); // Copy before move.
319 return this->_derived().addEntity(name, std::move(entity));
320 }
321
322 /// Insert an entity in-place.
323 template <class... Args>
324 EntityT&
325 addEntity(const std::string& name, Args... args)
326 {
327 ChildT& child = this->template _addChild<ChildT>(name, args...);
328 child.id() = this->id().withEntityName(name);
329 return child;
330 }
331
332 // MISC
333
334 bool
335 equalsDeep(const DerivedT& other) const
336 {
337 if (this->size() != other.size())
338 {
339 return false;
340 }
341 for (const auto& [key, value] : this->_container)
342 {
343 if (not other.hasEntity(key))
344 {
345 return false;
346 }
347
348 if (not value.equalsDeep(other.getEntity(key)))
349 {
350 return false;
351 }
352 }
353 return true;
354 }
355
356 static std::string
358 {
359 return "provider segment";
360 }
361
362 std::string
364 {
365 return this->name();
366 }
367 };
368
369} // namespace armarx::armem::base
constexpr T c
MemoryID withEntityName(const std::string &name) const
Definition MemoryID.cpp:425
std::string entityName
Definition MemoryID.h:53
std::string providerSegmentName
Definition MemoryID.h:52
Data of a provider segment containing multiple entities.
const EntityT * findEntity(const MemoryID &entityID) const
bool hasEntity(const std::string &name) const
typename EntityT::EntitySnapshotT EntitySnapshotT
ProviderSegmentBase(const MemoryID id, aron::type::ObjectPtr aronType=nullptr, const std::vector< PredictionEngine > &predictionEngines={})
bool forEachInstanceIn(const MemoryID &id, InstanceFunctionT &&func)
EntityT & addEntity(const std::string &name, Args... args)
Insert an entity in-place.
const EntityT & getEntity(const std::string &name) const
ProviderSegmentBase(ProviderSegmentBase &&other)=default
EntityT & getEntity(const std::string &name)
EntityT & getEntity(const MemoryID &entityID)
bool equalsDeep(const DerivedT &other) const
bool forEachEntity(EntityFunctionT &&func) const
ProviderSegmentBase(const std::string &name, const MemoryID parentID, aron::type::ObjectPtr aronType=nullptr, const std::vector< PredictionEngine > &predictionEngines={})
EntityT * findEntity(const std::string &name)
std::vector< std::string > getEntityNames() const
EntityT & addEntity(EntityT &&entity)
Move and insert an entity.
const EntityT & getEntity(const MemoryID &entityID) const
bool forEachInstanceIn(const MemoryID &id, InstanceFunctionT &&func) const
EntityT & addEntity(const EntityT &entity)
Copy and insert an entity.
EntityT * findEntity(const MemoryID &entityID)
EntityT & addEntity(const std::string &name)
Add an empty entity with the given name.
void append(const OtherDerivedT &other)
typename EntitySnapshotT::EntityInstanceT EntityInstanceT
bool hasEntity(const MemoryID &entityID) const
ProviderSegmentBase(const ProviderSegmentBase &other)=default
ProviderSegmentBase(const std::string &name, aron::type::ObjectPtr aronType=nullptr, const std::vector< PredictionEngine > &predictionEngines={})
const EntityT * findEntity(const std::string &name) const
UpdateResult update(const EntityUpdate &update)
Updates an entity's history.
ProviderSegmentBase & operator=(const ProviderSegmentBase &other)=default
ProviderSegmentBase & operator=(ProviderSegmentBase &&other)=default
Something with a specific ARON type.
Definition AronTyped.h:12
aron::type::ObjectPtr & aronType()
Definition AronTyped.cpp:19
AronTyped(aron::type::ObjectPtr aronType=nullptr)
Definition AronTyped.cpp:8
Provides default implmentations of MemoryContainer, as well as iterators (which requires a template).
void _checkContainerName(const std::string &gottenName, const std::string &actualName, bool emptyOk=true) const
Something that supports a set of prediction engines.
Definition Predictive.h:38
Predictive(const std::vector< PredictionEngine > &engines={})
Definition Predictive.h:40
const std::vector< PredictionEngine > & predictionEngines() const
Definition Predictive.h:46
auto & getChildByKey(const KeyT &key, ContainerT &&container, const ParentT &owner, KeyStringFn &&keyStringFn)
Retrieve a child in a container by its key.
void checkHasEntityName(const MemoryID &entityID)
Throw armem::error::InvalidMemoryID if the given ID has no entity name.
bool forEachInstanceIn(const MemoryID &id, FunctionT &&func, ParentT &parent, bool single, ChildT *child)
auto * findChildByKey(const KeyT &key, ContainerT &&container)
Find a child in a container by its key.
UpdateType
The type of an update.
Definition Commit.h:17
std::shared_ptr< Object > ObjectPtr
Definition Object.h:36
An update of an entity for a specific point in time.
Definition Commit.h:26
MemoryID entityID
The entity's ID.
Definition Commit.h:28
UpdateResult(const typename EntityT::UpdateResult &c)