BodyLockInterface.h 4.3 KB

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