Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Body/BodyLockMulti.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 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/// Destructor will unlock the bodies36~BodyLockMultiBase()37{38if (mMutexMask != 0)39{40if (Write)41mBodyLockInterface.UnlockWrite(mMutexMask);42else43mBodyLockInterface.UnlockRead(mMutexMask);44}45}4647/// Access the body (returns null if body was not properly locked)48inline BodyType * GetBody(int inBodyIndex) const49{50// Range check51JPH_ASSERT(inBodyIndex >= 0 && inBodyIndex < mNumBodyIDs);5253// Get body ID54const BodyID &body_id = mBodyIDs[inBodyIndex];55if (body_id.IsInvalid())56return nullptr;5758// Get a reference to the body or nullptr when it is no longer valid59return mBodyLockInterface.TryGetBody(body_id);60}6162private:63const BodyLockInterface & mBodyLockInterface;64MutexMask mMutexMask;65const BodyID * mBodyIDs;66int mNumBodyIDs;67};6869/// A multi body lock takes a number of body IDs and locks the underlying bodies so that other threads cannot access its members70///71/// The common usage pattern is:72///73/// BodyLockInterface lock_interface = physics_system.GetBodyLockInterface(); // Or non-locking interface if the lock is already taken74/// const BodyID *body_id = ...; // Obtain IDs to bodies75/// int num_body_ids = ...;76///77/// // Scoped lock78/// {79/// BodyLockMultiRead lock(lock_interface, body_ids, num_body_ids);80/// for (int i = 0; i < num_body_ids; ++i)81/// {82/// const Body *body = lock.GetBody(i);83/// if (body != nullptr)84/// {85/// const Body &body = lock.Body();86///87/// // Do something with body88/// ...89/// }90/// }91/// }92class BodyLockMultiRead : public BodyLockMultiBase<false, const Body>93{94using BodyLockMultiBase::BodyLockMultiBase;95};9697/// Specialization that locks multiple bodies for writing to. @see BodyLockMultiRead for usage patterns.98class BodyLockMultiWrite : public BodyLockMultiBase<true, Body>99{100using BodyLockMultiBase::BodyLockMultiBase;101};102103JPH_NAMESPACE_END104105106