DART 6.12.2
Loading...
Searching...
No Matches
CompositeData.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2021, The DART development contributors
3 * All rights reserved.
4 *
5 * The list of contributors can be found at:
6 * https://github.com/dartsim/dart/blob/master/LICENSE
7 *
8 * This file is provided under the following "BSD-style" License:
9 * Redistribution and use in source and binary forms, with or
10 * without modification, are permitted provided that the following
11 * conditions are met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef DART_COMMON_DETAIL_COMPOSITEDATA_HPP_
34#define DART_COMMON_DETAIL_COMPOSITEDATA_HPP_
35
36#include <map>
37#include <typeindex>
38#include <typeinfo>
39#include <unordered_set>
40
41#include <Eigen/Core>
42
44
45namespace dart {
46namespace common {
47namespace detail {
48
49//==============================================================================
50// This default template definition will be called when AspectOrComposite is
51// an Aspect.
52template <class AspectOrComposite, bool isAspect>
54{
55 using Type = AspectOrComposite;
56};
57
58//==============================================================================
59// This template specialization will be called when AspectOrComposite is not
60// an Aspect (and is presumably a composite that defines a nested Aspect type).
61template <class AspectOrComposite>
62struct GetAspectImpl<AspectOrComposite, false>
63{
64 // If you get a compiler error that leads you here, then you are trying to
65 // ask for the Aspect of an object that is not associated with any Aspect.
66 // That means it does not define a nested Aspect type (such as how
67 // RevoluteJoint defines the RevoluteJoint::Aspect).
68 //
69 // Whatever function is leading to the error must be given a template type
70 // that either defines a nested type with the name Aspect, or else inherits
71 // from the type dart::common::Aspect.
72 using Type = typename AspectOrComposite::Aspect;
73};
74
75//==============================================================================
76template <class AspectT>
83
84//==============================================================================
85template <class AspectT>
87{
89};
90
91//==============================================================================
92template <class AspectT>
97
98//==============================================================================
100 = std::map<std::type_index, std::unique_ptr<Aspect::State>>;
102 = std::map<std::type_index, std::unique_ptr<Aspect::Properties>>;
103
104//==============================================================================
105template <typename MapType, template <class> class GetData>
106class CompositeData : public CloneableMap<MapType>
107{
108public:
110 template <typename... Args>
111 CompositeData(Args&&... args)
112 : CloneableMap<MapType>(std::forward<Args>(args)...)
113 {
114 // Do nothing
115 }
116
117 virtual ~CompositeData() = default;
118
120 template <class AspectT, typename... Args>
121 typename GetData<AspectT>::Type& create(Args&&... args)
122 {
123 using Data = typename GetData<AspectT>::Type;
124 using AspectType = typename GetAspect<AspectT>::Type;
125 using DataType = typename GetData<Aspect>::Type;
126
127 std::unique_ptr<DataType>& data = this->mMap[typeid(AspectType)]
128 = std::make_unique<Data>(std::forward<Args>(args)...);
129 return static_cast<Data&>(*data);
130 }
131
132 template <class AspectT>
133 typename GetData<AspectT>::Type* get()
134 {
135 using Data = typename GetData<AspectT>::Type;
136 using AspectType = typename GetAspect<AspectT>::Type;
137
138 typename MapType::iterator it = this->mMap.find(typeid(AspectType));
139 if (this->mMap.end() == it)
140 return nullptr;
141
142 return static_cast<Data*>(it->second.get());
143 }
144
145 template <class AspectT>
146 const typename GetData<AspectT>::Type* get() const
147 {
148 return const_cast<CompositeData<MapType, GetData>*>(this)->get<AspectT>();
149 }
150
151 template <class AspectT, typename... Args>
152 typename GetData<AspectT>::Type& getOrCreate(Args&&... args)
153 {
154 using Data = typename GetData<AspectT>::Type;
155 using AspectType = typename GetAspect<AspectT>::Type;
156
157 auto& it = this->mMap.insert(
158 std::make_pair<std::type_index, std::unique_ptr<Data>>(
159 typeid(AspectType), nullptr));
160
161 const bool exists = !it.second;
162 if (!exists)
163 it.first = std::make_unique<Data>(std::forward<Args>(args)...);
164
165 return static_cast<Data&>(*it.first);
166 }
167
168 template <class AspectT>
169 bool has() const
170 {
171 return (get<AspectT>() != nullptr);
172 }
173};
174
175//==============================================================================
179
180//==============================================================================
181template <
182 class CompositeType,
183 template <class>
184 class GetData,
185 typename... Aspects>
187{
188public:
189 ComposeData() = default;
190
191 ComposeData(const CompositeType&)
192 {
193 // Do nothing
194 }
195
196 virtual ~ComposeData() = default;
197
198 void setFrom(const CompositeType&)
199 {
200 // Do nothing
201 }
202
203protected:
204 void _addData(CompositeType&) const
205 {
206 // Do nothing
207 }
208};
209
210//==============================================================================
211template <
212 class CompositeType,
213 template <class>
214 class GetData,
215 class AspectT,
216 typename... Remainder>
217struct ComposeData<CompositeType, GetData, AspectT, Remainder...>
218 : public GetData<AspectT>::Type,
219 public ComposeData<CompositeType, GetData, Remainder...>
220{
221public:
223 {
224 Delegate
225 };
226
227 using ThisClass = ComposeData<CompositeType, GetData, AspectT, Remainder...>;
228 using Base = typename GetData<AspectT>::Type;
229 using Data = typename Base::Data;
231
232 template <typename Arg>
233 struct ConvertIfData
234 {
235 using Type = typename std::conditional<
236 std::is_base_of<typename Base::Data, Arg>::value,
237 typename Base::Data,
238 Arg>::type;
239 };
240
241 template <typename Arg>
242 struct ConvertIfComposite
243 {
244 using Type = typename std::conditional<
245 std::is_base_of<CompositeType, Arg>::value,
246 CompositeType,
247 Arg>::type;
248 };
249
250 // To get byte-aligned Eigen vectors
251 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
252
254
255 ComposeData() = default;
256
257 virtual ~ComposeData() = default;
258
259 template <typename Arg1, typename... Args>
260 ComposeData(const Arg1& arg1, const Args&... args)
261 : ComposeData(
262 Delegate,
263 static_cast<const typename ConvertIfData<Arg1>::Type&>(arg1),
264 args...)
265 {
266 // This constructor delegates
267 }
268
270 ComposeData(const CompositeType& composite)
271 : ComposeData<CompositeType, GetData, Remainder...>(composite)
272 {
273 _setBaseFrom(composite);
274 }
275
276 template <typename... Aspects>
278 : ComposeData(static_cast<const CompositeType&>(composite))
279 {
280 // This is a delegating constructor. If we get passed another ComposeData
281 // object, then we convert it into a composite to ensure that we grab all
282 // of its aspects.
283 }
284
285 // Dev Note: We must not use the argument 'composite' as a temporary, or else
286 // it will get deleted when it reaches the last base constructor, preventing
287 // any higher level constructors from calling _setBaseFrom(~) on it.
288 ComposeData(CompositeType&& composite)
289 : ComposeData(static_cast<const CompositeType&>(composite))
290 {
291 // This is a delegating constructor
292 }
293
294 operator CompositeType() const
295 {
296 CompositeType composite;
297 _addData(composite);
298
299 return composite;
300 }
301
302 void setFrom(const CompositeType& composite)
303 {
304 _setBaseFrom(composite);
306 }
307
308 ComposeData& operator=(const CompositeType& composite)
309 {
310 setFrom(composite);
311 return *this;
312 }
313
318 template <typename... Args>
319 void copy(const Args&... args)
320 {
321 _findData(args...);
322 }
323
324protected:
325 template <typename... Args>
326 ComposeData(DelegateTag, const Args&... args)
327 : ComposeData<CompositeType, GetData, Remainder...>(args...)
328 {
329 // Pass all the arguments along to the next base class
330 }
331
332 template <typename... Args>
333 ComposeData(DelegateTag, const Data& arg1, const Args&... args)
334 : Base(arg1), ComposeData<CompositeType, GetData, Remainder...>(args...)
335 {
336 // Peel off the first argument and then pass along the rest
337 }
338
339 void _setBaseFrom(const CompositeType& composite)
340 {
341 const Base* data = composite.template get<AspectType>();
342 if (data)
343 static_cast<Base&>(*this) = *data;
344 }
345
346 void _addData(CompositeType& composite) const
347 {
348 composite.template create<AspectType>(static_cast<const Base&>(*this));
350 }
351
353 {
354 // Do nothing
355 }
356
357 template <typename Arg1, typename... Args>
358 void _findData(const Arg1& arg1, const Args&... args)
359 {
360 _attemptToUse(static_cast<const typename ConvertIfData<Arg1>::Type&>(arg1));
361 _findData(args...);
362 }
363
364 template <typename Arg>
365 void _attemptToUse(const Arg&)
366 {
367 // Do nothing
368 }
369
370 void _attemptToUse(const typename Base::Data& data)
371 {
372 static_cast<Base&>(*this) = data;
373 }
374
375 void _attemptToUse(const CompositeType& composite)
376 {
377 _setBaseFrom(composite);
378 }
379};
380
381//==============================================================================
382template <typename... Aspects>
384
385template <typename... Data>
388
389} // namespace detail
390} // namespace common
391} // namespace dart
392
393#endif // DART_COMMON_DETAIL_COMPOSITEDATA_HPP_
#define DART_DEFINE_ALIGNED_SHARED_OBJECT_CREATOR(class_name)
Definition Memory.hpp:153
std::string type
Definition SdfParser.cpp:82
MapHolder is a templated wrapper class that is used to allow maps of Aspect::State and Aspect::Proper...
Definition Cloneable.hpp:221
MapType mMap
A map containing the collection of States for the Aspect.
Definition Cloneable.hpp:280
Definition CompositeData.hpp:187
ComposeData(const CompositeType &)
Definition CompositeData.hpp:191
void _addData(CompositeType &) const
Definition CompositeData.hpp:204
void setFrom(const CompositeType &)
Definition CompositeData.hpp:198
Definition CompositeData.hpp:107
bool has() const
Definition CompositeData.hpp:169
GetData< AspectT >::Type & create(Args &&... args)
Create (or replace) a piece of data in this.
Definition CompositeData.hpp:121
const GetData< AspectT >::Type * get() const
Definition CompositeData.hpp:146
GetData< AspectT >::Type & getOrCreate(Args &&... args)
Definition CompositeData.hpp:152
CompositeData(Args &&... args)
Forwarding constructor.
Definition CompositeData.hpp:111
GetData< AspectT >::Type * get()
Definition CompositeData.hpp:133
CompositeData< CompositeStateMap, GetState > CompositeState
Definition CompositeData.hpp:176
std::map< std::type_index, std::unique_ptr< Aspect::State > > CompositeStateMap
Definition CompositeData.hpp:100
std::map< std::type_index, std::unique_ptr< Aspect::Properties > > CompositePropertiesMap
Definition CompositeData.hpp:102
CompositeData< CompositePropertiesMap, GetProperties > CompositeProperties
Definition CompositeData.hpp:178
Definition BulletCollisionDetector.cpp:60
Definition SharedLibraryManager.hpp:46
typename std::conditional< std::is_base_of< CompositeType, Arg >::value, CompositeType, Arg >::type Type
Definition CompositeData.hpp:247
typename std::conditional< std::is_base_of< typename Base::Data, Arg >::value, typename Base::Data, Arg >::type Type
Definition CompositeData.hpp:238
ComposeData & operator=(const CompositeType &composite)
Definition CompositeData.hpp:308
void _addData(CompositeType &composite) const
Definition CompositeData.hpp:346
typename GetData< AspectT >::Type Base
Definition CompositeData.hpp:228
void _setBaseFrom(const CompositeType &composite)
Definition CompositeData.hpp:339
ComposeData(DelegateTag, const Args &... args)
Definition CompositeData.hpp:326
void copy(const Args &... args)
Grab any relevant data and copy it into this composite.
Definition CompositeData.hpp:319
void _attemptToUse(const CompositeType &composite)
Definition CompositeData.hpp:375
void _findData(const Arg1 &arg1, const Args &... args)
Definition CompositeData.hpp:358
void setFrom(const CompositeType &composite)
Definition CompositeData.hpp:302
ComposeData(DelegateTag, const Data &arg1, const Args &... args)
Definition CompositeData.hpp:333
void _attemptToUse(const typename Base::Data &data)
Definition CompositeData.hpp:370
ComposeData(const ComposeData< CompositeType, GetData, Aspects... > &composite)
Definition CompositeData.hpp:277
ComposeData(CompositeType &&composite)
Definition CompositeData.hpp:288
typename GetAspect< AspectT >::Type AspectType
Definition CompositeData.hpp:230
ComposeData(const CompositeType &composite)
Grab relevant data out of a composite object.
Definition CompositeData.hpp:270
typename AspectOrComposite::Aspect Type
Definition CompositeData.hpp:72
Definition CompositeData.hpp:54
AspectOrComposite Type
Definition CompositeData.hpp:55
Definition CompositeData.hpp:78
typename GetAspectImpl< AspectT, std::is_base_of< Aspect, AspectT >::value >::Type Type
Definition CompositeData.hpp:81
Definition CompositeData.hpp:94
typename GetAspect< AspectT >::Type::Properties Type
Definition CompositeData.hpp:95
Definition CompositeData.hpp:87
typename GetAspect< AspectT >::Type::State Type
Definition CompositeData.hpp:88