1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-05 15:55:45 +00:00

Add classes to encapsulate value guarded by mutex

This commit is contained in:
elsid 2018-09-29 20:36:42 +03:00
parent 1a27489904
commit cf4066751c
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40
3 changed files with 69 additions and 42 deletions

View File

@ -6,6 +6,7 @@
#include "navmeshcacheitem.hpp"
#include "tileposition.hpp"
#include "tilebounds.hpp"
#include "sharednavmesh.hpp"
#include <osg/Vec3f>
@ -16,11 +17,8 @@ class dtNavMesh;
namespace DetourNavigator
{
class RecastMesh;
class SharedNavMesh;
struct Settings;
using NavMeshPtr = std::shared_ptr<dtNavMesh>;
enum class UpdateNavMeshStatus
{
ignore,

View File

@ -1,6 +1,8 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_SHAREDNAVMESH_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_SHAREDNAVMESH_H
#include <components/misc/guarded.hpp>
#include <mutex>
#include <memory>
@ -9,45 +11,7 @@ class dtNavMesh;
namespace DetourNavigator
{
using NavMeshPtr = std::shared_ptr<dtNavMesh>;
class LockedSharedNavMesh
{
public:
LockedSharedNavMesh(std::mutex& mutex, const NavMeshPtr& value)
: mLock(new std::lock_guard<std::mutex>(mutex)), mValue(value)
{}
dtNavMesh* operator ->() const
{
return mValue.get();
}
dtNavMesh& operator *() const
{
return *mValue;
}
private:
std::unique_ptr<const std::lock_guard<std::mutex>> mLock;
NavMeshPtr mValue;
};
class SharedNavMesh
{
public:
SharedNavMesh(const NavMeshPtr& value)
: mMutex(std::make_shared<std::mutex>()), mValue(value)
{}
LockedSharedNavMesh lock() const
{
return LockedSharedNavMesh(*mMutex, mValue);
}
private:
std::shared_ptr<std::mutex> mMutex;
NavMeshPtr mValue;
};
using SharedNavMesh = Misc::SharedGuarded<dtNavMesh>;
}
#endif

View File

@ -0,0 +1,65 @@
#ifndef OPENMW_COMPONENTS_MISC_GUARDED_H
#define OPENMW_COMPONENTS_MISC_GUARDED_H
#include <mutex>
#include <memory>
namespace Misc
{
template <class T>
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<std::mutex> mLock;
std::reference_wrapper<T> mValue;
};
template <class T>
class SharedGuarded
{
public:
SharedGuarded()
: mMutex(std::make_shared<std::mutex>())
{}
SharedGuarded(std::shared_ptr<T> value)
: mMutex(std::make_shared<std::mutex>()), mValue(std::move(value))
{}
Locked<T> lock() const
{
return Locked<T>(*mMutex, *mValue);
}
Locked<const T> lockConst() const
{
return Locked<const T>(*mMutex, *mValue);
}
private:
std::shared_ptr<std::mutex> mMutex;
std::shared_ptr<T> mValue;
};
}
#endif