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