DART 6.7.3
Loading...
Searching...
No Matches
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
47namespace dart {
48namespace common {
49
50//==============================================================================
51template <class T>
52bool Composite::has() const
53{
54 return (get<T>() != nullptr);
55}
56
57//==============================================================================
58template <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//==============================================================================
69template <class T>
70const T* Composite::get() const
71{
72 return const_cast<Composite*>(this)->get<T>();
73}
74
75//==============================================================================
76template <class T>
77void Composite::set(const T* aspect)
78{
79 _set(typeid(T), aspect);
80}
81
82//==============================================================================
83template <class T>
84void Composite::set(std::unique_ptr<T>&& aspect)
85{
86 _set(typeid(T), std::move(aspect));
87}
88
89//==============================================================================
90template <class T, typename ...Args>
91T* 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//==============================================================================
101template <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//==============================================================================
114template <class T>
115std::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//==============================================================================
130template <class T>
132{
133 return false;
134}
135
136//==============================================================================
137template <class T>
139{
140 return (mRequiredAspects.find(typeid(T)) != mRequiredAspects.end());
141}
142
143//==============================================================================
144template <class T>
145void createAspects(T* /*comp*/)
146{
147 // Do nothing
148}
149
150//==============================================================================
151template <class T, class NextAspect, class... Aspects>
152void 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
Definition BulletCollisionDetector.cpp:63