Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Body/BodyLock.h
9912 views
1
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3
// SPDX-License-Identifier: MIT
4
5
#pragma once
6
7
#include <Jolt/Physics/Body/BodyLockInterface.h>
8
9
JPH_NAMESPACE_BEGIN
10
11
/// Base class for locking bodies for the duration of the scope of this class (do not use directly)
12
template <bool Write, class BodyType>
13
class BodyLockBase : public NonCopyable
14
{
15
public:
16
/// Constructor will lock the body
17
BodyLockBase(const BodyLockInterface &inBodyLockInterface, const BodyID &inBodyID) :
18
mBodyLockInterface(inBodyLockInterface)
19
{
20
if (inBodyID == BodyID())
21
{
22
// Invalid body id
23
mBodyLockMutex = nullptr;
24
mBody = nullptr;
25
}
26
else
27
{
28
// Get mutex
29
mBodyLockMutex = Write? inBodyLockInterface.LockWrite(inBodyID) : inBodyLockInterface.LockRead(inBodyID);
30
31
// Get a reference to the body or nullptr when it is no longer valid
32
mBody = inBodyLockInterface.TryGetBody(inBodyID);
33
}
34
}
35
36
/// Explicitly release the lock (normally this is done in the destructor)
37
inline void ReleaseLock()
38
{
39
if (mBodyLockMutex != nullptr)
40
{
41
if (Write)
42
mBodyLockInterface.UnlockWrite(mBodyLockMutex);
43
else
44
mBodyLockInterface.UnlockRead(mBodyLockMutex);
45
46
mBodyLockMutex = nullptr;
47
mBody = nullptr;
48
}
49
}
50
51
/// Destructor will unlock the body
52
~BodyLockBase()
53
{
54
ReleaseLock();
55
}
56
57
/// Test if the lock was successful (if the body ID was valid)
58
inline bool Succeeded() const
59
{
60
return mBody != nullptr;
61
}
62
63
/// Test if the lock was successful (if the body ID was valid) and the body is still in the broad phase
64
inline bool SucceededAndIsInBroadPhase() const
65
{
66
return mBody != nullptr && mBody->IsInBroadPhase();
67
}
68
69
/// Access the body
70
inline BodyType & GetBody() const
71
{
72
JPH_ASSERT(mBody != nullptr, "Should check Succeeded() first");
73
return *mBody;
74
}
75
76
private:
77
const BodyLockInterface & mBodyLockInterface;
78
SharedMutex * mBodyLockMutex;
79
BodyType * mBody;
80
};
81
82
/// A body lock takes a body ID and locks the underlying body so that other threads cannot access its members
83
///
84
/// The common usage pattern is:
85
///
86
/// BodyLockInterface lock_interface = physics_system.GetBodyLockInterface(); // Or non-locking interface if the lock is already taken
87
/// BodyID body_id = ...; // Obtain ID to body
88
///
89
/// // Scoped lock
90
/// {
91
/// BodyLockRead lock(lock_interface, body_id);
92
/// if (lock.Succeeded()) // body_id may no longer be valid
93
/// {
94
/// const Body &body = lock.GetBody();
95
///
96
/// // Do something with body
97
/// ...
98
/// }
99
/// }
100
class BodyLockRead : public BodyLockBase<false, const Body>
101
{
102
using BodyLockBase::BodyLockBase;
103
};
104
105
/// Specialization that locks a body for writing to. @see BodyLockRead for usage patterns.
106
class BodyLockWrite : public BodyLockBase<true, Body>
107
{
108
using BodyLockBase::BodyLockBase;
109
};
110
111
JPH_NAMESPACE_END
112
113