DART 6.7.3
Loading...
Searching...
No Matches
BodyNodePtr.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_DYNAMICS_DETAIL_BODYNODEPTR_HPP_
34#define DART_DYNAMICS_DETAIL_BODYNODEPTR_HPP_
35
36#include <memory>
37#include <mutex>
38#include <atomic>
39
40namespace dart{
41namespace dynamics {
42
43class Skeleton;
44
45//==============================================================================
47{
48 std::mutex mMutex;
49 std::weak_ptr<const Skeleton> mSkeleton;
50};
51
52//==============================================================================
54{
55public:
56 template<class> friend class TemplateBodyNodePtr;
57 template<class> friend class TemplateWeakBodyNodePtr;
58
60 std::shared_ptr<Skeleton> getSkeleton();
61
63 std::shared_ptr<const Skeleton> getSkeleton() const;
64
65private:
66
67 //--------------------------------------------------------------------------
68 // Reference counting
69 //--------------------------------------------------------------------------
70
73 void incrementReferenceCount() const;
74
77 void decrementReferenceCount() const;
78
79protected:
80
83
85 std::weak_ptr<Skeleton> mSkeleton;
86
89 mutable std::atomic<int> mReferenceCount;
90
96 mutable std::shared_ptr<Skeleton> mReferenceSkeleton;
97
101 std::shared_ptr<MutexedWeakSkeletonPtr> mLockedSkeleton;
102
103};
104
109template <class BodyNodeT>
111{
112public:
114 TemplateBodyNodePtr() : mPtr(nullptr) { }
115
118 TemplateBodyNodePtr(BodyNodeT* _ptr) : mPtr(nullptr) { set(_ptr); }
119
122 : mPtr(nullptr)
123 {
124 set(_bnp.get());
125 }
126
128 template <class OtherBodyNodeT>
130 : mPtr(nullptr)
131 {
132 set(_bnp.get());
133 }
134
136 ~TemplateBodyNodePtr() { set(nullptr); }
137
139 template <class OtherBodyNodeT>
142 {
143 set(_bnp.get());
144 return *this;
145 }
146
149 {
150 set(_ptr);
151 return *this;
152 }
153
155 operator BodyNodeT*() const { return mPtr; }
156
158 BodyNodeT& operator*() const { return *mPtr; }
159
161 BodyNodeT* operator->() const { return mPtr; }
162
164 BodyNodeT* get() const { return mPtr; }
165
167 void set(BodyNodeT* _ptr)
168 {
169 if(mPtr == _ptr)
170 return;
171
172 if(nullptr != mPtr)
173 {
174 static_cast<const SkeletonRefCountingBase*>(mPtr)->
175 decrementReferenceCount();
176 }
177
178 if(nullptr != _ptr)
179 {
180 static_cast<const SkeletonRefCountingBase*>(_ptr)->
181 incrementReferenceCount();
182 }
183
184 mPtr = _ptr;
185 }
186
187private:
189 BodyNodeT* mPtr;
190};
191
197template <class BodyNodeT>
199{
200public:
201
202 template<class> friend class TemplateWeakBodyNodePtr;
203
206
209 TemplateWeakBodyNodePtr(BodyNodeT* _ptr) : mPtr(nullptr) { set(_ptr); }
210
212 template <class OtherBodyNodeT>
215 : mPtr(nullptr) { set(_weakPtr); }
216
219 {
220 set(_ptr);
221 return *this;
222 }
223
225 template <class OtherBodyNodeT>
228 {
229 set(_weakPtr);
230 return *this;
231 }
232
241 {
242 if(nullptr == mLocker)
243 return nullptr;
244
245 // We do not use the expired() function here, because we want to ensure that
246 // the Skeleton's reference count remains up while we create the strong
247 // BodyNodePtr that we're going to return.
248 std::lock_guard<std::mutex> lock(mLocker->mMutex);
249 std::shared_ptr<const Skeleton> skeleton = mLocker->mSkeleton.lock();
250 if(nullptr == skeleton)
251 return nullptr;
252
254 }
255
257 void set(BodyNodeT* _ptr)
258 {
259 mPtr = _ptr;
260
261 if(nullptr == mPtr)
262 mLocker = nullptr;
263 else
264 mLocker = static_cast<const SkeletonRefCountingBase*>(_ptr)->
265 mLockedSkeleton;
266 }
267
270 template <class OtherBodyNodeT>
272 {
273 if(nullptr == _weakPtr.mLocker)
274 {
275 set(nullptr);
276 return;
277 }
278
279 std::lock_guard<std::mutex> lock(_weakPtr.mLocker->mMutex);
280 std::shared_ptr<const Skeleton> skeleton =
281 _weakPtr.mLocker->mSkeleton.lock();
282 if(nullptr == skeleton)
283 {
284 set(nullptr);
285 return;
286 }
287
288 set(_weakPtr.mPtr);
289 }
290
299 bool expired() const
300 {
301 if(nullptr == mLocker)
302 return true;
303
304 // It is okay for 'lock' to go "unused", because it is managed by RAII after
305 // it has been initialized
306 std::lock_guard<std::mutex> lock(mLocker->mMutex);
307 std::shared_ptr<const Skeleton> skeleton = mLocker->mSkeleton.lock();
308 if(nullptr == skeleton)
309 return true;
310
311 return false;
312 }
313
314private:
316 BodyNodeT* mPtr;
317
320 std::shared_ptr<MutexedWeakSkeletonPtr> mLocker;
321};
322
323
324} // namespace dynamics
325} // namespace dart
326
327#endif // DART_DYNAMICS_DETAIL_BODYNODEPTR_HPP_
Definition BodyNodePtr.hpp:54
std::shared_ptr< MutexedWeakSkeletonPtr > mLockedSkeleton
Shared reference to a weak_ptr of this BodyNode's Skeleton, along with a mutex to ensure thread safet...
Definition BodyNodePtr.hpp:101
std::shared_ptr< Skeleton > getSkeleton()
Return the Skeleton this BodyNode belongs to.
Definition BodyNode.cpp:149
std::atomic< int > mReferenceCount
Reference count for the number of BodyNodePtrs that are referring to this BodyNode.
Definition BodyNodePtr.hpp:89
SkeletonRefCountingBase()
Default Constructor.
Definition BodyNode.cpp:125
std::weak_ptr< Skeleton > mSkeleton
Weak pointer to the Skeleton this BodyNode belongs to.
Definition BodyNodePtr.hpp:85
std::shared_ptr< Skeleton > mReferenceSkeleton
If mReferenceCount is zero, then mReferenceSkeleton will hold a nullptr.
Definition BodyNodePtr.hpp:96
void incrementReferenceCount() const
Atomically increment the reference count for this BodyNode.
Definition BodyNode.cpp:133
void decrementReferenceCount() const
Atomically decrement the reference count for this BodyNode.
Definition BodyNode.cpp:141
TemplateBodyNodePtr is a templated class that enables users to create a reference-counting BodyNodePt...
Definition BodyNodePtr.hpp:111
BodyNodeT * operator->() const
Dereferencing operation.
Definition BodyNodePtr.hpp:161
BodyNodeT * mPtr
Raw pointer for the BodyNode that this BodyNodePtr references.
Definition BodyNodePtr.hpp:189
TemplateBodyNodePtr(const TemplateBodyNodePtr< OtherBodyNodeT > &_bnp)
Templated constructor for copying other BodyNodePtrs.
Definition BodyNodePtr.hpp:129
TemplateBodyNodePtr()
Default constructor.
Definition BodyNodePtr.hpp:114
void set(BodyNodeT *_ptr)
Set the BodyNode for this BodyNodePtr.
Definition BodyNodePtr.hpp:167
BodyNodeT & operator*() const
Dereferencing operator.
Definition BodyNodePtr.hpp:158
TemplateBodyNodePtr(BodyNodeT *_ptr)
Typical constructor.
Definition BodyNodePtr.hpp:118
TemplateBodyNodePtr(const TemplateBodyNodePtr &_bnp)
User defined copy-constructor.
Definition BodyNodePtr.hpp:121
~TemplateBodyNodePtr()
Destructor. Releases the BodyNode reference before being destroyed.
Definition BodyNodePtr.hpp:136
TemplateBodyNodePtr & operator=(const TemplateBodyNodePtr< OtherBodyNodeT > &_bnp)
Change the BodyNode that this BodyNodePtr references.
Definition BodyNodePtr.hpp:140
BodyNodeT * get() const
Get the raw BodyNode pointer.
Definition BodyNodePtr.hpp:164
TemplateWeakBodyNodePtr is a templated class that enables users to create a non-reference-holding Wea...
Definition BodyNodePtr.hpp:199
TemplateBodyNodePtr< BodyNodeT > lock() const
Locks the BodyNode reference to ensure that the referenced BodyNode (1) is currently still available,...
Definition BodyNodePtr.hpp:240
void set(BodyNodeT *_ptr)
Set the BodyNode for this WeakBodyNodePtr.
Definition BodyNodePtr.hpp:257
BodyNodeT * mPtr
Raw pointer for the BodyNode that this WeakBodyNodePtr references.
Definition BodyNodePtr.hpp:316
TemplateWeakBodyNodePtr(BodyNodeT *_ptr)
Typical constructor.
Definition BodyNodePtr.hpp:209
void set(const TemplateWeakBodyNodePtr< OtherBodyNodeT > &_weakPtr)
Attempt to set the BodyNode for this WeakBodyNodePtr based on another WeakBodyNodePtr.
Definition BodyNodePtr.hpp:271
TemplateWeakBodyNodePtr & operator=(BodyNodeT *_ptr)
Assignment operator for raw BodyNode pointers.
Definition BodyNodePtr.hpp:218
TemplateWeakBodyNodePtr()
Default constructor.
Definition BodyNodePtr.hpp:205
TemplateWeakBodyNodePtr(const TemplateWeakBodyNodePtr< OtherBodyNodeT > &_weakPtr)
Constructor that takes in a WeakBodyNodePtr.
Definition BodyNodePtr.hpp:213
bool expired() const
Returns true if this WeakBodyNodePtr is referencing a nullptr or a pointer which has been deleted.
Definition BodyNodePtr.hpp:299
std::shared_ptr< MutexedWeakSkeletonPtr > mLocker
A shared_ptr that allows the WeakBodyNodePtr to know whether it can lock into a BodyNodePtr.
Definition BodyNodePtr.hpp:320
Definition BulletCollisionDetector.cpp:63
Definition BodyNodePtr.hpp:47
std::weak_ptr< const Skeleton > mSkeleton
Definition BodyNodePtr.hpp:49
std::mutex mMutex
Definition BodyNodePtr.hpp:48