Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Body/BodyLockMulti.h
21647 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Physics/Body/BodyLockInterface.h>78JPH_NAMESPACE_BEGIN910/// Base class for locking multiple bodies for the duration of the scope of this class (do not use directly)11template <bool Write, class BodyType>12class BodyLockMultiBase : public NonCopyable13{14public:15/// Redefine MutexMask16using MutexMask = BodyLockInterface::MutexMask;1718/// Constructor will lock the bodies19BodyLockMultiBase(const BodyLockInterface &inBodyLockInterface, const BodyID *inBodyIDs, int inNumber) :20mBodyLockInterface(inBodyLockInterface),21mMutexMask(inBodyLockInterface.GetMutexMask(inBodyIDs, inNumber)),22mBodyIDs(inBodyIDs),23mNumBodyIDs(inNumber)24{25if (mMutexMask != 0)26{27// Get mutex28if (Write)29inBodyLockInterface.LockWrite(mMutexMask);30else31inBodyLockInterface.LockRead(mMutexMask);32}33}3435/// Explicitly release the locks on all bodies (normally this is done in the destructor)36inline void ReleaseLocks()37{38if (mMutexMask != 0)39{40if (Write)41mBodyLockInterface.UnlockWrite(mMutexMask);42else43mBodyLockInterface.UnlockRead(mMutexMask);4445mMutexMask = 0;46mBodyIDs = nullptr;47mNumBodyIDs = 0;48}49}5051/// Destructor will unlock the bodies52~BodyLockMultiBase()53{54ReleaseLocks();55}5657/// Returns the number of bodies that were locked58inline int GetNumBodies() const59{60return mNumBodyIDs;61}6263/// Access the body (returns null if body was not properly locked)64inline BodyType * GetBody(int inBodyIndex) const65{66// Range check67JPH_ASSERT(inBodyIndex >= 0 && inBodyIndex < mNumBodyIDs);6869// Get body ID70const BodyID &body_id = mBodyIDs[inBodyIndex];71if (body_id.IsInvalid())72return nullptr;7374// Get a reference to the body or nullptr when it is no longer valid75return mBodyLockInterface.TryGetBody(body_id);76}7778private:79const BodyLockInterface & mBodyLockInterface;80MutexMask mMutexMask;81const BodyID * mBodyIDs;82int mNumBodyIDs;83};8485/// A multi body lock takes a number of body IDs and locks the underlying bodies so that other threads cannot access its members86///87/// The common usage pattern is:88///89/// BodyLockInterface lock_interface = physics_system.GetBodyLockInterface(); // Or non-locking interface if the lock is already taken90/// const BodyID *body_id = ...; // Obtain IDs to bodies91/// int num_body_ids = ...;92///93/// // Scoped lock94/// {95/// BodyLockMultiRead lock(lock_interface, body_ids, num_body_ids);96/// for (int i = 0; i < num_body_ids; ++i)97/// {98/// const Body *body = lock.GetBody(i);99/// if (body != nullptr)100/// {101/// const Body &body = lock.Body();102///103/// // Do something with body104/// ...105/// }106/// }107/// }108class BodyLockMultiRead : public BodyLockMultiBase<false, const Body>109{110using BodyLockMultiBase::BodyLockMultiBase;111};112113/// Specialization that locks multiple bodies for writing to. @see BodyLockMultiRead for usage patterns.114class BodyLockMultiWrite : public BodyLockMultiBase<true, Body>115{116using BodyLockMultiBase::BodyLockMultiBase;117};118119JPH_NAMESPACE_END120121122