mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-12 13:13:27 +00:00
Use ScopeGuarded instead of raw mutex
This commit is contained in:
parent
cf4066751c
commit
ae7285e960
@ -72,9 +72,7 @@ namespace DetourNavigator
|
|||||||
const std::shared_ptr<NavMeshCacheItem>& navMeshCacheItem, const TilePosition& playerTile,
|
const std::shared_ptr<NavMeshCacheItem>& navMeshCacheItem, const TilePosition& playerTile,
|
||||||
const std::map<TilePosition, ChangeType>& changedTiles)
|
const std::map<TilePosition, ChangeType>& changedTiles)
|
||||||
{
|
{
|
||||||
log("post jobs playerTile=", playerTile);
|
*mPlayerTile.lock() = playerTile;
|
||||||
|
|
||||||
setPlayerTile(playerTile);
|
|
||||||
|
|
||||||
if (changedTiles.empty())
|
if (changedTiles.empty())
|
||||||
return;
|
return;
|
||||||
@ -124,10 +122,10 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
const auto start = std::chrono::steady_clock::now();
|
const auto start = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
setFirstStart(start);
|
const auto firstStart = setFirstStart(start);
|
||||||
|
|
||||||
const auto recastMesh = mRecastMeshManager.get().getMesh(job.mChangedTile);
|
const auto recastMesh = mRecastMeshManager.get().getMesh(job.mChangedTile);
|
||||||
const auto playerTile = getPlayerTile();
|
const auto playerTile = *mPlayerTile.lockConst();
|
||||||
const auto offMeshConnections = mOffMeshConnectionsManager.get().get(job.mChangedTile);
|
const auto offMeshConnections = mOffMeshConnectionsManager.get().get(job.mChangedTile);
|
||||||
|
|
||||||
const auto status = updateNavMesh(job.mAgentHalfExtents, recastMesh.get(), job.mChangedTile, playerTile,
|
const auto status = updateNavMesh(job.mAgentHalfExtents, recastMesh.get(), job.mChangedTile, playerTile,
|
||||||
@ -143,7 +141,7 @@ namespace DetourNavigator
|
|||||||
" generation=", job.mNavMeshCacheItem->mGeneration,
|
" generation=", job.mNavMeshCacheItem->mGeneration,
|
||||||
" revision=", job.mNavMeshCacheItem->mNavMeshRevision,
|
" revision=", job.mNavMeshCacheItem->mNavMeshRevision,
|
||||||
" time=", std::chrono::duration_cast<FloatMs>(finish - start).count(), "ms",
|
" time=", std::chrono::duration_cast<FloatMs>(finish - start).count(), "ms",
|
||||||
" total_time=", std::chrono::duration_cast<FloatMs>(finish - getFirstStart()).count(), "ms");
|
" total_time=", std::chrono::duration_cast<FloatMs>(finish - firstStart).count(), "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<AsyncNavMeshUpdater::Job> AsyncNavMeshUpdater::getNextJob()
|
boost::optional<AsyncNavMeshUpdater::Job> AsyncNavMeshUpdater::getNextJob()
|
||||||
@ -188,28 +186,11 @@ namespace DetourNavigator
|
|||||||
writeToFile(*job.mNavMeshCacheItem->mValue.lock(), mSettings.get().mNavMeshPathPrefix, navMeshRevision);
|
writeToFile(*job.mNavMeshCacheItem->mValue.lock(), mSettings.get().mNavMeshPathPrefix, navMeshRevision);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point AsyncNavMeshUpdater::getFirstStart()
|
std::chrono::steady_clock::time_point AsyncNavMeshUpdater::setFirstStart(const std::chrono::steady_clock::time_point& value)
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mFirstStartMutex);
|
const auto locked = mFirstStart.lock();
|
||||||
return *mFirstStart;
|
if (!*locked)
|
||||||
}
|
*locked = value;
|
||||||
|
return *locked.get();
|
||||||
void AsyncNavMeshUpdater::setFirstStart(const std::chrono::steady_clock::time_point& value)
|
|
||||||
{
|
|
||||||
const std::lock_guard<std::mutex> lock(mFirstStartMutex);
|
|
||||||
if (!mFirstStart)
|
|
||||||
mFirstStart = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
TilePosition AsyncNavMeshUpdater::getPlayerTile()
|
|
||||||
{
|
|
||||||
const std::lock_guard<std::mutex> lock(mPlayerTileMutex);
|
|
||||||
return mPlayerTile;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsyncNavMeshUpdater::setPlayerTile(const TilePosition& value)
|
|
||||||
{
|
|
||||||
const std::lock_guard<std::mutex> lock(mPlayerTileMutex);
|
|
||||||
mPlayerTile = value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,10 +67,8 @@ namespace DetourNavigator
|
|||||||
std::condition_variable mDone;
|
std::condition_variable mDone;
|
||||||
Jobs mJobs;
|
Jobs mJobs;
|
||||||
std::map<osg::Vec3f, std::set<TilePosition>> mPushed;
|
std::map<osg::Vec3f, std::set<TilePosition>> mPushed;
|
||||||
std::mutex mPlayerTileMutex;
|
Misc::ScopeGuarded<TilePosition> mPlayerTile;
|
||||||
TilePosition mPlayerTile;
|
Misc::ScopeGuarded<boost::optional<std::chrono::steady_clock::time_point>> mFirstStart;
|
||||||
std::mutex mFirstStartMutex;
|
|
||||||
boost::optional<std::chrono::steady_clock::time_point> mFirstStart;
|
|
||||||
std::vector<std::thread> mThreads;
|
std::vector<std::thread> mThreads;
|
||||||
|
|
||||||
void process() throw();
|
void process() throw();
|
||||||
@ -79,17 +77,9 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
boost::optional<Job> getNextJob();
|
boost::optional<Job> getNextJob();
|
||||||
|
|
||||||
void notifyHasJob();
|
|
||||||
|
|
||||||
void writeDebugFiles(const Job& job, const RecastMesh* recastMesh) const;
|
void writeDebugFiles(const Job& job, const RecastMesh* recastMesh) const;
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point getFirstStart();
|
std::chrono::steady_clock::time_point setFirstStart(const std::chrono::steady_clock::time_point& value);
|
||||||
|
|
||||||
void setFirstStart(const std::chrono::steady_clock::time_point& value);
|
|
||||||
|
|
||||||
TilePosition getPlayerTile();
|
|
||||||
|
|
||||||
void setPlayerTile(const TilePosition& value);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "tilebounds.hpp"
|
#include "tilebounds.hpp"
|
||||||
|
|
||||||
#include <components/bullethelpers/operators.hpp>
|
#include <components/bullethelpers/operators.hpp>
|
||||||
|
#include <components/misc/guarded.hpp>
|
||||||
#include <components/osghelpers/operators.hpp>
|
#include <components/osghelpers/operators.hpp>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@ -11,7 +12,6 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -77,21 +77,19 @@ namespace DetourNavigator
|
|||||||
public:
|
public:
|
||||||
void setSink(std::unique_ptr<Sink> sink)
|
void setSink(std::unique_ptr<Sink> sink)
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> guard(mMutex);
|
*mSink.lock() = std::move(sink);
|
||||||
mSink = std::move(sink);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isEnabled() const
|
bool isEnabled()
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> guard(mMutex);
|
return bool(*mSink.lockConst());
|
||||||
return bool(mSink);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const std::string& text)
|
void write(const std::string& text)
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> guard(mMutex);
|
const auto sink = mSink.lock();
|
||||||
if (mSink)
|
if (*sink)
|
||||||
mSink->write(text);
|
sink.get()->write(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Log& instance()
|
static Log& instance()
|
||||||
@ -101,8 +99,7 @@ namespace DetourNavigator
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::mutex mMutex;
|
Misc::ScopeGuarded<std::unique_ptr<Sink>> mSink;
|
||||||
std::unique_ptr<Sink> mSink;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void write(std::ostream& stream)
|
inline void write(std::ostream& stream)
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "tileposition.hpp"
|
#include "tileposition.hpp"
|
||||||
#include "objectid.hpp"
|
#include "objectid.hpp"
|
||||||
|
|
||||||
|
#include <components/misc/guarded.hpp>
|
||||||
|
|
||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
@ -33,42 +35,42 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
bool add(const ObjectId id, const OffMeshConnection& value)
|
bool add(const ObjectId id, const OffMeshConnection& value)
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mMutex);
|
const auto values = mValues.lock();
|
||||||
|
|
||||||
if (!mValuesById.insert(std::make_pair(id, value)).second)
|
if (!values->mById.insert(std::make_pair(id, value)).second)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto startTilePosition = getTilePosition(mSettings, value.mStart);
|
const auto startTilePosition = getTilePosition(mSettings, value.mStart);
|
||||||
const auto endTilePosition = getTilePosition(mSettings, value.mEnd);
|
const auto endTilePosition = getTilePosition(mSettings, value.mEnd);
|
||||||
|
|
||||||
mValuesByTilePosition[startTilePosition].insert(id);
|
values->mByTilePosition[startTilePosition].insert(id);
|
||||||
|
|
||||||
if (startTilePosition != endTilePosition)
|
if (startTilePosition != endTilePosition)
|
||||||
mValuesByTilePosition[endTilePosition].insert(id);
|
values->mByTilePosition[endTilePosition].insert(id);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<OffMeshConnection> remove(const ObjectId id)
|
boost::optional<OffMeshConnection> remove(const ObjectId id)
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mMutex);
|
const auto values = mValues.lock();
|
||||||
|
|
||||||
const auto itById = mValuesById.find(id);
|
const auto itById = values->mById.find(id);
|
||||||
|
|
||||||
if (itById == mValuesById.end())
|
if (itById == values->mById.end())
|
||||||
return boost::none;
|
return boost::none;
|
||||||
|
|
||||||
const auto result = itById->second;
|
const auto result = itById->second;
|
||||||
|
|
||||||
mValuesById.erase(itById);
|
values->mById.erase(itById);
|
||||||
|
|
||||||
const auto startTilePosition = getTilePosition(mSettings, result.mStart);
|
const auto startTilePosition = getTilePosition(mSettings, result.mStart);
|
||||||
const auto endTilePosition = getTilePosition(mSettings, result.mEnd);
|
const auto endTilePosition = getTilePosition(mSettings, result.mEnd);
|
||||||
|
|
||||||
removeByTilePosition(startTilePosition, id);
|
removeByTilePosition(values->mByTilePosition, startTilePosition, id);
|
||||||
|
|
||||||
if (startTilePosition != endTilePosition)
|
if (startTilePosition != endTilePosition)
|
||||||
removeByTilePosition(endTilePosition, id);
|
removeByTilePosition(values->mByTilePosition, endTilePosition, id);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -77,18 +79,18 @@ namespace DetourNavigator
|
|||||||
{
|
{
|
||||||
std::vector<OffMeshConnection> result;
|
std::vector<OffMeshConnection> result;
|
||||||
|
|
||||||
const std::lock_guard<std::mutex> lock(mMutex);
|
const auto values = mValues.lock();
|
||||||
|
|
||||||
const auto itByTilePosition = mValuesByTilePosition.find(tilePosition);
|
const auto itByTilePosition = values->mByTilePosition.find(tilePosition);
|
||||||
|
|
||||||
if (itByTilePosition == mValuesByTilePosition.end())
|
if (itByTilePosition == values->mByTilePosition.end())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
std::for_each(itByTilePosition->second.begin(), itByTilePosition->second.end(),
|
std::for_each(itByTilePosition->second.begin(), itByTilePosition->second.end(),
|
||||||
[&] (const ObjectId v)
|
[&] (const ObjectId v)
|
||||||
{
|
{
|
||||||
const auto itById = mValuesById.find(v);
|
const auto itById = values->mById.find(v);
|
||||||
if (itById != mValuesById.end())
|
if (itById != values->mById.end())
|
||||||
result.push_back(itById->second);
|
result.push_back(itById->second);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -96,15 +98,20 @@ namespace DetourNavigator
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Settings& mSettings;
|
struct Values
|
||||||
std::mutex mMutex;
|
|
||||||
std::unordered_map<ObjectId, OffMeshConnection> mValuesById;
|
|
||||||
std::map<TilePosition, std::unordered_set<ObjectId>> mValuesByTilePosition;
|
|
||||||
|
|
||||||
void removeByTilePosition(const TilePosition& tilePosition, const ObjectId id)
|
|
||||||
{
|
{
|
||||||
const auto it = mValuesByTilePosition.find(tilePosition);
|
std::unordered_map<ObjectId, OffMeshConnection> mById;
|
||||||
if (it != mValuesByTilePosition.end())
|
std::map<TilePosition, std::unordered_set<ObjectId>> mByTilePosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Settings& mSettings;
|
||||||
|
Misc::ScopeGuarded<Values> mValues;
|
||||||
|
|
||||||
|
void removeByTilePosition(std::map<TilePosition, std::unordered_set<ObjectId>>& valuesByTilePosition,
|
||||||
|
const TilePosition& tilePosition, const ObjectId id)
|
||||||
|
{
|
||||||
|
const auto it = valuesByTilePosition.find(tilePosition);
|
||||||
|
if (it != valuesByTilePosition.end())
|
||||||
it->second.erase(id);
|
it->second.erase(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -17,19 +17,18 @@ namespace DetourNavigator
|
|||||||
const auto border = getBorderSize(mSettings);
|
const auto border = getBorderSize(mSettings);
|
||||||
getTilesPositions(shape, transform, mSettings, [&] (const TilePosition& tilePosition)
|
getTilesPositions(shape, transform, mSettings, [&] (const TilePosition& tilePosition)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mTilesMutex);
|
const auto tiles = mTiles.lock();
|
||||||
auto tile = mTiles.find(tilePosition);
|
auto tile = tiles->find(tilePosition);
|
||||||
if (tile == mTiles.end())
|
if (tile == tiles->end())
|
||||||
{
|
{
|
||||||
auto tileBounds = makeTileBounds(mSettings, tilePosition);
|
auto tileBounds = makeTileBounds(mSettings, tilePosition);
|
||||||
tileBounds.mMin -= osg::Vec2f(border, border);
|
tileBounds.mMin -= osg::Vec2f(border, border);
|
||||||
tileBounds.mMax += osg::Vec2f(border, border);
|
tileBounds.mMax += osg::Vec2f(border, border);
|
||||||
tile = mTiles.insert(std::make_pair(tilePosition,
|
tile = tiles->insert(std::make_pair(tilePosition,
|
||||||
CachedRecastMeshManager(mSettings, tileBounds))).first;
|
CachedRecastMeshManager(mSettings, tileBounds))).first;
|
||||||
}
|
}
|
||||||
if (tile->second.addObject(id, shape, transform, areaType))
|
if (tile->second.addObject(id, shape, transform, areaType))
|
||||||
{
|
{
|
||||||
lock.unlock();
|
|
||||||
tilesPositions.push_back(tilePosition);
|
tilesPositions.push_back(tilePosition);
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
@ -46,14 +45,15 @@ namespace DetourNavigator
|
|||||||
if (object == mObjectsTilesPositions.end())
|
if (object == mObjectsTilesPositions.end())
|
||||||
return false;
|
return false;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
std::unique_lock<std::mutex> lock(mTilesMutex);
|
{
|
||||||
|
const auto tiles = mTiles.lock();
|
||||||
for (const auto& tilePosition : object->second)
|
for (const auto& tilePosition : object->second)
|
||||||
{
|
{
|
||||||
const auto tile = mTiles.find(tilePosition);
|
const auto tile = tiles->find(tilePosition);
|
||||||
if (tile != mTiles.end())
|
if (tile != tiles->end())
|
||||||
result = tile->second.updateObject(id, transform, areaType) || result;
|
result = tile->second.updateObject(id, transform, areaType) || result;
|
||||||
}
|
}
|
||||||
lock.unlock();
|
}
|
||||||
if (result)
|
if (result)
|
||||||
++mRevision;
|
++mRevision;
|
||||||
return result;
|
return result;
|
||||||
@ -67,14 +67,13 @@ namespace DetourNavigator
|
|||||||
boost::optional<RemovedRecastMeshObject> result;
|
boost::optional<RemovedRecastMeshObject> result;
|
||||||
for (const auto& tilePosition : object->second)
|
for (const auto& tilePosition : object->second)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mTilesMutex);
|
const auto tiles = mTiles.lock();
|
||||||
const auto tile = mTiles.find(tilePosition);
|
const auto tile = tiles->find(tilePosition);
|
||||||
if (tile == mTiles.end())
|
if (tile == tiles->end())
|
||||||
continue;
|
continue;
|
||||||
const auto tileResult = tile->second.removeObject(id);
|
const auto tileResult = tile->second.removeObject(id);
|
||||||
if (tile->second.isEmpty())
|
if (tile->second.isEmpty())
|
||||||
mTiles.erase(tile);
|
tiles->erase(tile);
|
||||||
lock.unlock();
|
|
||||||
if (tileResult && !result)
|
if (tileResult && !result)
|
||||||
result = tileResult;
|
result = tileResult;
|
||||||
}
|
}
|
||||||
@ -94,8 +93,8 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
if (cellSize == std::numeric_limits<int>::max())
|
if (cellSize == std::numeric_limits<int>::max())
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mTilesMutex);
|
const auto tiles = mTiles.lock();
|
||||||
for (auto& tile : mTiles)
|
for (auto& tile : *tiles)
|
||||||
{
|
{
|
||||||
if (tile.second.addWater(cellPosition, cellSize, transform))
|
if (tile.second.addWater(cellPosition, cellSize, transform))
|
||||||
{
|
{
|
||||||
@ -108,19 +107,18 @@ namespace DetourNavigator
|
|||||||
{
|
{
|
||||||
getTilesPositions(cellSize, transform, mSettings, [&] (const TilePosition& tilePosition)
|
getTilesPositions(cellSize, transform, mSettings, [&] (const TilePosition& tilePosition)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mTilesMutex);
|
const auto tiles = mTiles.lock();
|
||||||
auto tile = mTiles.find(tilePosition);
|
auto tile = tiles->find(tilePosition);
|
||||||
if (tile == mTiles.end())
|
if (tile == tiles->end())
|
||||||
{
|
{
|
||||||
auto tileBounds = makeTileBounds(mSettings, tilePosition);
|
auto tileBounds = makeTileBounds(mSettings, tilePosition);
|
||||||
tileBounds.mMin -= osg::Vec2f(border, border);
|
tileBounds.mMin -= osg::Vec2f(border, border);
|
||||||
tileBounds.mMax += osg::Vec2f(border, border);
|
tileBounds.mMax += osg::Vec2f(border, border);
|
||||||
tile = mTiles.insert(std::make_pair(tilePosition,
|
tile = tiles->insert(std::make_pair(tilePosition,
|
||||||
CachedRecastMeshManager(mSettings, tileBounds))).first;
|
CachedRecastMeshManager(mSettings, tileBounds))).first;
|
||||||
}
|
}
|
||||||
if (tile->second.addWater(cellPosition, cellSize, transform))
|
if (tile->second.addWater(cellPosition, cellSize, transform))
|
||||||
{
|
{
|
||||||
lock.unlock();
|
|
||||||
tilesPositions.push_back(tilePosition);
|
tilesPositions.push_back(tilePosition);
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
@ -141,14 +139,13 @@ namespace DetourNavigator
|
|||||||
boost::optional<RecastMeshManager::Water> result;
|
boost::optional<RecastMeshManager::Water> result;
|
||||||
for (const auto& tilePosition : object->second)
|
for (const auto& tilePosition : object->second)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mTilesMutex);
|
const auto tiles = mTiles.lock();
|
||||||
const auto tile = mTiles.find(tilePosition);
|
const auto tile = tiles->find(tilePosition);
|
||||||
if (tile == mTiles.end())
|
if (tile == tiles->end())
|
||||||
continue;
|
continue;
|
||||||
const auto tileResult = tile->second.removeWater(cellPosition);
|
const auto tileResult = tile->second.removeWater(cellPosition);
|
||||||
if (tile->second.isEmpty())
|
if (tile->second.isEmpty())
|
||||||
mTiles.erase(tile);
|
tiles->erase(tile);
|
||||||
lock.unlock();
|
|
||||||
if (tileResult && !result)
|
if (tileResult && !result)
|
||||||
result = tileResult;
|
result = tileResult;
|
||||||
}
|
}
|
||||||
@ -159,17 +156,16 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
std::shared_ptr<RecastMesh> TileCachedRecastMeshManager::getMesh(const TilePosition& tilePosition)
|
std::shared_ptr<RecastMesh> TileCachedRecastMeshManager::getMesh(const TilePosition& tilePosition)
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mTilesMutex);
|
const auto tiles = mTiles.lock();
|
||||||
const auto it = mTiles.find(tilePosition);
|
const auto it = tiles->find(tilePosition);
|
||||||
if (it == mTiles.end())
|
if (it == tiles->end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return it->second.getMesh();
|
return it->second.getMesh();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TileCachedRecastMeshManager::hasTile(const TilePosition& tilePosition)
|
bool TileCachedRecastMeshManager::hasTile(const TilePosition& tilePosition)
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mTilesMutex);
|
return mTiles.lockConst()->count(tilePosition);
|
||||||
return mTiles.count(tilePosition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t TileCachedRecastMeshManager::getRevision() const
|
std::size_t TileCachedRecastMeshManager::getRevision() const
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include "cachedrecastmeshmanager.hpp"
|
#include "cachedrecastmeshmanager.hpp"
|
||||||
#include "tileposition.hpp"
|
#include "tileposition.hpp"
|
||||||
|
|
||||||
|
#include <components/misc/guarded.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
@ -32,8 +34,7 @@ namespace DetourNavigator
|
|||||||
template <class Function>
|
template <class Function>
|
||||||
void forEachTilePosition(Function&& function)
|
void forEachTilePosition(Function&& function)
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(mTilesMutex);
|
for (const auto& tile : *mTiles.lock())
|
||||||
for (const auto& tile : mTiles)
|
|
||||||
function(tile.first);
|
function(tile.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,8 +42,7 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const Settings& mSettings;
|
const Settings& mSettings;
|
||||||
std::mutex mTilesMutex;
|
Misc::ScopeGuarded<std::map<TilePosition, CachedRecastMeshManager>> mTiles;
|
||||||
std::map<TilePosition, CachedRecastMeshManager> mTiles;
|
|
||||||
std::unordered_map<ObjectId, std::vector<TilePosition>> mObjectsTilesPositions;
|
std::unordered_map<ObjectId, std::vector<TilePosition>> mObjectsTilesPositions;
|
||||||
std::map<osg::Vec2i, std::vector<TilePosition>> mWaterTilesPositions;
|
std::map<osg::Vec2i, std::vector<TilePosition>> mWaterTilesPositions;
|
||||||
std::size_t mRevision = 0;
|
std::size_t mRevision = 0;
|
||||||
|
@ -34,6 +34,35 @@ namespace Misc
|
|||||||
std::reference_wrapper<T> mValue;
|
std::reference_wrapper<T> mValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class ScopeGuarded
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScopeGuarded() = default;
|
||||||
|
|
||||||
|
ScopeGuarded(const T& value)
|
||||||
|
: mValue(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ScopeGuarded(T&& value)
|
||||||
|
: mValue(std::move(value))
|
||||||
|
{}
|
||||||
|
|
||||||
|
Locked<T> lock()
|
||||||
|
{
|
||||||
|
return Locked<T>(mMutex, mValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
Locked<const T> lockConst()
|
||||||
|
{
|
||||||
|
return Locked<const T>(mMutex, mValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex mMutex;
|
||||||
|
T mValue;
|
||||||
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class SharedGuarded
|
class SharedGuarded
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user