DART 6.7.3
Loading...
Searching...
No Matches
CompositeData.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2019, 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 <Eigen/Core>
37
38#include <map>
39#include <unordered_set>
40#include <typeinfo>
41#include <typeindex>
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>
78{
79 using Type = typename GetAspectImpl<
80 AspectT, std::is_base_of<Aspect, AspectT>::value>::Type;
81};
82
83//==============================================================================
84template <class AspectT>
86{
88};
89
90//==============================================================================
91template <class AspectT>
96
97//==============================================================================
98using CompositeStateMap = std::map< std::type_index, std::unique_ptr<Aspect::State> >;
99using CompositePropertiesMap = std::map< std::type_index, std::unique_ptr<Aspect::Properties> >;
100
101//==============================================================================
102template <typename MapType, template <class> class GetData>
103class CompositeData : public CloneableMap<MapType>
104{
105public:
106
108 template <typename... Args>
109 CompositeData(Args&&... args)
110 : CloneableMap<MapType>(std::forward<Args>(args)...)
111 {
112 // Do nothing
113 }
114
115 virtual ~CompositeData() = default;
116
118 template <class AspectT, typename... Args>
119 typename GetData<AspectT>::Type& create(Args&&... args)
120 {
121 using Data = typename GetData<AspectT>::Type;
122 using AspectType = typename GetAspect<AspectT>::Type;
123 using DataType = typename GetData<Aspect>::Type;
124
125 std::unique_ptr<DataType>& data = this->mMap[typeid(AspectType)]
126 = make_unique<Data>(std::forward<Args>(args)...);
127 return static_cast<Data&>(*data);
128 }
129
130 template <class AspectT>
131 typename GetData<AspectT>::Type* get()
132 {
133 using Data = typename GetData<AspectT>::Type;
134 using AspectType = typename GetAspect<AspectT>::Type;
135
136 typename MapType::iterator it = this->mMap.find(typeid(AspectType));
137 if(this->mMap.end() == it)
138 return nullptr;
139
140 return static_cast<Data*>(it->second.get());
141 }
142
143 template <class AspectT>
144 const typename GetData<AspectT>::Type* get() const
145 {
146 return const_cast<CompositeData<MapType, GetData>*>(this)->get<AspectT>();
147 }
148
149 template <class AspectT, typename... Args>
150 typename GetData<AspectT>::Type& getOrCreate(Args&&... args)
151 {
152 using Data = typename GetData<AspectT>::Type;
153 using AspectType = typename GetAspect<AspectT>::Type;
154
155 auto& it = this->mMap.insert(
156 std::make_pair<std::type_index, std::unique_ptr<Data>>(
157 typeid(AspectType), nullptr));
158
159 const bool exists = !it.second;
160 if(!exists)
161 it.first = make_unique<Data>(std::forward<Args>(args)...);
162
163 return static_cast<Data&>(*it.first);
164 }
165
166 template <class AspectT>
167 bool has() const
168 {
169 return (get<AspectT>() != nullptr);
170 }
171};
172
173//==============================================================================
176
177//==============================================================================
178template <class CompositeType, template<class> class GetData, typename... Aspects>
180{
181public:
182
183 ComposeData() = default;
184
185 ComposeData(const CompositeType&)
186 {
187 // Do nothing
188 }
189
190 virtual ~ComposeData() = default;
191
192 void setFrom(const CompositeType&)
193 {
194 // Do nothing
195 }
196
197protected:
198
199 void _addData(CompositeType&) const
200 {
201 // Do nothing
202 }
203};
204
205//==============================================================================
206template <class CompositeType, template<class> class GetData, class AspectT,
207 typename... Remainder>
208struct ComposeData<CompositeType, GetData, AspectT, Remainder...> :
209 public GetData<AspectT>::Type,
210 public ComposeData<CompositeType, GetData, Remainder...>
211{
212public:
213
214 enum DelegateTag { Delegate };
215
216 using ThisClass = ComposeData<CompositeType, GetData, AspectT, Remainder...>;
217 using Base = typename GetData<AspectT>::Type;
218 using Data = typename Base::Data;
220
221 template <typename Arg>
222 struct ConvertIfData
223 {
224 using Type = typename std::conditional<
225 std::is_base_of<typename Base::Data, Arg>::value,
226 typename Base::Data, Arg>::type;
227 };
228
229 template <typename Arg>
230 struct ConvertIfComposite
231 {
232 using Type = typename std::conditional<
233 std::is_base_of<CompositeType, Arg>::value,
234 CompositeType, Arg>::type;
235 };
236
237 // To get byte-aligned Eigen vectors
238 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
239
241
242 ComposeData() = default;
243
244 virtual ~ComposeData() = default;
245
246 template <typename Arg1, typename... Args>
247 ComposeData(const Arg1& arg1, const Args&... args)
248 : ComposeData(
249 Delegate,
250 static_cast<const typename ConvertIfData<Arg1>::Type&>(arg1),
251 args...)
252 {
253 // This constructor delegates
254 }
255
257 ComposeData(const CompositeType& composite)
258 : ComposeData<CompositeType, GetData, Remainder...>(composite)
259 {
260 _setBaseFrom(composite);
261 }
262
263 template <typename... Aspects>
265 : ComposeData(static_cast<const CompositeType&>(composite))
266 {
267 // This is a delegating constructor. If we get passed another ComposeData
268 // object, then we convert it into a composite to ensure that we grab all
269 // of its aspects.
270 }
271
272 // Dev Note: We must not use the argument 'composite' as a temporary, or else
273 // it will get deleted when it reaches the last base constructor, preventing
274 // any higher level constructors from calling _setBaseFrom(~) on it.
275 ComposeData(CompositeType&& composite)
276 : ComposeData(static_cast<const CompositeType&>(composite))
277 {
278 // This is a delegating constructor
279 }
280
281 operator CompositeType() const
282 {
283 CompositeType composite;
284 _addData(composite);
285
286 return composite;
287 }
288
289 void setFrom(const CompositeType& composite)
290 {
291 _setBaseFrom(composite);
293 }
294
295 ComposeData& operator =(const CompositeType& composite)
296 {
297 setFrom(composite);
298 return *this;
299 }
300
305 template <typename... Args>
306 void copy(const Args&... args)
307 {
308 _findData(args...);
309 }
310
311protected:
312
313 template <typename... Args>
314 ComposeData(DelegateTag, const Args&... args)
315 : ComposeData<CompositeType, GetData, Remainder...>(args...)
316 {
317 // Pass all the arguments along to the next base class
318 }
319
320 template <typename... Args>
321 ComposeData(DelegateTag, const Data& arg1, const Args&... args)
322 : Base(arg1),
323 ComposeData<CompositeType, GetData, Remainder...>(args...)
324 {
325 // Peel off the first argument and then pass along the rest
326 }
327
328 void _setBaseFrom(const CompositeType& composite)
329 {
330 const Base* data = composite.template get<AspectType>();
331 if(data)
332 static_cast<Base&>(*this) = *data;
333 }
334
335 void _addData(CompositeType& composite) const
336 {
337 composite.template create<AspectType>(static_cast<const Base&>(*this));
339 }
340
342 {
343 // Do nothing
344 }
345
346 template <typename Arg1, typename... Args>
347 void _findData(const Arg1& arg1, const Args&... args)
348 {
349 _attemptToUse(static_cast<const typename ConvertIfData<Arg1>::Type&>(arg1));
350 _findData(args...);
351 }
352
353 template <typename Arg>
354 void _attemptToUse(const Arg&)
355 {
356 // Do nothing
357 }
358
359 void _attemptToUse(const typename Base::Data& data)
360 {
361 static_cast<Base&>(*this) = data;
362 }
363
364 void _attemptToUse(const CompositeType& composite)
365 {
366 _setBaseFrom(composite);
367 }
368};
369
370//==============================================================================
371template <typename... Aspects>
373
374template <typename... Data>
377
378} // namespace detail
379} // namespace common
380} // namespace dart
381
382#endif // DART_COMMON_DETAIL_COMPOSITEDATA_HPP_
#define DART_DEFINE_ALIGNED_SHARED_OBJECT_CREATOR(class_name)
Definition Memory.hpp:148
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:224
MapType mMap
A map containing the collection of States for the Aspect.
Definition Cloneable.hpp:285
Definition CompositeData.hpp:180
ComposeData(const CompositeType &)
Definition CompositeData.hpp:185
void _addData(CompositeType &) const
Definition CompositeData.hpp:199
void setFrom(const CompositeType &)
Definition CompositeData.hpp:192
Definition CompositeData.hpp:104
bool has() const
Definition CompositeData.hpp:167
GetData< AspectT >::Type & create(Args &&... args)
Create (or replace) a piece of data in this.
Definition CompositeData.hpp:119
const GetData< AspectT >::Type * get() const
Definition CompositeData.hpp:144
GetData< AspectT >::Type & getOrCreate(Args &&... args)
Definition CompositeData.hpp:150
CompositeData(Args &&... args)
Forwarding constructor.
Definition CompositeData.hpp:109
GetData< AspectT >::Type * get()
Definition CompositeData.hpp:131
CompositeData< CompositeStateMap, GetState > CompositeState
Definition CompositeData.hpp:174
std::map< std::type_index, std::unique_ptr< Aspect::Properties > > CompositePropertiesMap
Definition CompositeData.hpp:99
std::map< std::type_index, std::unique_ptr< Aspect::State > > CompositeStateMap
Definition CompositeData.hpp:98
CompositeData< CompositePropertiesMap, GetProperties > CompositeProperties
Definition CompositeData.hpp:175
Definition BulletCollisionDetector.cpp:63
Definition SharedLibraryManager.hpp:43
typename std::conditional< std::is_base_of< CompositeType, Arg >::value, CompositeType, Arg >::type Type
Definition CompositeData.hpp:234
typename std::conditional< std::is_base_of< typename Base::Data, Arg >::value, typename Base::Data, Arg >::type Type
Definition CompositeData.hpp:226
void _addData(CompositeType &composite) const
Definition CompositeData.hpp:335
typename GetData< AspectT >::Type Base
Definition CompositeData.hpp:217
void _setBaseFrom(const CompositeType &composite)
Definition CompositeData.hpp:328
ComposeData(DelegateTag, const Args &... args)
Definition CompositeData.hpp:314
void copy(const Args &... args)
Grab any relevant data and copy it into this composite.
Definition CompositeData.hpp:306
void _attemptToUse(const CompositeType &composite)
Definition CompositeData.hpp:364
void _findData(const Arg1 &arg1, const Args &... args)
Definition CompositeData.hpp:347
void setFrom(const CompositeType &composite)
Definition CompositeData.hpp:289
ComposeData(DelegateTag, const Data &arg1, const Args &... args)
Definition CompositeData.hpp:321
void _attemptToUse(const typename Base::Data &data)
Definition CompositeData.hpp:359
ComposeData(const ComposeData< CompositeType, GetData, Aspects... > &composite)
Definition CompositeData.hpp:264
ComposeData(CompositeType &&composite)
Definition CompositeData.hpp:275
typename GetAspect< AspectT >::Type AspectType
Definition CompositeData.hpp:219
ComposeData(const CompositeType &composite)
Grab relevant data out of a composite object.
Definition CompositeData.hpp:257
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:80
Definition CompositeData.hpp:93
typename GetAspect< AspectT >::Type::Properties Type
Definition CompositeData.hpp:94
Definition CompositeData.hpp:86
typename GetAspect< AspectT >::Type::State Type
Definition CompositeData.hpp:87