DART 6.10.1
Loading...
Searching...
No Matches
EmbeddedAspect.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_EMBEDDEDASPECT_HPP_
34#define DART_COMMON_DETAIL_EMBEDDEDASPECT_HPP_
35
38
39namespace dart {
40namespace common {
41namespace detail {
42
43//==============================================================================
44template <class AspectT, typename StateT>
45void DefaultSetEmbeddedState(AspectT* aspect, const StateT& state)
46{
47 aspect->getComposite()->setAspectState(state);
48}
49
50//==============================================================================
51template <class AspectT, typename StateT>
52const StateT& DefaultGetEmbeddedState(const AspectT* aspect)
53{
54 return aspect->getComposite()->getAspectState();
55}
56
57//==============================================================================
58template <class AspectT, typename PropertiesT>
60 AspectT* aspect, const PropertiesT& properties)
61{
62 aspect->getComposite()->setAspectProperties(properties);
63}
64
65//==============================================================================
66template <class AspectT, typename PropertiesT>
67const PropertiesT& DefaultGetEmbeddedProperties(const AspectT* aspect)
68{
69 return aspect->getComposite()->getAspectProperties();
70}
71
72//==============================================================================
73template <
74 class BaseT,
75 class DerivedT,
76 typename StateDataT,
78 void (*setEmbeddedState)(DerivedT*, const StateT&)
79 = &DefaultSetEmbeddedState<DerivedT, StateT>,
80 const StateT& (*getEmbeddedState)(const DerivedT*)
81 = &DefaultGetEmbeddedState<DerivedT, StateT> >
82class EmbeddedStateAspect : public BaseT
83{
84public:
85 using Base = BaseT;
86 using Derived = DerivedT;
87 using State = StateT;
88 using StateData = StateDataT;
89 constexpr static void (*SetEmbeddedState)(Derived*, const State&)
90 = setEmbeddedState;
91 constexpr static const State& (*GetEmbeddedState)(const Derived*)
92 = getEmbeddedState;
93
95 {
96 Delegate
97 };
98
100
101 virtual ~EmbeddedStateAspect() = default;
102
104 template <typename T>
106 {
107 using type = typename std::
108 conditional<std::is_base_of<StateData, T>::value, StateData, T>::type;
109 };
110
113 {
114 // Do nothing
115 }
116
120 //
121 // Dev Note: The complex construction pattern used here allows us to satisfy
122 // three simultaneous design constraints:
123 // 1. We can identify when the user has passed in relevant State information
124 // and capture that information. The type can be of **any** class type
125 // that inherits StateData.
126 // 2. We can ignore any non-State information that the user has passed in,
127 // and move that information along to the Base class.
128 // 3. We can handle arbitrary numbers of arguments of any type to pass along
129 // to the Base class.
130 // If anyone can come up with a cleaner way of accomplishing all three of
131 // these constraints, I would gladly replace this implementation. -(MXG)
132 template <typename T, typename... RemainingArgs>
133 EmbeddedStateAspect(const T& arg1, RemainingArgs&&... remainingArgs)
135 Delegate,
136 static_cast<const typename ConvertIfState<T>::type&>(arg1),
137 std::forward<RemainingArgs>(remainingArgs)...)
138 {
139 // Do nothing
140 }
141
142 // Documentation inherited
143 void setAspectState(const Aspect::State& state) override final
144 {
145 setState(static_cast<const State&>(state));
146 }
147
149 void setState(const State& state)
150 {
151 if (this->hasComposite())
152 {
153 SetEmbeddedState(static_cast<Derived*>(this), state);
154 return;
155 }
156
157 // If the correct type of Composite is not available, we store this on the
158 // heap until this Aspect is moved.
159 mTemporaryState = std::make_unique<State>(state);
160 }
161
162 // Documentation inherited
163 const Aspect::State* getAspectState() const override final
164 {
165 return &getState();
166 }
167
169 const State& getState() const
170 {
171 if (this->hasComposite())
172 {
173 return GetEmbeddedState(static_cast<const Derived*>(this));
174 }
175
176 if (!mTemporaryState)
177 {
178 dterr << "[detail::EmbeddedStateAspect::getState] This Aspect is not in "
179 << "a Composite, but it also does not have a temporary State "
180 << "available. This should not happen! Please report this as a "
181 << "bug!\n";
182 assert(false);
183 }
184
185 return *mTemporaryState;
186 }
187
188 // Documentation inherited
189 std::unique_ptr<Aspect> cloneAspect() const override
190 {
191 return std::make_unique<Derived>(this->getState());
192 }
193
194protected:
197 template <typename... RemainingArgs>
199 DelegateTag, const StateData& state, RemainingArgs&&... remainingArgs)
200 : Base(std::forward<RemainingArgs>(remainingArgs)...),
201 mTemporaryState(std::make_unique<State>(state))
202 {
203 // Do nothing
204 }
205
208 template <typename... BaseArgs>
209 EmbeddedStateAspect(DelegateTag, BaseArgs&&... args)
210 : Base(std::forward<BaseArgs>(args)...)
211 {
212 // Do nothing
213 }
214
216 void setComposite(Composite* newComposite) override
217 {
218 assert(nullptr == this->getComposite());
219
220 Base::setComposite(newComposite);
221 if (mTemporaryState)
222 SetEmbeddedState(static_cast<Derived*>(this), *mTemporaryState);
223
224 mTemporaryState = nullptr;
225 }
226
228 void loseComposite(Composite* oldComposite) override
229 {
230 mTemporaryState = std::make_unique<State>(
231 GetEmbeddedState(static_cast<const Derived*>(this)));
232 Base::loseComposite(oldComposite);
233 }
234
239 std::unique_ptr<State> mTemporaryState;
240};
241
242//==============================================================================
243template <
244 class BaseT,
245 class DerivedT,
246 typename PropertiesDataT,
248 void (*setEmbeddedProperties)(DerivedT*, const PropertiesT&)
249 = &DefaultSetEmbeddedProperties<DerivedT, PropertiesT>,
250 const PropertiesT& (*getEmbeddedProperties)(const DerivedT*)
251 = &DefaultGetEmbeddedProperties<DerivedT, PropertiesT> >
252class EmbeddedPropertiesAspect : public BaseT
253{
254protected:
256 {
257 Delegate
258 };
259
260public:
261 using Base = BaseT;
262 using Derived = DerivedT;
263 using Properties = PropertiesT;
264 using PropertiesData = PropertiesDataT;
265 constexpr static void (*SetEmbeddedProperties)(Derived*, const Properties&)
266 = setEmbeddedProperties;
267 constexpr static const Properties& (*GetEmbeddedProperties)(const Derived*)
268 = getEmbeddedProperties;
269
271
272 virtual ~EmbeddedPropertiesAspect() = default;
273
275 template <typename T>
277 {
278 using type = typename std::conditional<
279 std::is_base_of<PropertiesData, T>::value,
281 T>::type;
282 };
283
286 {
287 // Do nothing
288 }
289
293 //
294 // Dev Note: The complex construction pattern used here allows us to satisfy
295 // three simultaneous design constraints:
296 // 1. We can identify when the user has passed in relevant Properties
297 // information and capture that information. The type can be of **any**
298 // class type that inherits PropertiesData.
299 // 2. We can ignore any non-Properties information that the user has passed
300 // in, and move that information along to the Base class.
301 // 3. We can handle arbitrary numbers of arguments of any type to pass along
302 // to the Base class.
303 // If anyone can come up with a cleaner way of accomplishing all three of
304 // these constraints, I would gladly replace this implementation. -(MXG)
305 template <typename T, typename... RemainingArgs>
306 EmbeddedPropertiesAspect(const T& arg1, RemainingArgs&&... remainingArgs)
308 Delegate,
309 static_cast<const typename ConvertIfProperties<T>::type&>(arg1),
310 std::forward<RemainingArgs>(remainingArgs)...)
311 {
312 // Do nothing
313 }
314
315 // Documentation inherited
317 {
318 setProperties(static_cast<const Properties&>(properties));
319 }
320
321 // Documentation inherited
323 {
324 if (this->hasComposite())
325 {
326 SetEmbeddedProperties(static_cast<Derived*>(this), properties);
327 return;
328 }
329
330 // If the correct type of Composite is not available, we store this on the
331 // heap until this Aspect is moved.
332 mTemporaryProperties = std::make_unique<Properties>(properties);
333 }
334
335 // Documentation inherited
336 const Aspect::Properties* getAspectProperties() const override final
337 {
338 return &getProperties();
339 }
340
341 // Documentation inherited
343 {
344 if (this->hasComposite())
345 {
346 return GetEmbeddedProperties(static_cast<const Derived*>(this));
347 }
348
349 if (!mTemporaryProperties)
350 {
351 dterr << "[detail::EmbeddedPropertiesAspect::getProperties] This Aspect "
352 << "is not in a Composite, but it also does not have temporary "
353 << "Properties available. This should not happen! Please report "
354 << "this as a bug!\n";
355 assert(false);
356 }
357
358 return *mTemporaryProperties;
359 }
360
361 std::unique_ptr<Aspect> cloneAspect() const override
362 {
363 return std::make_unique<Derived>(this->getProperties());
364 }
365
366protected:
369 template <typename... RemainingArgs>
373 RemainingArgs&&... remainingArgs)
374 : Base(std::forward<RemainingArgs>(remainingArgs)...),
375 mTemporaryProperties(std::make_unique<Properties>(properties))
376 {
377 // Do nothing
378 }
379
382 template <typename... BaseArgs>
384 : Base(std::forward<BaseArgs>(args)...)
385 {
386 // Do nothing
387 }
388
390 void setComposite(Composite* newComposite) override
391 {
392 assert(nullptr == this->getComposite());
393
394 Base::setComposite(newComposite);
395 if (mTemporaryProperties)
396 SetEmbeddedProperties(static_cast<Derived*>(this), *mTemporaryProperties);
397
398 // Release the temporary memory
399 mTemporaryProperties = nullptr;
400 }
401
403 void loseComposite(Composite* oldComposite) override
404 {
405 mTemporaryProperties = std::make_unique<Properties>(
406 GetEmbeddedProperties(static_cast<Derived*>(this)));
407 Base::loseComposite(oldComposite);
408 }
409
414 std::unique_ptr<Properties> mTemporaryProperties;
415};
416
417//==============================================================================
418//
419// These namespace-level definitions are required to enable ODR-use of static
420// constexpr member variables.
421//
422// See this StackOverflow answer: http://stackoverflow.com/a/14396189/111426
423//
424template <
425 class BaseT,
426 class DerivedT,
427 typename StateDataT,
428 typename StateT,
429 void (*setEmbeddedState)(DerivedT*, const StateT&),
430 const StateT& (*getEmbeddedState)(const DerivedT*)>
431constexpr void (*EmbeddedStateAspect<
432 BaseT,
433 DerivedT,
434 StateDataT,
435 StateT,
436 setEmbeddedState,
437 getEmbeddedState>::SetEmbeddedState)(DerivedT*, const StateT&);
438
439//==============================================================================
440template <
441 class BaseT,
442 class DerivedT,
443 typename StateDataT,
444 typename StateT,
445 void (*setEmbeddedState)(DerivedT*, const StateT&),
446 const StateT& (*getEmbeddedState)(const DerivedT*)>
447constexpr const StateT& (*EmbeddedStateAspect<
448 BaseT,
449 DerivedT,
450 StateDataT,
451 StateT,
452 setEmbeddedState,
453 getEmbeddedState>::GetEmbeddedState)(const DerivedT*);
454
455//==============================================================================
456template <
457 class BaseT,
458 class DerivedT,
459 typename PropertiesDataT,
460 typename PropertiesT,
461 void (*setEmbeddedProperties)(DerivedT*, const PropertiesT&),
462 const PropertiesT& (*getEmbeddedProperties)(const DerivedT*)>
464 BaseT,
465 DerivedT,
466 PropertiesDataT,
467 PropertiesT,
468 setEmbeddedProperties,
469 getEmbeddedProperties>::SetEmbeddedProperties)(
470 DerivedT*, const PropertiesT&);
471
472//==============================================================================
473template <
474 class BaseT,
475 class DerivedT,
476 typename PropertiesDataT,
477 typename PropertiesT,
478 void (*setEmbeddedProperties)(DerivedT*, const PropertiesT&),
479 const PropertiesT& (*getEmbeddedProperties)(const DerivedT*)>
480constexpr const PropertiesT& (*EmbeddedPropertiesAspect<
481 BaseT,
482 DerivedT,
483 PropertiesDataT,
484 PropertiesT,
485 setEmbeddedProperties,
486 getEmbeddedProperties>::GetEmbeddedProperties)(
487 const DerivedT*);
488
489} // namespace detail
490} // namespace common
491} // namespace dart
492
493#endif // DART_COMMON_DETAIL_EMBEDDEDASPECT_HPP_
#define dterr
Output an error message.
Definition Console.hpp:49
BodyPropPtr properties
Definition SdfParser.cpp:80
std::string type
Definition SdfParser.cpp:82
If your Aspect has Properties, then that Properties class should inherit this Aspect::Properties clas...
Definition Aspect.hpp:86
If your Aspect has a State, then that State class should inherit this Aspect::State class.
Definition Aspect.hpp:65
Composite is a base class that should be virtually inherited by any class that wants to be able to ma...
Definition Composite.hpp:53
The MakeCloneable class is used to easily create an Cloneable (such as Node::State) which simply take...
Definition Cloneable.hpp:84
Definition EmbeddedAspect.hpp:253
PropertiesDataT PropertiesData
Definition EmbeddedAspect.hpp:264
EmbeddedPropertiesAspect(const EmbeddedPropertiesAspect &)=delete
EmbeddedPropertiesAspect(DelegateTag, const PropertiesData &properties, RemainingArgs &&... remainingArgs)
Construct this Aspect using the PropertiesData, and pass the remaining arguments into the constructor...
Definition EmbeddedAspect.hpp:370
std::unique_ptr< Properties > mTemporaryProperties
After this Aspect is constructed and during transitions between Composite objects,...
Definition EmbeddedAspect.hpp:414
void setComposite(Composite *newComposite) override
Pass the temporary Properties of this Aspect into the new Composite.
Definition EmbeddedAspect.hpp:390
BaseT Base
Definition EmbeddedAspect.hpp:261
const Aspect::Properties * getAspectProperties() const override final
Definition EmbeddedAspect.hpp:336
const Properties & getProperties() const
Definition EmbeddedAspect.hpp:342
PropertiesT Properties
Definition EmbeddedAspect.hpp:263
DelegateTag
Definition EmbeddedAspect.hpp:256
DerivedT Derived
Definition EmbeddedAspect.hpp:262
EmbeddedPropertiesAspect(const T &arg1, RemainingArgs &&... remainingArgs)
Construct this Aspect.
Definition EmbeddedAspect.hpp:306
void setAspectProperties(const Aspect::Properties &properties) override final
Definition EmbeddedAspect.hpp:316
EmbeddedPropertiesAspect(DelegateTag, BaseArgs &&... args)
Construct this Aspect without affecting the Properties, and pass all the arguments into the construct...
Definition EmbeddedAspect.hpp:383
void setProperties(const Properties &properties)
Definition EmbeddedAspect.hpp:322
std::unique_ptr< Aspect > cloneAspect() const override
Definition EmbeddedAspect.hpp:361
void loseComposite(Composite *oldComposite) override
Save the embedded Properties of this Composite before we remove the Aspect.
Definition EmbeddedAspect.hpp:403
EmbeddedPropertiesAspect()
Construct this Aspect without affecting the Properties.
Definition EmbeddedAspect.hpp:285
Definition EmbeddedAspect.hpp:83
const Aspect::State * getAspectState() const override final
Definition EmbeddedAspect.hpp:163
void setState(const State &state)
Set the State of this Aspect.
Definition EmbeddedAspect.hpp:149
void loseComposite(Composite *oldComposite) override
Save the embedded State of this Composite before we remove the Aspect.
Definition EmbeddedAspect.hpp:228
DelegateTag
Definition EmbeddedAspect.hpp:95
DerivedT Derived
Definition EmbeddedAspect.hpp:86
const State & getState() const
Get the State of this Aspect.
Definition EmbeddedAspect.hpp:169
StateDataT StateData
Definition EmbeddedAspect.hpp:88
StateT State
Definition EmbeddedAspect.hpp:87
void setAspectState(const Aspect::State &state) override final
Definition EmbeddedAspect.hpp:143
std::unique_ptr< Aspect > cloneAspect() const override
Definition EmbeddedAspect.hpp:189
BaseT Base
Definition EmbeddedAspect.hpp:85
void setComposite(Composite *newComposite) override
Pass the temporary State of this Aspect into the new Composite.
Definition EmbeddedAspect.hpp:216
EmbeddedStateAspect(const EmbeddedStateAspect &)=delete
EmbeddedStateAspect(DelegateTag, BaseArgs &&... args)
Construct this Aspect without affecting the State, and pass all the arguments into the constructor of...
Definition EmbeddedAspect.hpp:209
EmbeddedStateAspect(DelegateTag, const StateData &state, RemainingArgs &&... remainingArgs)
Construct this Aspect using the StateData, and pass the remaining arguments into the constructor of t...
Definition EmbeddedAspect.hpp:198
EmbeddedStateAspect(const T &arg1, RemainingArgs &&... remainingArgs)
Construct this Aspect.
Definition EmbeddedAspect.hpp:133
EmbeddedStateAspect()
Construct this Aspect without affecting the State.
Definition EmbeddedAspect.hpp:112
std::unique_ptr< State > mTemporaryState
After this Aspect is constructed and during transitions between Composite objects,...
Definition EmbeddedAspect.hpp:239
void DefaultSetEmbeddedProperties(AspectT *aspect, const PropertiesT &properties)
Definition EmbeddedAspect.hpp:59
void DefaultSetEmbeddedState(AspectT *aspect, const StateT &state)
Definition EmbeddedAspect.hpp:45
const PropertiesT & DefaultGetEmbeddedProperties(const AspectT *aspect)
Definition EmbeddedAspect.hpp:67
const StateT & DefaultGetEmbeddedState(const AspectT *aspect)
Definition EmbeddedAspect.hpp:52
std::unique_ptr< T > make_unique(Args &&... args)
Definition Memory-impl.hpp:67
Definition BulletCollisionDetector.cpp:65
Definition SharedLibraryManager.hpp:46
Used to identify constructor arguments that can be used as Properties.
Definition EmbeddedAspect.hpp:277
typename std::conditional< std::is_base_of< PropertiesData, T >::value, PropertiesData, T >::type type
Definition EmbeddedAspect.hpp:281
Used to identify constructor arguments that can be used as a State.
Definition EmbeddedAspect.hpp:106
typename std::conditional< std::is_base_of< StateData, T >::value, StateData, T >::type type
Definition EmbeddedAspect.hpp:108