BodyLockInterface.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Physics/Body/Body.h>
  6. #include <Jolt/Physics/Body/BodyManager.h>
  7. #include <Jolt/Physics/PhysicsLock.h>
  8. #include <Jolt/Core/Mutex.h>
  9. JPH_NAMESPACE_BEGIN
  10. /// Base class interface for locking a body. Usually you will use BodyLockRead / BodyLockWrite / BodyLockMultiRead / BodyLockMultiWrite instead.
  11. class BodyLockInterface : public NonCopyable
  12. {
  13. public:
  14. /// Redefine MutexMask
  15. using MutexMask = BodyManager::MutexMask;
  16. /// Constructor
  17. explicit BodyLockInterface(BodyManager &inBodyManager) : mBodyManager(inBodyManager) { }
  18. virtual ~BodyLockInterface() = default;
  19. ///@name Locking functions
  20. ///@{
  21. virtual SharedMutex * LockRead(const BodyID &inBodyID) const = 0;
  22. virtual void UnlockRead(SharedMutex *inMutex) const = 0;
  23. virtual SharedMutex * LockWrite(const BodyID &inBodyID) const = 0;
  24. virtual void UnlockWrite(SharedMutex *inMutex) const = 0;
  25. ///@}
  26. /// Get the mask needed to lock all bodies
  27. inline MutexMask GetAllBodiesMutexMask() const
  28. {
  29. return mBodyManager.GetAllBodiesMutexMask();
  30. }
  31. ///@name Batch locking functions
  32. ///@{
  33. virtual MutexMask GetMutexMask(const BodyID *inBodies, int inNumber) const = 0;
  34. virtual void LockRead(MutexMask inMutexMask) const = 0;
  35. virtual void UnlockRead(MutexMask inMutexMask) const = 0;
  36. virtual void LockWrite(MutexMask inMutexMask) const = 0;
  37. virtual void UnlockWrite(MutexMask inMutexMask) const = 0;
  38. ///@}
  39. /// Convert body ID to body
  40. inline Body * TryGetBody(const BodyID &inBodyID) const { return mBodyManager.TryGetBody(inBodyID); }
  41. protected:
  42. BodyManager & mBodyManager;
  43. };
  44. /// Implementation that performs no locking (assumes the lock has already been taken)
  45. class BodyLockInterfaceNoLock final : public BodyLockInterface
  46. {
  47. public:
  48. using BodyLockInterface::BodyLockInterface;
  49. ///@name Locking functions
  50. virtual SharedMutex * LockRead(const BodyID &inBodyID) const override { return nullptr; }
  51. virtual void UnlockRead(SharedMutex *inMutex) const override { /* Nothing to do */ }
  52. virtual SharedMutex * LockWrite(const BodyID &inBodyID) const override { return nullptr; }
  53. virtual void UnlockWrite(SharedMutex *inMutex) const override { /* Nothing to do */ }
  54. ///@name Batch locking functions
  55. virtual MutexMask GetMutexMask(const BodyID *inBodies, int inNumber) const override { return 0; }
  56. virtual void LockRead(MutexMask inMutexMask) const override { /* Nothing to do */ }
  57. virtual void UnlockRead(MutexMask inMutexMask) const override { /* Nothing to do */ }
  58. virtual void LockWrite(MutexMask inMutexMask) const override { /* Nothing to do */ }
  59. virtual void UnlockWrite(MutexMask inMutexMask) const override { /* Nothing to do */ }
  60. };
  61. /// Implementation that uses the body manager to lock the correct mutex for a body
  62. class BodyLockInterfaceLocking final : public BodyLockInterface
  63. {
  64. public:
  65. using BodyLockInterface::BodyLockInterface;
  66. ///@name Locking functions
  67. virtual SharedMutex * LockRead(const BodyID &inBodyID) const override
  68. {
  69. SharedMutex &mutex = mBodyManager.GetMutexForBody(inBodyID);
  70. PhysicsLock::sLockShared(mutex JPH_IF_ENABLE_ASSERTS(, &mBodyManager, EPhysicsLockTypes::PerBody));
  71. return &mutex;
  72. }
  73. virtual void UnlockRead(SharedMutex *inMutex) const override
  74. {
  75. PhysicsLock::sUnlockShared(*inMutex JPH_IF_ENABLE_ASSERTS(, &mBodyManager, EPhysicsLockTypes::PerBody));
  76. }
  77. virtual SharedMutex * LockWrite(const BodyID &inBodyID) const override
  78. {
  79. SharedMutex &mutex = mBodyManager.GetMutexForBody(inBodyID);
  80. PhysicsLock::sLock(mutex JPH_IF_ENABLE_ASSERTS(, &mBodyManager, EPhysicsLockTypes::PerBody));
  81. return &mutex;
  82. }
  83. virtual void UnlockWrite(SharedMutex *inMutex) const override
  84. {
  85. PhysicsLock::sUnlock(*inMutex JPH_IF_ENABLE_ASSERTS(, &mBodyManager, EPhysicsLockTypes::PerBody));
  86. }
  87. ///@name Batch locking functions
  88. virtual MutexMask GetMutexMask(const BodyID *inBodies, int inNumber) const override
  89. {
  90. return mBodyManager.GetMutexMask(inBodies, inNumber);
  91. }
  92. virtual void LockRead(MutexMask inMutexMask) const override
  93. {
  94. mBodyManager.LockRead(inMutexMask);
  95. }
  96. virtual void UnlockRead(MutexMask inMutexMask) const override
  97. {
  98. mBodyManager.UnlockRead(inMutexMask);
  99. }
  100. virtual void LockWrite(MutexMask inMutexMask) const override
  101. {
  102. mBodyManager.LockWrite(inMutexMask);
  103. }
  104. virtual void UnlockWrite(MutexMask inMutexMask) const override
  105. {
  106. mBodyManager.UnlockWrite(inMutexMask);
  107. }
  108. };
  109. JPH_NAMESPACE_END