DART 6.10.1
Loading...
Searching...
No Matches
BodyNodePtr.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2021, 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 <atomic>
37#include <memory>
38#include <mutex>
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>
57 friend class TemplateBodyNodePtr;
58 template <class>
60
62 std::shared_ptr<Skeleton> getSkeleton();
63
65 std::shared_ptr<const Skeleton> getSkeleton() const;
66
67private:
68 //--------------------------------------------------------------------------
69 // Reference counting
70 //--------------------------------------------------------------------------
71
74 void incrementReferenceCount() const;
75
78 void decrementReferenceCount() const;
79
80protected:
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
108template <class BodyNodeT>
110{
111public:
114 {
115 }
116
119 TemplateBodyNodePtr(BodyNodeT* _ptr) : mPtr(nullptr)
120 {
121 set(_ptr);
122 }
123
126 {
127 set(_bnp.get());
128 }
129
131 template <class OtherBodyNodeT>
133 : mPtr(nullptr)
134 {
135 set(_bnp.get());
136 }
137
140 {
141 set(nullptr);
142 }
143
146 {
147 set(bnp.get());
148 return *this;
149 }
150
152 template <class OtherBodyNodeT>
155 {
156 set(_bnp.get());
157 return *this;
158 }
159
162 {
163 set(_ptr);
164 return *this;
165 }
166
168 operator BodyNodeT*() const
169 {
170 return mPtr;
171 }
172
174 BodyNodeT& operator*() const
175 {
176 return *mPtr;
177 }
178
180 BodyNodeT* operator->() const
181 {
182 return mPtr;
183 }
184
186 BodyNodeT* get() const
187 {
188 return mPtr;
189 }
190
192 void set(BodyNodeT* _ptr)
193 {
194 if (mPtr == _ptr)
195 return;
196
197 if (nullptr != mPtr)
198 {
199 static_cast<const SkeletonRefCountingBase*>(mPtr)
200 ->decrementReferenceCount();
201 }
202
203 if (nullptr != _ptr)
204 {
205 static_cast<const SkeletonRefCountingBase*>(_ptr)
206 ->incrementReferenceCount();
207 }
208
209 mPtr = _ptr;
210 }
211
212private:
214 BodyNodeT* mPtr;
215};
216
222template <class BodyNodeT>
224{
225public:
226 template <class>
228
231 {
232 }
233
236 TemplateWeakBodyNodePtr(BodyNodeT* _ptr) : mPtr(nullptr)
237 {
238 set(_ptr);
239 }
240
242 template <class OtherBodyNodeT>
245 : mPtr(nullptr)
246 {
247 set(_weakPtr);
248 }
249
252 {
253 set(_ptr);
254 return *this;
255 }
256
258 template <class OtherBodyNodeT>
261 {
262 set(_weakPtr);
263 return *this;
264 }
265
274 {
275 if (nullptr == mLocker)
276 return nullptr;
277
278 // We do not use the expired() function here, because we want to ensure that
279 // the Skeleton's reference count remains up while we create the strong
280 // BodyNodePtr that we're going to return.
281 std::lock_guard<std::mutex> lock(mLocker->mMutex);
282 std::shared_ptr<const Skeleton> skeleton = mLocker->mSkeleton.lock();
283 if (nullptr == skeleton)
284 return nullptr;
285
287 }
288
290 void set(BodyNodeT* _ptr)
291 {
292 mPtr = _ptr;
293
294 if (nullptr == mPtr)
295 mLocker = nullptr;
296 else
297 mLocker
298 = static_cast<const SkeletonRefCountingBase*>(_ptr)->mLockedSkeleton;
299 }
300
303 template <class OtherBodyNodeT>
305 {
306 if (nullptr == _weakPtr.mLocker)
307 {
308 set(nullptr);
309 return;
310 }
311
312 std::lock_guard<std::mutex> lock(_weakPtr.mLocker->mMutex);
313 std::shared_ptr<const Skeleton> skeleton
314 = _weakPtr.mLocker->mSkeleton.lock();
315 if (nullptr == skeleton)
316 {
317 set(nullptr);
318 return;
319 }
320
321 set(_weakPtr.mPtr);
322 }
323
332 bool expired() const
333 {
334 if (nullptr == mLocker)
335 return true;
336
337 // It is okay for 'lock' to go "unused", because it is managed by RAII after
338 // it has been initialized
339 std::lock_guard<std::mutex> lock(mLocker->mMutex);
340 std::shared_ptr<const Skeleton> skeleton = mLocker->mSkeleton.lock();
341 if (nullptr == skeleton)
342 return true;
343
344 return false;
345 }
346
347private:
349 BodyNodeT* mPtr;
350
353 std::shared_ptr<MutexedWeakSkeletonPtr> mLocker;
354};
355
356} // namespace dynamics
357} // namespace dart
358
359#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:152
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:128
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:136
void decrementReferenceCount() const
Atomically decrement the reference count for this BodyNode.
Definition BodyNode.cpp:144
TemplateBodyNodePtr is a templated class that enables users to create a reference-counting BodyNodePt...
Definition BodyNodePtr.hpp:110
BodyNodeT * operator->() const
Dereferencing operation.
Definition BodyNodePtr.hpp:180
TemplateBodyNodePtr & operator=(const TemplateBodyNodePtr &bnp)
User defined assignment operator.
Definition BodyNodePtr.hpp:145
BodyNodeT * mPtr
Raw pointer for the BodyNode that this BodyNodePtr references.
Definition BodyNodePtr.hpp:214
TemplateBodyNodePtr(const TemplateBodyNodePtr< OtherBodyNodeT > &_bnp)
Templated constructor for copying other BodyNodePtrs.
Definition BodyNodePtr.hpp:132
TemplateBodyNodePtr()
Default constructor.
Definition BodyNodePtr.hpp:113
void set(BodyNodeT *_ptr)
Set the BodyNode for this BodyNodePtr.
Definition BodyNodePtr.hpp:192
BodyNodeT & operator*() const
Dereferencing operator.
Definition BodyNodePtr.hpp:174
TemplateBodyNodePtr(BodyNodeT *_ptr)
Typical constructor.
Definition BodyNodePtr.hpp:119
TemplateBodyNodePtr(const TemplateBodyNodePtr &_bnp)
User defined copy-constructor.
Definition BodyNodePtr.hpp:125
~TemplateBodyNodePtr()
Destructor. Releases the BodyNode reference before being destroyed.
Definition BodyNodePtr.hpp:139
TemplateBodyNodePtr & operator=(BodyNodeT *_ptr)
Assignment operator.
Definition BodyNodePtr.hpp:161
TemplateBodyNodePtr & operator=(const TemplateBodyNodePtr< OtherBodyNodeT > &_bnp)
Change the BodyNode that this BodyNodePtr references.
Definition BodyNodePtr.hpp:153
BodyNodeT * get() const
Get the raw BodyNode pointer.
Definition BodyNodePtr.hpp:186
TemplateWeakBodyNodePtr is a templated class that enables users to create a non-reference-holding Wea...
Definition BodyNodePtr.hpp:224
TemplateBodyNodePtr< BodyNodeT > lock() const
Locks the BodyNode reference to ensure that the referenced BodyNode (1) is currently still available,...
Definition BodyNodePtr.hpp:273
void set(BodyNodeT *_ptr)
Set the BodyNode for this WeakBodyNodePtr.
Definition BodyNodePtr.hpp:290
BodyNodeT * mPtr
Raw pointer for the BodyNode that this WeakBodyNodePtr references.
Definition BodyNodePtr.hpp:349
TemplateWeakBodyNodePtr(BodyNodeT *_ptr)
Typical constructor.
Definition BodyNodePtr.hpp:236
void set(const TemplateWeakBodyNodePtr< OtherBodyNodeT > &_weakPtr)
Attempt to set the BodyNode for this WeakBodyNodePtr based on another WeakBodyNodePtr.
Definition BodyNodePtr.hpp:304
TemplateWeakBodyNodePtr & operator=(BodyNodeT *_ptr)
Assignment operator for raw BodyNode pointers.
Definition BodyNodePtr.hpp:251
TemplateWeakBodyNodePtr()
Default constructor.
Definition BodyNodePtr.hpp:230
TemplateWeakBodyNodePtr(const TemplateWeakBodyNodePtr< OtherBodyNodeT > &_weakPtr)
Constructor that takes in a WeakBodyNodePtr.
Definition BodyNodePtr.hpp:243
bool expired() const
Returns true if this WeakBodyNodePtr is referencing a nullptr or a pointer which has been deleted.
Definition BodyNodePtr.hpp:332
TemplateWeakBodyNodePtr & operator=(const TemplateWeakBodyNodePtr< OtherBodyNodeT > &_weakPtr)
Assignment operator for WeakBodyNodePtrs.
Definition BodyNodePtr.hpp:259
std::shared_ptr< MutexedWeakSkeletonPtr > mLocker
A shared_ptr that allows the WeakBodyNodePtr to know whether it can lock into a BodyNodePtr.
Definition BodyNodePtr.hpp:353
Definition BulletCollisionDetector.cpp:65
Definition BodyNodePtr.hpp:47
std::weak_ptr< const Skeleton > mSkeleton
Definition BodyNodePtr.hpp:49
std::mutex mMutex
Definition BodyNodePtr.hpp:48