DART  6.7.3
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 
36 #include "dart/common/Aspect.hpp"
38 
39 namespace dart {
40 namespace common {
41 namespace detail {
42 
43 //==============================================================================
44 template <class AspectT, typename StateT>
45 void DefaultSetEmbeddedState(AspectT* aspect, const StateT& state)
46 {
47  aspect->getComposite()->setAspectState(state);
48 }
49 
50 //==============================================================================
51 template <class AspectT, typename StateT>
52 const StateT& DefaultGetEmbeddedState(const AspectT* aspect)
53 {
54  return aspect->getComposite()->getAspectState();
55 }
56 
57 //==============================================================================
58 template <class AspectT, typename PropertiesT>
59 void DefaultSetEmbeddedProperties(AspectT* aspect, const PropertiesT& properties)
60 {
61  aspect->getComposite()->setAspectProperties(properties);
62 }
63 
64 //==============================================================================
65 template <class AspectT, typename PropertiesT>
66 const PropertiesT& DefaultGetEmbeddedProperties(const AspectT* aspect)
67 {
68  return aspect->getComposite()->getAspectProperties();
69 }
70 
71 //==============================================================================
72 template <class BaseT, class DerivedT, typename StateDataT,
73  typename StateT = common::Aspect::MakeState<StateDataT>,
74  void (*setEmbeddedState)(DerivedT*, const StateT&) =
75  &DefaultSetEmbeddedState<DerivedT, StateT>,
76  const StateT& (*getEmbeddedState)(const DerivedT*) =
77  &DefaultGetEmbeddedState<DerivedT, StateT> >
78 class EmbeddedStateAspect : public BaseT
79 {
80 public:
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 
190 protected:
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 //==============================================================================
243 template <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> >
249 class EmbeddedPropertiesAspect : public BaseT
250 {
251 protected:
252 
253  enum DelegateTag { Delegate };
254 
255 public:
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
338  const Properties& getProperties() const
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 
362 protected:
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 //
423 template <class BaseT, class DerivedT, typename StateDataT,
424  typename StateT,
425  void (*setEmbeddedState)(DerivedT*, const StateT&),
426  const StateT& (*getEmbeddedState)(const DerivedT*)>
427 constexpr void (*EmbeddedStateAspect<
428  BaseT, DerivedT, StateDataT, StateT, setEmbeddedState,
429  getEmbeddedState>::SetEmbeddedState)(DerivedT*, const StateT&);
430 
431 //==============================================================================
432 template <class BaseT, class DerivedT, typename StateDataT,
433  typename StateT,
434  void (*setEmbeddedState)(DerivedT*, const StateT&),
435  const StateT& (*getEmbeddedState)(const DerivedT*)>
436 constexpr const StateT& (*EmbeddedStateAspect<
437  BaseT, DerivedT, StateDataT, StateT, setEmbeddedState,
438  getEmbeddedState>::GetEmbeddedState)(const DerivedT*);
439 
440 //==============================================================================
441 template <class BaseT, class DerivedT, typename PropertiesDataT,
442  typename PropertiesT,
443  void (*setEmbeddedProperties)(DerivedT*, const PropertiesT&),
444  const PropertiesT& (*getEmbeddedProperties)(const DerivedT*)>
445 constexpr void (*EmbeddedPropertiesAspect<
446  BaseT, DerivedT, PropertiesDataT, PropertiesT, setEmbeddedProperties,
447  getEmbeddedProperties>::SetEmbeddedProperties)(DerivedT*, const PropertiesT&);
448 
449 //==============================================================================
450 template <class BaseT, class DerivedT, typename PropertiesDataT,
451  typename PropertiesT,
452  void (*setEmbeddedProperties)(DerivedT*, const PropertiesT&),
453  const PropertiesT& (*getEmbeddedProperties)(const DerivedT*)>
454 constexpr 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
const Aspect::Properties * getAspectProperties() const override final
Definition: EmbeddedAspect.hpp:332
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
std::unique_ptr< Aspect > cloneAspect() const override
Definition: EmbeddedAspect.hpp:357
PropertiesT Properties
Definition: EmbeddedAspect.hpp:259
DelegateTag
Definition: EmbeddedAspect.hpp:253
const Properties & getProperties() const
Definition: EmbeddedAspect.hpp:338
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
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
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
std::unique_ptr< Aspect > cloneAspect() const override
Definition: EmbeddedAspect.hpp:185
DelegateTag
Definition: EmbeddedAspect.hpp:89
DerivedT Derived
Definition: EmbeddedAspect.hpp:83
StateDataT StateData
Definition: EmbeddedAspect.hpp:85
StateT State
Definition: EmbeddedAspect.hpp:84
void setAspectState(const Aspect::State &state) override final
Definition: EmbeddedAspect.hpp:139
const Aspect::State * getAspectState() const override final
Definition: EmbeddedAspect.hpp:159
BaseT Base
Definition: EmbeddedAspect.hpp:82
const State & getState() const
Get the State of this Aspect.
Definition: EmbeddedAspect.hpp:165
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 StateT & DefaultGetEmbeddedState(const AspectT *aspect)
Definition: EmbeddedAspect.hpp:52
const PropertiesT & DefaultGetEmbeddedProperties(const AspectT *aspect)
Definition: EmbeddedAspect.hpp:66
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