EntitySnapshotBase.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 
7 
8 #include "EntityInstanceBase.h"
11 #include "detail/lookup_mixins.h"
12 
14 {
15  void throwIfNotEqual(const Time& ownTime, const Time& updateTime);
16 }
17 
18 namespace armarx::armem::base
19 {
20  /**
21  * @brief Data of an entity at one point in time.
22  */
23  template <class _EntityInstanceT, class _Derived>
25  public detail::MemoryContainerBase<std::vector<_EntityInstanceT>, _Derived>
26  {
28 
29  public:
30  using typename Base::ContainerT;
31  using typename Base::DerivedT;
32 
33  using EntityInstanceT = _EntityInstanceT;
34 
35 
36  public:
38  {
39  }
40 
41  explicit EntitySnapshotBase(Time time, const MemoryID& parentID = {}) :
42  EntitySnapshotBase(parentID.withTimestamp(time))
43  {
44  }
45 
46  explicit EntitySnapshotBase(const MemoryID& id) : Base(id)
47  {
48  }
49 
50  EntitySnapshotBase(const EntitySnapshotBase& other) = default;
51  EntitySnapshotBase(EntitySnapshotBase&& other) = default;
52  EntitySnapshotBase& operator=(const EntitySnapshotBase& other) = default;
54 
55  // READING
56 
57  // Get key
58  inline Time&
59  time()
60  {
61  return this->id().timestamp;
62  }
63 
64  inline const Time&
65  time() const
66  {
67  return this->id().timestamp;
68  }
69 
70  /// Indicate whether this snapshot has any instances.
71  bool
72  hasInstances() const
73  {
74  return not this->empty();
75  }
76 
77  // Has child by key
78  bool
79  hasInstance(int index) const
80  {
81  return this->findInstance(index) != nullptr;
82  }
83 
84  // Has child by ID
85  bool
86  hasInstance(const MemoryID& instanceID) const
87  {
88  return this->findInstance(instanceID) != nullptr;
89  }
90 
91  // Find child by key
94  {
95  return const_cast<EntityInstanceT*>(
96  const_cast<const EntitySnapshotBase*>(this)->findInstance(index));
97  }
98 
99  const EntityInstanceT*
100  findInstance(int index) const
101  {
102  const size_t si = static_cast<size_t>(index);
103  return (index >= 0 && si < this->_container.size()) ? &this->_container[si] : nullptr;
104  }
105 
106  // Get child by key
107  /**
108  * @brief Get the given instance.
109  * @param index The instance's index.
110  * @return The instance.
111  * @throw `armem::error::MissingEntry` If the given index is invalid.
112  */
115  {
116  return const_cast<EntityInstanceT&>(
117  const_cast<const EntitySnapshotBase*>(this)->getInstance(index));
118  }
119 
120  const EntityInstanceT&
121  getInstance(int index) const
122  {
123  if (const EntityInstanceT* instance = findInstance(index))
124  {
125  return *instance;
126  }
127  else
128  {
129  throw armem::error::MissingEntry::create<EntityInstanceT>(std::to_string(index),
130  *this);
131  }
132  }
133 
134  // Find child by MemoryID
136  findInstance(const MemoryID& instanceID)
137  {
138  detail::checkHasInstanceIndex(instanceID);
139  return this->findInstance(instanceID.instanceIndex);
140  }
141 
142  const EntityInstanceT*
143  findInstance(const MemoryID& instanceID) const
144  {
145  detail::checkHasInstanceIndex(instanceID);
146  return this->findInstance(instanceID.instanceIndex);
147  }
148 
149  // Get child by MemoryID
150  /**
151  * @brief Get the given instance.
152  * @param index The instance's index.
153  * @return The instance.
154  * @throw `armem::error::MissingEntry` If the given index is invalid.
155  * @throw `armem::error::InvalidMemoryID` If memory ID does not have an instance index.
156  */
158  getInstance(const MemoryID& instanceID)
159  {
160  detail::checkHasInstanceIndex(instanceID);
161  return this->getInstance(instanceID.instanceIndex);
162  }
163 
164  const EntityInstanceT&
165  getInstance(const MemoryID& instanceID) const
166  {
167  detail::checkHasInstanceIndex(instanceID);
168  return this->getInstance(instanceID.instanceIndex);
169  }
170 
171  // ITERATION
172 
173  /**
174  * @param func Function like void process(EntityInstanceT& instance)>
175  */
176  template <class InstanceFunctionT>
177  bool
178  forEachInstance(InstanceFunctionT&& func)
179  {
180  return this->forEachChild(func);
181  }
182 
183  /**
184  * @param func Function like void process (const EntityInstanceT& instance)
185  */
186  template <class InstanceFunctionT>
187  bool
188  forEachInstance(InstanceFunctionT&& func) const
189  {
190  return this->forEachChild(func);
191  }
192 
193  /**
194  * @param func Function like void process(EntityInstanceT& instance)>
195  */
196  template <class InstanceFunctionT>
197  bool
198  forEachInstanceIn(const MemoryID& id, InstanceFunctionT&& func)
199  {
200  if (id.hasInstanceIndex())
201  {
202  EntityInstanceT* child = findInstance(id.instanceIndex);
203  return child ? base::detail::call(func, *child) : true;
204  }
205  else
206  {
207  return this->forEachInstance(func);
208  }
209  }
210 
211  /**
212  * @param func Function like void process (const EntityInstanceT& instance)
213  */
214  template <class InstanceFunctionT>
215  bool
216  forEachInstanceIn(const MemoryID& id, InstanceFunctionT&& func) const
217  {
218  if (id.hasInstanceIndex())
219  {
220  const EntityInstanceT* child = findInstance(id.instanceIndex);
221  return child ? base::detail::call(func, *child) : true;
222  }
223  else
224  {
225  return this->forEachInstance(func);
226  }
227  }
228 
229  // Get child keys
230  std::vector<int>
232  {
233  std::vector<int> indices;
234  indices.reserve(this->size());
235  for (size_t i = 0; i < this->size(); ++i)
236  {
237  indices.push_back(static_cast<int>(i));
238  }
239  return indices;
240  }
241 
242  // MODIFICATION
243 
244  void
246  {
247  detail::throwIfNotEqual(time(), update.referencedTime);
248 
249  this->_container.clear();
250  for (int index = 0; index < int(update.instancesData.size()); ++index)
251  {
252  EntityInstanceT& data = this->_container.emplace_back(index, this->id());
253  data.update(update);
254  }
255  }
256 
257  /**
258  * @brief Add a single instance with data.
259  * @param instance The instance.
260  * @return The stored instance.
261  * @throw `armem::error::InvalidArgument` If the given index is invalid. Must be equal to container.size() or -1 (meaning push_back)
262  */
264  addInstance(const EntityInstanceT& instance)
265  {
266  return addInstance(EntityInstanceT(instance));
267  }
268 
271  {
272  if (instance.index() > 0 && static_cast<size_t>(instance.index()) > this->_container.size())
273  {
275  std::to_string(instance.index()),
276  "EntitySnapshot::addInstance",
277  "Cannot add an EntityInstance because its index is too big.");
278  }
279 
280  int index = instance.index();
281  EntityInstanceT& added = this->_container.emplace_back(std::move(instance));
282 
283  added.id() = this->id().withInstanceIndex(index);
284  return added;
285  }
286 
289  {
290  //ARMARX_INFO << "Trying to add an instance without instance yet generated";
291  int index = static_cast<int>(this->size()); //this is the problem, because instances have names 0 and 11 (I do not know why)
292  EntityInstanceT& added = this->_container.emplace_back(EntityInstanceT());
293  added.id() = this->id().withInstanceIndex(index);
294  return added;
295  }
296 
297  // MISC
298 
299  bool
300  equalsDeep(const DerivedT& other) const
301  {
302  //std::cout << "EntitySnapshot::equalsDeep" << std::endl;
303  if (this->size() != other.size())
304  {
305  return false;
306  }
307  int i = 0;
308  for (const auto& instance : this->_container)
309  {
310  if (not instance.equalsDeep(other.getInstance(i)))
311  {
312  return false;
313  }
314  i++;
315  }
316  return true;
317  }
318 
319  std::string
320  getKeyString() const
321  {
322  return toDateTimeMilliSeconds(this->time());
323  }
324 
325  static std::string
327  {
328  return "entity snapshot";
329  }
330  };
331 
332 } // namespace armarx::armem::base
armarx::armem::base::EntitySnapshotBase::getInstance
const EntityInstanceT & getInstance(int index) const
Definition: EntitySnapshotBase.h:121
armarx::armem::base
Definition: CoreSegmentBase.h:15
armarx::armem::base::detail::MemoryContainerBase< std::vector< _EntityInstanceT >, _Derived >::empty
bool empty() const
Definition: MemoryContainerBase.h:44
armarx::armem::MemoryID::timestamp
Time timestamp
Definition: MemoryID.h:54
armarx::armem::base::EntitySnapshotBase::getInstance
EntityInstanceT & getInstance(int index)
Get the given instance.
Definition: EntitySnapshotBase.h:114
armarx::armem::base::EntitySnapshotBase::getInstance
const EntityInstanceT & getInstance(const MemoryID &instanceID) const
Definition: EntitySnapshotBase.h:165
armarx::armem::error::InvalidArgument
Indicates that an argument was invalid.
Definition: ArMemError.h:27
MemoryContainerBase.h
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::armem::base::EntitySnapshotBase::addInstance
EntityInstanceT & addInstance(const EntityInstanceT &instance)
Add a single instance with data.
Definition: EntitySnapshotBase.h:264
armarx::armem::base::EntitySnapshotBase::forEachInstance
bool forEachInstance(InstanceFunctionT &&func)
Definition: EntitySnapshotBase.h:178
armarx::armem::base::detail::MemoryItem
Base class of memory classes on different levels.
Definition: MemoryItem.h:14
armarx::armem::base::EntitySnapshotBase
Data of an entity at one point in time.
Definition: EntitySnapshotBase.h:24
MemoryID.h
armarx::armem::base::detail::MemoryContainerBase< std::vector< _EntityInstanceT >, _Derived >::forEachChild
bool forEachChild(ChildFunctionT &&func)
Definition: MemoryContainerBase.h:64
EntityInstanceBase.h
armarx::armem::base::detail
Definition: AronTyped.cpp:6
armarx::armem::base::EntitySnapshotBase::getKeyString
std::string getKeyString() const
Definition: EntitySnapshotBase.h:320
armarx::armem::base::EntitySnapshotBase::forEachInstance
bool forEachInstance(InstanceFunctionT &&func) const
Definition: EntitySnapshotBase.h:188
armarx::armem::base::detail::MemoryContainerBase
Provides default implmentations of MemoryContainer, as well as iterators (which requires a template).
Definition: MemoryContainerBase.h:16
armarx::armem::MemoryID::instanceIndex
int instanceIndex
Definition: MemoryID.h:55
armarx::armem::base::EntitySnapshotBase::forEachInstanceIn
bool forEachInstanceIn(const MemoryID &id, InstanceFunctionT &&func)
Definition: EntitySnapshotBase.h:198
lookup_mixins.h
armarx::armem::base::EntitySnapshotBase::equalsDeep
bool equalsDeep(const DerivedT &other) const
Definition: EntitySnapshotBase.h:300
armarx::armem::base::EntitySnapshotBase::findInstance
EntityInstanceT * findInstance(const MemoryID &instanceID)
Definition: EntitySnapshotBase.h:136
armarx::armem::base::EntitySnapshotBase::time
const Time & time() const
Definition: EntitySnapshotBase.h:65
armarx::armem::base::EntitySnapshotBase::forEachInstanceIn
bool forEachInstanceIn(const MemoryID &id, InstanceFunctionT &&func) const
Definition: EntitySnapshotBase.h:216
armarx::armem::base::detail::throwIfNotEqual
void throwIfNotEqual(const Time &ownTime, const Time &updateTime)
Definition: EntitySnapshotBase.cpp:6
armarx::armem::base::detail::MemoryContainerBase< std::vector< _EntityInstanceT >, _Derived >::size
std::size_t size() const
Definition: MemoryContainerBase.h:48
armarx::armem::base::EntitySnapshotBase::hasInstances
bool hasInstances() const
Indicate whether this snapshot has any instances.
Definition: EntitySnapshotBase.h:72
armarx::armem::base::EntitySnapshotBase::hasInstance
bool hasInstance(const MemoryID &instanceID) const
Definition: EntitySnapshotBase.h:86
armarx::armem::base::EntitySnapshotBase::addInstance
EntityInstanceT & addInstance(EntityInstanceT &&instance)
Definition: EntitySnapshotBase.h:270
armarx::armem::base::EntitySnapshotBase::getInstanceIndices
std::vector< int > getInstanceIndices() const
Definition: EntitySnapshotBase.h:231
armarx::armem::MemoryID
A memory ID.
Definition: MemoryID.h:47
pcl::graph::indices
pcl::PointIndices::Ptr indices(const PCG &g)
Retrieve the indices of the points of the point cloud stored in a point cloud graph that actually bel...
Definition: point_cloud_graph.h:737
armarx::armem::toDateTimeMilliSeconds
std::string toDateTimeMilliSeconds(const Time &time, int decimals=6)
Returns timeas e.g.
Definition: Time.cpp:35
armarx::armem::base::EntitySnapshotBase::EntitySnapshotBase
EntitySnapshotBase()
Definition: EntitySnapshotBase.h:37
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::armem::base::EntitySnapshotBase::EntitySnapshotBase
EntitySnapshotBase(Time time, const MemoryID &parentID={})
Definition: EntitySnapshotBase.h:41
armarx::armem::base::EntitySnapshotBase::operator=
EntitySnapshotBase & operator=(const EntitySnapshotBase &other)=default
armarx::armem::EntityUpdate
An update of an entity for a specific point in time.
Definition: Commit.h:27
armarx::armem::base::EntitySnapshotBase::findInstance
const EntityInstanceT * findInstance(const MemoryID &instanceID) const
Definition: EntitySnapshotBase.h:143
iteration_mixins.h
armarx::armem::base::detail::MemoryContainerBase< std::vector< _EntityInstanceT >, _Derived >::DerivedT
_Derived DerivedT
Definition: MemoryContainerBase.h:23
armarx::armem::base::detail::MemoryItem::id
MemoryID & id()
Definition: MemoryItem.h:27
armarx::armem::base::detail::checkHasInstanceIndex
void checkHasInstanceIndex(const MemoryID &instanceID)
Throw armem::error::InvalidMemoryID if the given ID has no instance index.
Definition: lookup_mixins.cpp:9
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::armem::base::detail::MemoryContainerBase< std::vector< _EntityInstanceT >, _Derived >::ContainerT
std::vector< _EntityInstanceT > ContainerT
Definition: MemoryContainerBase.h:24
armarx::armem::base::EntitySnapshotBase::getLevelName
static std::string getLevelName()
Definition: EntitySnapshotBase.h:326
armarx::core::time::DateTime
Represents a point in time.
Definition: DateTime.h:24
armarx::armem::base::EntitySnapshotBase::hasInstance
bool hasInstance(int index) const
Definition: EntitySnapshotBase.h:79
armarx::armem::base::EntitySnapshotBase::time
Time & time()
Definition: EntitySnapshotBase.h:59
armarx::armem::base::EntitySnapshotBase::update
void update(const EntityUpdate &update)
Definition: EntitySnapshotBase.h:245
Time.h
armarx::armem::base::EntitySnapshotBase::findInstance
const EntityInstanceT * findInstance(int index) const
Definition: EntitySnapshotBase.h:100
armarx::armem::base::EntitySnapshotBase< EntityInstance, EntitySnapshot >::EntityInstanceT
EntityInstance EntityInstanceT
Definition: EntitySnapshotBase.h:33
armarx::armem::base::detail::call
bool call(FunctionT &&func, ChildT &&child)
Definition: iteration_mixins.h:39
armarx::armem::base::EntitySnapshotBase::getInstance
EntityInstanceT & getInstance(const MemoryID &instanceID)
Get the given instance.
Definition: EntitySnapshotBase.h:158
armarx::armem::MemoryID::withInstanceIndex
MemoryID withInstanceIndex(int index) const
Definition: MemoryID.cpp:436
armarx::armem::base::EntitySnapshotBase::addInstance
EntityInstanceT & addInstance()
Definition: EntitySnapshotBase.h:288
armarx::armem::base::detail::MemoryContainerBase< std::vector< _EntityInstanceT >, _Derived >::_container
ContainerT _container
Definition: MemoryContainerBase.h:150
armarx::armem::base::EntitySnapshotBase::EntitySnapshotBase
EntitySnapshotBase(const MemoryID &id)
Definition: EntitySnapshotBase.h:46
armarx::armem::base::EntitySnapshotBase::findInstance
EntityInstanceT * findInstance(int index)
Definition: EntitySnapshotBase.h:93