Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Body/BodyLockMulti.h
21647 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 multiple bodies for the duration of the scope of this class (do not use directly)
12
template <bool Write, class BodyType>
13
class BodyLockMultiBase : public NonCopyable
14
{
15
public:
16
/// Redefine MutexMask
17
using MutexMask = BodyLockInterface::MutexMask;
18
19
/// Constructor will lock the bodies
20
BodyLockMultiBase(const BodyLockInterface &inBodyLockInterface, const BodyID *inBodyIDs, int inNumber) :
21
mBodyLockInterface(inBodyLockInterface),
22
mMutexMask(inBodyLockInterface.GetMutexMask(inBodyIDs, inNumber)),
23
mBodyIDs(inBodyIDs),
24
mNumBodyIDs(inNumber)
25
{
26
if (mMutexMask != 0)
27
{
28
// Get mutex
29
if (Write)
30
inBodyLockInterface.LockWrite(mMutexMask);
31
else
32
inBodyLockInterface.LockRead(mMutexMask);
33
}
34
}
35
36
/// Explicitly release the locks on all bodies (normally this is done in the destructor)
37
inline void ReleaseLocks()
38
{
39
if (mMutexMask != 0)
40
{
41
if (Write)
42
mBodyLockInterface.UnlockWrite(mMutexMask);
43
else
44
mBodyLockInterface.UnlockRead(mMutexMask);
45
46
mMutexMask = 0;
47
mBodyIDs = nullptr;
48
mNumBodyIDs = 0;
49
}
50
}
51
52
/// Destructor will unlock the bodies
53
~BodyLockMultiBase()
54
{
55
ReleaseLocks();
56
}
57
58
/// Returns the number of bodies that were locked
59
inline int GetNumBodies() const
60
{
61
return mNumBodyIDs;
62
}
63
64
/// Access the body (returns null if body was not properly locked)
65
inline BodyType * GetBody(int inBodyIndex) const
66
{
67
// Range check
68
JPH_ASSERT(inBodyIndex >= 0 && inBodyIndex < mNumBodyIDs);
69
70
// Get body ID
71
const BodyID &body_id = mBodyIDs[inBodyIndex];
72
if (body_id.IsInvalid())
73
return nullptr;
74
75
// Get a reference to the body or nullptr when it is no longer valid
76
return mBodyLockInterface.TryGetBody(body_id);
77
}
78
79
private:
80
const BodyLockInterface & mBodyLockInterface;
81
MutexMask mMutexMask;
82
const BodyID * mBodyIDs;
83
int mNumBodyIDs;
84
};
85
86
/// A multi body lock takes a number of body IDs and locks the underlying bodies so that other threads cannot access its members
87
///
88
/// The common usage pattern is:
89
///
90
/// BodyLockInterface lock_interface = physics_system.GetBodyLockInterface(); // Or non-locking interface if the lock is already taken
91
/// const BodyID *body_id = ...; // Obtain IDs to bodies
92
/// int num_body_ids = ...;
93
///
94
/// // Scoped lock
95
/// {
96
/// BodyLockMultiRead lock(lock_interface, body_ids, num_body_ids);
97
/// for (int i = 0; i < num_body_ids; ++i)
98
/// {
99
/// const Body *body = lock.GetBody(i);
100
/// if (body != nullptr)
101
/// {
102
/// const Body &body = lock.Body();
103
///
104
/// // Do something with body
105
/// ...
106
/// }
107
/// }
108
/// }
109
class BodyLockMultiRead : public BodyLockMultiBase<false, const Body>
110
{
111
using BodyLockMultiBase::BodyLockMultiBase;
112
};
113
114
/// Specialization that locks multiple bodies for writing to. @see BodyLockMultiRead for usage patterns.
115
class BodyLockMultiWrite : public BodyLockMultiBase<true, Body>
116
{
117
using BodyLockMultiBase::BodyLockMultiBase;
118
};
119
120
JPH_NAMESPACE_END
121
122