diff --git a/components/detournavigator/makenavmesh.hpp b/components/detournavigator/makenavmesh.hpp index f9c304ee99..963e0daa8b 100644 --- a/components/detournavigator/makenavmesh.hpp +++ b/components/detournavigator/makenavmesh.hpp @@ -6,6 +6,7 @@ #include "navmeshcacheitem.hpp" #include "tileposition.hpp" #include "tilebounds.hpp" +#include "sharednavmesh.hpp" #include @@ -16,11 +17,8 @@ class dtNavMesh; namespace DetourNavigator { class RecastMesh; - class SharedNavMesh; struct Settings; - using NavMeshPtr = std::shared_ptr; - enum class UpdateNavMeshStatus { ignore, diff --git a/components/detournavigator/sharednavmesh.hpp b/components/detournavigator/sharednavmesh.hpp index 657973c2f6..8045434a18 100644 --- a/components/detournavigator/sharednavmesh.hpp +++ b/components/detournavigator/sharednavmesh.hpp @@ -1,6 +1,8 @@ #ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_SHAREDNAVMESH_H #define OPENMW_COMPONENTS_DETOURNAVIGATOR_SHAREDNAVMESH_H +#include + #include #include @@ -9,45 +11,7 @@ class dtNavMesh; namespace DetourNavigator { using NavMeshPtr = std::shared_ptr; - - class LockedSharedNavMesh - { - public: - LockedSharedNavMesh(std::mutex& mutex, const NavMeshPtr& value) - : mLock(new std::lock_guard(mutex)), mValue(value) - {} - - dtNavMesh* operator ->() const - { - return mValue.get(); - } - - dtNavMesh& operator *() const - { - return *mValue; - } - - private: - std::unique_ptr> mLock; - NavMeshPtr mValue; - }; - - class SharedNavMesh - { - public: - SharedNavMesh(const NavMeshPtr& value) - : mMutex(std::make_shared()), mValue(value) - {} - - LockedSharedNavMesh lock() const - { - return LockedSharedNavMesh(*mMutex, mValue); - } - - private: - std::shared_ptr mMutex; - NavMeshPtr mValue; - }; + using SharedNavMesh = Misc::SharedGuarded; } #endif diff --git a/components/misc/guarded.hpp b/components/misc/guarded.hpp new file mode 100644 index 0000000000..f70f5e4c5e --- /dev/null +++ b/components/misc/guarded.hpp @@ -0,0 +1,65 @@ +#ifndef OPENMW_COMPONENTS_MISC_GUARDED_H +#define OPENMW_COMPONENTS_MISC_GUARDED_H + +#include +#include + +namespace Misc +{ + template + class Locked + { + public: + Locked(std::mutex& mutex, T& value) + : mLock(mutex), mValue(value) + {} + + T& get() const + { + return mValue.get(); + } + + T* operator ->() const + { + return std::addressof(get()); + } + + T& operator *() const + { + return get(); + } + + private: + std::unique_lock mLock; + std::reference_wrapper mValue; + }; + + template + class SharedGuarded + { + public: + SharedGuarded() + : mMutex(std::make_shared()) + {} + + SharedGuarded(std::shared_ptr value) + : mMutex(std::make_shared()), mValue(std::move(value)) + {} + + Locked lock() const + { + return Locked(*mMutex, *mValue); + } + + Locked lockConst() const + { + return Locked(*mMutex, *mValue); + } + + private: + std::shared_ptr mMutex; + std::shared_ptr mValue; + }; +} + +#endif