diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index 9bc6f942f0..529316adab 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -1,4 +1,8 @@ #include +#include +#include +#include +#include #include #include @@ -28,6 +32,15 @@ namespace { + template + std::optional> makeExclusiveLock(Mutex& mutex, int threadCount) + { + assert(threadCount >= 0); + if (threadCount > 0) + return std::unique_lock(mutex); + return {}; + } + /// @brief A scoped lock that is either exclusive or inexistent depending on configuration template class MaybeExclusiveLock @@ -35,24 +48,23 @@ namespace public: /// @param mutex a mutex /// @param threadCount decide wether the excluse lock will be taken - MaybeExclusiveLock(Mutex& mutex, int threadCount) : mMutex(mutex), mThreadCount(threadCount) - { - assert(threadCount >= 0); - if (mThreadCount > 0) - mMutex.lock(); - } - - ~MaybeExclusiveLock() - { - if (mThreadCount > 0) - mMutex.unlock(); - } + explicit MaybeExclusiveLock(Mutex& mutex, int threadCount) + : mImpl(makeExclusiveLock(mutex, threadCount)) + {} private: - Mutex& mMutex; - unsigned int mThreadCount; + std::optional> mImpl; }; + template + std::optional> makeSharedLock(Mutex& mutex, int threadCount) + { + assert(threadCount >= 0); + if (threadCount > 0) + return std::shared_lock(mutex); + return {}; + } + /// @brief A scoped lock that is either shared or inexistent depending on configuration template class MaybeSharedLock @@ -60,24 +72,25 @@ namespace public: /// @param mutex a shared mutex /// @param threadCount decide wether the shared lock will be taken - MaybeSharedLock(Mutex& mutex, int threadCount) : mMutex(mutex), mThreadCount(threadCount) - { - assert(threadCount >= 0); - if (mThreadCount > 0) - mMutex.lock_shared(); - } - - ~MaybeSharedLock() - { - if (mThreadCount > 0) - mMutex.unlock_shared(); - } + explicit MaybeSharedLock(Mutex& mutex, int threadCount) + : mImpl(makeSharedLock(mutex, threadCount)) + {} private: - Mutex& mMutex; - unsigned int mThreadCount; + std::optional> mImpl; }; + template + std::variant, std::shared_lock> makeLock(Mutex& mutex, int threadCount) + { + assert(threadCount >= 0); + if (threadCount > 1) + return std::shared_lock(mutex); + if (threadCount == 1) + return std::unique_lock(mutex); + return std::monostate {}; + } + /// @brief A scoped lock that is either shared, exclusive or inexistent depending on configuration template class MaybeLock @@ -85,25 +98,11 @@ namespace public: /// @param mutex a shared mutex /// @param threadCount decide wether the lock will be shared, exclusive or inexistent - MaybeLock(Mutex& mutex, int threadCount) : mMutex(mutex), mThreadCount(threadCount) - { - assert(threadCount >= 0); - if (mThreadCount > 1) - mMutex.lock_shared(); - else if(mThreadCount == 1) - mMutex.lock(); - } + explicit MaybeLock(Mutex& mutex, int threadCount) + : mImpl(makeLock(mutex, threadCount)) {} - ~MaybeLock() - { - if (mThreadCount > 1) - mMutex.unlock_shared(); - else if(mThreadCount == 1) - mMutex.unlock(); - } private: - Mutex& mMutex; - unsigned int mThreadCount; + std::variant, std::shared_lock> mImpl; }; bool isUnderWater(const MWPhysics::ActorFrameData& actorData)