Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Body/BodyLock.h
9912 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 bodies for the duration of the scope of this class (do not use directly)11template <bool Write, class BodyType>12class BodyLockBase : public NonCopyable13{14public:15/// Constructor will lock the body16BodyLockBase(const BodyLockInterface &inBodyLockInterface, const BodyID &inBodyID) :17mBodyLockInterface(inBodyLockInterface)18{19if (inBodyID == BodyID())20{21// Invalid body id22mBodyLockMutex = nullptr;23mBody = nullptr;24}25else26{27// Get mutex28mBodyLockMutex = Write? inBodyLockInterface.LockWrite(inBodyID) : inBodyLockInterface.LockRead(inBodyID);2930// Get a reference to the body or nullptr when it is no longer valid31mBody = inBodyLockInterface.TryGetBody(inBodyID);32}33}3435/// Explicitly release the lock (normally this is done in the destructor)36inline void ReleaseLock()37{38if (mBodyLockMutex != nullptr)39{40if (Write)41mBodyLockInterface.UnlockWrite(mBodyLockMutex);42else43mBodyLockInterface.UnlockRead(mBodyLockMutex);4445mBodyLockMutex = nullptr;46mBody = nullptr;47}48}4950/// Destructor will unlock the body51~BodyLockBase()52{53ReleaseLock();54}5556/// Test if the lock was successful (if the body ID was valid)57inline bool Succeeded() const58{59return mBody != nullptr;60}6162/// Test if the lock was successful (if the body ID was valid) and the body is still in the broad phase63inline bool SucceededAndIsInBroadPhase() const64{65return mBody != nullptr && mBody->IsInBroadPhase();66}6768/// Access the body69inline BodyType & GetBody() const70{71JPH_ASSERT(mBody != nullptr, "Should check Succeeded() first");72return *mBody;73}7475private:76const BodyLockInterface & mBodyLockInterface;77SharedMutex * mBodyLockMutex;78BodyType * mBody;79};8081/// A body lock takes a body ID and locks the underlying body so that other threads cannot access its members82///83/// The common usage pattern is:84///85/// BodyLockInterface lock_interface = physics_system.GetBodyLockInterface(); // Or non-locking interface if the lock is already taken86/// BodyID body_id = ...; // Obtain ID to body87///88/// // Scoped lock89/// {90/// BodyLockRead lock(lock_interface, body_id);91/// if (lock.Succeeded()) // body_id may no longer be valid92/// {93/// const Body &body = lock.GetBody();94///95/// // Do something with body96/// ...97/// }98/// }99class BodyLockRead : public BodyLockBase<false, const Body>100{101using BodyLockBase::BodyLockBase;102};103104/// Specialization that locks a body for writing to. @see BodyLockRead for usage patterns.105class BodyLockWrite : public BodyLockBase<true, Body>106{107using BodyLockBase::BodyLockBase;108};109110JPH_NAMESPACE_END111112113