DART 6.12.2
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:
113 TemplateBodyNodePtr() : mPtr(nullptr) {}
114
117 TemplateBodyNodePtr(BodyNodeT* _ptr) : mPtr(nullptr)
118 {
119 set(_ptr);
120 }
121
124 {
125 set(_bnp.get());
126 }
127
129 template <class OtherBodyNodeT>
131 : mPtr(nullptr)
132 {
133 set(_bnp.get());
134 }
135
138 {
139 set(nullptr);
140 }
141
144 {
145 set(bnp.get());
146 return *this;
147 }
148
150 template <class OtherBodyNodeT>
153 {
154 set(_bnp.get());
155 return *this;
156 }
157
160 {
161 set(_ptr);
162 return *this;
163 }
164
166 operator BodyNodeT*() const
167 {
168 return mPtr;
169 }
170
172 BodyNodeT& operator*() const
173 {
174 return *mPtr;
175 }
176
178 BodyNodeT* operator->() const
179 {
180 return mPtr;
181 }
182
184 BodyNodeT* get() const
185 {
186 return mPtr;
187 }
188
190 void set(BodyNodeT* _ptr)
191 {
192 if (mPtr == _ptr)
193 return;
194
195 if (nullptr != mPtr)
196 {
197 static_cast<const SkeletonRefCountingBase*>(mPtr)
198 ->decrementReferenceCount();
199 }
200
201 if (nullptr != _ptr)
202 {
203 static_cast<const SkeletonRefCountingBase*>(_ptr)
204 ->incrementReferenceCount();
205 }
206
207 mPtr = _ptr;
208 }
209
210private:
212 BodyNodeT* mPtr;
213};
214
220template <class BodyNodeT>
222{
223public:
224 template <class>
226
229
232 TemplateWeakBodyNodePtr(BodyNodeT* _ptr) : mPtr(nullptr)
233 {
234 set(_ptr);
235 }
236
238 template <class OtherBodyNodeT>
241 : mPtr(nullptr)
242 {
243 set(_weakPtr);
244 }
245
248 {
249 set(_ptr);
250 return *this;
251 }
252
254 template <class OtherBodyNodeT>
257 {
258 set(_weakPtr);
259 return *this;
260 }
261
270 {
271 if (nullptr == mLocker)
272 return nullptr;
273
274 // We do not use the expired() function here, because we want to ensure that
275 // the Skeleton's reference count remains up while we create the strong
276 // BodyNodePtr that we're going to return.
277 std::lock_guard<std::mutex> lock(mLocker->mMutex);
278 std::shared_ptr<const Skeleton> skeleton = mLocker->mSkeleton.lock();
279 if (nullptr == skeleton)
280 return nullptr;
281
283 }
284
286 void set(BodyNodeT* _ptr)
287 {
288 mPtr = _ptr;
289
290 if (nullptr == mPtr)
291 mLocker = nullptr;
292 else
293 mLocker
294 = static_cast<const SkeletonRefCountingBase*>(_ptr)->mLockedSkeleton;
295 }
296
299 template <class OtherBodyNodeT>
301 {
302 if (nullptr == _weakPtr.mLocker)
303 {
304 set(nullptr);
305 return;
306 }
307
308 std::lock_guard<std::mutex> lock(_weakPtr.mLocker->mMutex);
309 std::shared_ptr<const Skeleton> skeleton
310 = _weakPtr.mLocker->mSkeleton.lock();
311 if (nullptr == skeleton)
312 {
313 set(nullptr);
314 return;
315 }
316
317 set(_weakPtr.mPtr);
318 }
319
328 bool expired() const
329 {
330 if (nullptr == mLocker)
331 return true;
332
333 // It is okay for 'lock' to go "unused", because it is managed by RAII after
334 // it has been initialized
335 std::lock_guard<std::mutex> lock(mLocker->mMutex);
336 std::shared_ptr<const Skeleton> skeleton = mLocker->mSkeleton.lock();
337 if (nullptr == skeleton)
338 return true;
339
340 return false;
341 }
342
343private:
345 BodyNodeT* mPtr;
346
349 std::shared_ptr<MutexedWeakSkeletonPtr> mLocker;
350};
351
352} // namespace dynamics
353} // namespace dart
354
355#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:178
TemplateBodyNodePtr & operator=(const TemplateBodyNodePtr &bnp)
User defined assignment operator.
Definition BodyNodePtr.hpp:143
BodyNodeT * mPtr
Raw pointer for the BodyNode that this BodyNodePtr references.
Definition BodyNodePtr.hpp:212
TemplateBodyNodePtr(const TemplateBodyNodePtr< OtherBodyNodeT > &_bnp)
Templated constructor for copying other BodyNodePtrs.
Definition BodyNodePtr.hpp:130
TemplateBodyNodePtr()
Default constructor.
Definition BodyNodePtr.hpp:113
void set(BodyNodeT *_ptr)
Set the BodyNode for this BodyNodePtr.
Definition BodyNodePtr.hpp:190
BodyNodeT & operator*() const
Dereferencing operator.
Definition BodyNodePtr.hpp:172
TemplateBodyNodePtr(BodyNodeT *_ptr)
Typical constructor.
Definition BodyNodePtr.hpp:117
TemplateBodyNodePtr(const TemplateBodyNodePtr &_bnp)
User defined copy-constructor.
Definition BodyNodePtr.hpp:123
~TemplateBodyNodePtr()
Destructor. Releases the BodyNode reference before being destroyed.
Definition BodyNodePtr.hpp:137
TemplateBodyNodePtr & operator=(BodyNodeT *_ptr)
Assignment operator.
Definition BodyNodePtr.hpp:159
TemplateBodyNodePtr & operator=(const TemplateBodyNodePtr< OtherBodyNodeT > &_bnp)
Change the BodyNode that this BodyNodePtr references.
Definition BodyNodePtr.hpp:151
BodyNodeT * get() const
Get the raw BodyNode pointer.
Definition BodyNodePtr.hpp:184
TemplateWeakBodyNodePtr is a templated class that enables users to create a non-reference-holding Wea...
Definition BodyNodePtr.hpp:222
TemplateBodyNodePtr< BodyNodeT > lock() const
Locks the BodyNode reference to ensure that the referenced BodyNode (1) is currently still available,...
Definition BodyNodePtr.hpp:269
void set(BodyNodeT *_ptr)
Set the BodyNode for this WeakBodyNodePtr.
Definition BodyNodePtr.hpp:286
BodyNodeT * mPtr
Raw pointer for the BodyNode that this WeakBodyNodePtr references.
Definition BodyNodePtr.hpp:345
TemplateWeakBodyNodePtr(BodyNodeT *_ptr)
Typical constructor.
Definition BodyNodePtr.hpp:232
void set(const TemplateWeakBodyNodePtr< OtherBodyNodeT > &_weakPtr)
Attempt to set the BodyNode for this WeakBodyNodePtr based on another WeakBodyNodePtr.
Definition BodyNodePtr.hpp:300
TemplateWeakBodyNodePtr & operator=(BodyNodeT *_ptr)
Assignment operator for raw BodyNode pointers.
Definition BodyNodePtr.hpp:247
TemplateWeakBodyNodePtr()
Default constructor.
Definition BodyNodePtr.hpp:228
TemplateWeakBodyNodePtr(const TemplateWeakBodyNodePtr< OtherBodyNodeT > &_weakPtr)
Constructor that takes in a WeakBodyNodePtr.
Definition BodyNodePtr.hpp:239
bool expired() const
Returns true if this WeakBodyNodePtr is referencing a nullptr or a pointer which has been deleted.
Definition BodyNodePtr.hpp:328
TemplateWeakBodyNodePtr & operator=(const TemplateWeakBodyNodePtr< OtherBodyNodeT > &_weakPtr)
Assignment operator for WeakBodyNodePtrs.
Definition BodyNodePtr.hpp:255
std::shared_ptr< MutexedWeakSkeletonPtr > mLocker
A shared_ptr that allows the WeakBodyNodePtr to know whether it can lock into a BodyNodePtr.
Definition BodyNodePtr.hpp:349
Definition BulletCollisionDetector.cpp:60
Definition BodyNodePtr.hpp:47
std::weak_ptr< const Skeleton > mSkeleton
Definition BodyNodePtr.hpp:49
std::mutex mMutex
Definition BodyNodePtr.hpp:48