godot-module-template/engine/thirdparty/jolt_physics/Jolt/Physics/Body/BodyLockInterface.h

135 lines
4.7 KiB
C++

// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#pragma once
#include <Jolt/Physics/Body/Body.h>
#include <Jolt/Physics/Body/BodyManager.h>
#include <Jolt/Physics/PhysicsLock.h>
#include <Jolt/Core/Mutex.h>
JPH_NAMESPACE_BEGIN
/// Base class interface for locking a body. Usually you will use BodyLockRead / BodyLockWrite / BodyLockMultiRead / BodyLockMultiWrite instead.
class BodyLockInterface : public NonCopyable
{
public:
/// Redefine MutexMask
using MutexMask = BodyManager::MutexMask;
/// Constructor
explicit BodyLockInterface(BodyManager &inBodyManager) : mBodyManager(inBodyManager) { }
virtual ~BodyLockInterface() = default;
///@name Locking functions
///@{
virtual SharedMutex * LockRead(const BodyID &inBodyID) const = 0;
virtual void UnlockRead(SharedMutex *inMutex) const = 0;
virtual SharedMutex * LockWrite(const BodyID &inBodyID) const = 0;
virtual void UnlockWrite(SharedMutex *inMutex) const = 0;
///@}
/// Get the mask needed to lock all bodies
inline MutexMask GetAllBodiesMutexMask() const
{
return mBodyManager.GetAllBodiesMutexMask();
}
///@name Batch locking functions
///@{
virtual MutexMask GetMutexMask(const BodyID *inBodies, int inNumber) const = 0;
virtual void LockRead(MutexMask inMutexMask) const = 0;
virtual void UnlockRead(MutexMask inMutexMask) const = 0;
virtual void LockWrite(MutexMask inMutexMask) const = 0;
virtual void UnlockWrite(MutexMask inMutexMask) const = 0;
///@}
/// Convert body ID to body
inline Body * TryGetBody(const BodyID &inBodyID) const { return mBodyManager.TryGetBody(inBodyID); }
protected:
BodyManager & mBodyManager;
};
/// Implementation that performs no locking (assumes the lock has already been taken)
class BodyLockInterfaceNoLock final : public BodyLockInterface
{
public:
using BodyLockInterface::BodyLockInterface;
///@name Locking functions
virtual SharedMutex * LockRead([[maybe_unused]] const BodyID &inBodyID) const override { return nullptr; }
virtual void UnlockRead([[maybe_unused]] SharedMutex *inMutex) const override { /* Nothing to do */ }
virtual SharedMutex * LockWrite([[maybe_unused]] const BodyID &inBodyID) const override { return nullptr; }
virtual void UnlockWrite([[maybe_unused]] SharedMutex *inMutex) const override { /* Nothing to do */ }
///@name Batch locking functions
virtual MutexMask GetMutexMask([[maybe_unused]] const BodyID *inBodies, [[maybe_unused]] int inNumber) const override { return 0; }
virtual void LockRead([[maybe_unused]] MutexMask inMutexMask) const override { /* Nothing to do */ }
virtual void UnlockRead([[maybe_unused]] MutexMask inMutexMask) const override { /* Nothing to do */ }
virtual void LockWrite([[maybe_unused]] MutexMask inMutexMask) const override { /* Nothing to do */ }
virtual void UnlockWrite([[maybe_unused]] MutexMask inMutexMask) const override { /* Nothing to do */ }
};
/// Implementation that uses the body manager to lock the correct mutex for a body
class BodyLockInterfaceLocking final : public BodyLockInterface
{
public:
using BodyLockInterface::BodyLockInterface;
///@name Locking functions
virtual SharedMutex * LockRead(const BodyID &inBodyID) const override
{
SharedMutex &mutex = mBodyManager.GetMutexForBody(inBodyID);
PhysicsLock::sLockShared(mutex JPH_IF_ENABLE_ASSERTS(, &mBodyManager, EPhysicsLockTypes::PerBody));
return &mutex;
}
virtual void UnlockRead(SharedMutex *inMutex) const override
{
PhysicsLock::sUnlockShared(*inMutex JPH_IF_ENABLE_ASSERTS(, &mBodyManager, EPhysicsLockTypes::PerBody));
}
virtual SharedMutex * LockWrite(const BodyID &inBodyID) const override
{
SharedMutex &mutex = mBodyManager.GetMutexForBody(inBodyID);
PhysicsLock::sLock(mutex JPH_IF_ENABLE_ASSERTS(, &mBodyManager, EPhysicsLockTypes::PerBody));
return &mutex;
}
virtual void UnlockWrite(SharedMutex *inMutex) const override
{
PhysicsLock::sUnlock(*inMutex JPH_IF_ENABLE_ASSERTS(, &mBodyManager, EPhysicsLockTypes::PerBody));
}
///@name Batch locking functions
virtual MutexMask GetMutexMask(const BodyID *inBodies, int inNumber) const override
{
return mBodyManager.GetMutexMask(inBodies, inNumber);
}
virtual void LockRead(MutexMask inMutexMask) const override
{
mBodyManager.LockRead(inMutexMask);
}
virtual void UnlockRead(MutexMask inMutexMask) const override
{
mBodyManager.UnlockRead(inMutexMask);
}
virtual void LockWrite(MutexMask inMutexMask) const override
{
mBodyManager.LockWrite(inMutexMask);
}
virtual void UnlockWrite(MutexMask inMutexMask) const override
{
mBodyManager.UnlockWrite(inMutexMask);
}
};
JPH_NAMESPACE_END