DART  6.7.3
Composite.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_COMPOSITE_HPP_
34 #define DART_COMMON_DETAIL_COMPOSITE_HPP_
35 
37 
38 #define DART_COMMON_CHECK_ILLEGAL_ASPECT_ERASE( Func, T, ReturnType )\
39  if(requiresAspect< T >())\
40  {\
41  dterr << "[Composite::" #Func << "] Illegal request to remove required "\
42  << "Aspect [" << typeid(T).name() << "]!\n";\
43  assert(false);\
44  return ReturnType ;\
45  }
46 
47 namespace dart {
48 namespace common {
49 
50 //==============================================================================
51 template <class T>
52 bool Composite::has() const
53 {
54  return (get<T>() != nullptr);
55 }
56 
57 //==============================================================================
58 template <class T>
60 {
61  AspectMap::iterator it = mAspectMap.find( typeid(T) );
62  if(mAspectMap.end() == it)
63  return nullptr;
64 
65  return static_cast<T*>(it->second.get());
66 }
67 
68 //==============================================================================
69 template <class T>
70 const T* Composite::get() const
71 {
72  return const_cast<Composite*>(this)->get<T>();
73 }
74 
75 //==============================================================================
76 template <class T>
77 void Composite::set(const T* aspect)
78 {
79  _set(typeid(T), aspect);
80 }
81 
82 //==============================================================================
83 template <class T>
84 void Composite::set(std::unique_ptr<T>&& aspect)
85 {
86  _set(typeid(T), std::move(aspect));
87 }
88 
89 //==============================================================================
90 template <class T, typename ...Args>
91 T* Composite::createAspect(Args&&... args)
92 {
93  T* aspect = new T(std::forward<Args>(args)...);
94  mAspectMap[typeid(T)] = std::unique_ptr<T>(aspect);
95  addToComposite(aspect);
96 
97  return aspect;
98 }
99 
100 //==============================================================================
101 template <class T>
103 {
104  AspectMap::iterator it = mAspectMap.find( typeid(T) );
106  if(mAspectMap.end() != it)
107  {
108  removeFromComposite(it->second.get());
109  it->second = nullptr;
110  }
111 }
112 
113 //==============================================================================
114 template <class T>
115 std::unique_ptr<T> Composite::releaseAspect()
116 {
117  std::unique_ptr<T> extraction = nullptr;
118  AspectMap::iterator it = mAspectMap.find( typeid(T) );
120  if(mAspectMap.end() != it)
121  {
122  removeFromComposite(it->second.get());
123  extraction = std::unique_ptr<T>(static_cast<T*>(it->second.release()));
124  }
125 
126  return extraction;
127 }
128 
129 //==============================================================================
130 template <class T>
132 {
133  return false;
134 }
135 
136 //==============================================================================
137 template <class T>
139 {
140  return (mRequiredAspects.find(typeid(T)) != mRequiredAspects.end());
141 }
142 
143 //==============================================================================
144 template <class T>
145 void createAspects(T* /*comp*/)
146 {
147  // Do nothing
148 }
149 
150 //==============================================================================
151 template <class T, class NextAspect, class... Aspects>
152 void createAspects(T* comp)
153 {
154  comp->template createAspect<NextAspect>();
155 
156  createAspects<T, Aspects...>(comp);
157 }
158 
159 } // namespace common
160 } // namespace dart
161 
162 //==============================================================================
163 // Create non-template alternatives to Composite functions
164 #define DART_BAKE_SPECIALIZED_ASPECT_IRREGULAR( TypeName, AspectName )\
165 \
166  inline bool has ## AspectName () const\
167  {\
168  return this->template has<TypeName>();\
169  }\
170 \
171 \
172  inline TypeName * get ## AspectName ()\
173  {\
174  return this->template get<TypeName>();\
175  }\
176 \
177 \
178  inline const TypeName* get ## AspectName () const\
179  {\
180  return this->template get<TypeName>();\
181  }\
182 \
183 \
187  inline TypeName * get ## AspectName (const bool createIfNull)\
188  {\
189  TypeName* aspect = get ## AspectName();\
190 \
191  if (createIfNull && nullptr == aspect)\
192  return create ## AspectName();\
193 \
194  return aspect;\
195  }\
196 \
197 \
202  inline void set ## AspectName (const TypeName * aspect)\
203  {\
204  this->template set<TypeName>(aspect);\
205  }\
206 \
207 \
212  inline void set ## AspectName (std::unique_ptr< TypeName >&& aspect)\
213  {\
214  this->template set<TypeName>(std::move(aspect));\
215  }\
216 \
217 \
218  template <typename ...Args>\
219  inline TypeName * create ## AspectName (Args&&... args)\
220  {\
221  return this->template createAspect<TypeName>(std::forward<Args>(args)...);\
222  }\
223 \
224 \
225  inline void remove ## AspectName ()\
226  {\
227  this->template removeAspect<TypeName>();\
228  }\
229 \
230 \
235  inline std::unique_ptr< TypeName > release ## AspectName ()\
236  {\
237  return this->template releaseAspect<TypeName>();\
238  }
239 
240 //==============================================================================
241 #define DART_BAKE_SPECIALIZED_ASPECT(AspectName)\
242  DART_BAKE_SPECIALIZED_ASPECT_IRREGULAR(AspectName, AspectName);
243 
244 #endif // DART_COMMON_DETAIL_COMPOSITE_HPP_
#define DART_BLANK
Definition: NoOp.hpp:55
Composite is a base class that should be virtually inherited by any class that wants to be able to ma...
Definition: Composite.hpp:52
RequiredAspectSet mRequiredAspects
A set containing type information for Aspects which are not allowed to leave this composite.
Definition: Composite.hpp:186
static constexpr bool isSpecializedFor()
Check if this Composite is specialized for a specific type of Aspect.
Definition: Composite.hpp:131
void removeAspect()
Remove an Aspect from this Composite.
Definition: Composite.hpp:102
bool requiresAspect() const
Check if this Composite requires this specific type of Aspect.
Definition: Composite.hpp:138
void _set(std::type_index type_idx, const Aspect *aspect)
Non-templated version of set(const T*)
Definition: Composite.cpp:278
T * get()
Get a certain type of Aspect from this Composite.
Definition: Composite.hpp:59
void addToComposite(Aspect *aspect)
Add this Aspect to the Composite.
Definition: Composite.cpp:264
void removeFromComposite(Aspect *aspect)
Remove this Aspect from the Composite.
Definition: Composite.cpp:271
std::unique_ptr< T > releaseAspect()
Remove an Aspect from this Composite, but return its unique_ptr instead of letting it be deleted.
Definition: Composite.hpp:115
bool has() const
Check if this Composite currently has a certain type of Aspect.
Definition: Composite.hpp:52
T * createAspect(Args &&... args)
Construct an Aspect inside of this Composite.
Definition: Composite.hpp:91
AspectMap mAspectMap
A map that relates the type of Aspect to its pointer.
Definition: Composite.hpp:182
void set(const T *aspect)
Make a clone of the aspect and place the clone into this Composite.
Definition: Composite.hpp:77
#define DART_COMMON_CHECK_ILLEGAL_ASPECT_ERASE(Func, T, ReturnType)
Definition: Composite.hpp:38
void createAspects(T *)
Attach an arbitrary number of Aspects to the specified Composite type.
Definition: Composite.hpp:145
std::multimap< dart::dynamics::Shape *, SimpleFrameShapeDnD * >::iterator iterator
Definition: Viewer.cpp:622
Definition: BulletCollisionDetector.cpp:63