1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-22 13:09:42 +00:00

Use single set to store pushed jobs for tiles

This commit is contained in:
elsid 2021-08-12 22:05:44 +02:00
parent a99266a60e
commit 8db640289c
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
2 changed files with 22 additions and 31 deletions

View file

@ -173,8 +173,6 @@ namespace DetourNavigator
return true; return true;
} }
minDistanceToPlayer = getMinDistanceTo(playerPosition, maxDistanceToPlayer, mPushed, mPresentTiles); minDistanceToPlayer = getMinDistanceTo(playerPosition, maxDistanceToPlayer, mPushed, mPresentTiles);
for (const auto& [threadId, queue] : mThreadsQueues)
minDistanceToPlayer = getMinDistanceTo(playerPosition, minDistanceToPlayer, queue.mPushed, mPresentTiles);
return minDistanceToPlayer >= maxDistanceToPlayer; return minDistanceToPlayer >= maxDistanceToPlayer;
}; };
std::unique_lock<std::mutex> lock(mMutex); std::unique_lock<std::mutex> lock(mMutex);
@ -319,7 +317,7 @@ namespace DetourNavigator
{ {
const auto hasJob = [&] { const auto hasJob = [&] {
return (!mJobs.empty() && mJobs.front().mProcessTime <= std::chrono::steady_clock::now()) return (!mJobs.empty() && mJobs.front().mProcessTime <= std::chrono::steady_clock::now())
|| !threadQueue.mJobs.empty(); || !threadQueue.empty();
}; };
if (!mHasJob.wait_for(lock, std::chrono::milliseconds(10), hasJob)) if (!mHasJob.wait_for(lock, std::chrono::milliseconds(10), hasJob))
@ -330,11 +328,11 @@ namespace DetourNavigator
} }
Log(Debug::Debug) << "Got " << mJobs.size() << " navigator jobs and " Log(Debug::Debug) << "Got " << mJobs.size() << " navigator jobs and "
<< threadQueue.mJobs.size() << " thread jobs by thread=" << std::this_thread::get_id(); << threadQueue.size() << " thread jobs by thread=" << std::this_thread::get_id();
auto job = threadQueue.mJobs.empty() auto job = threadQueue.empty()
? getJob(mJobs, mPushed, true) ? getJob(mJobs, true)
: getJob(threadQueue.mJobs, threadQueue.mPushed, false); : getJob(threadQueue, false);
if (!job) if (!job)
continue; continue;
@ -342,13 +340,22 @@ namespace DetourNavigator
const auto owner = lockTile(job->mAgentHalfExtents, job->mChangedTile); const auto owner = lockTile(job->mAgentHalfExtents, job->mChangedTile);
if (owner == threadId) if (owner == threadId)
{
const auto it = mPushed.find(job->mAgentHalfExtents);
if (it != mPushed.end())
{
it->second.erase(job->mChangedTile);
if (it->second.empty())
mPushed.erase(it);
}
return job; return job;
}
postThreadJob(std::move(*job), mThreadsQueues[owner]); postThreadJob(std::move(*job), mThreadsQueues[owner]);
} }
} }
std::optional<AsyncNavMeshUpdater::Job> AsyncNavMeshUpdater::getJob(Jobs& jobs, Pushed& pushed, bool changeLastUpdate) std::optional<AsyncNavMeshUpdater::Job> AsyncNavMeshUpdater::getJob(Jobs& jobs, bool changeLastUpdate)
{ {
const auto now = std::chrono::steady_clock::now(); const auto now = std::chrono::steady_clock::now();
@ -361,11 +368,6 @@ namespace DetourNavigator
if (changeLastUpdate && job.mChangeType == ChangeType::update) if (changeLastUpdate && job.mChangeType == ChangeType::update)
mLastUpdates[job.mAgentHalfExtents][job.mChangedTile] = now; mLastUpdates[job.mAgentHalfExtents][job.mChangedTile] = now;
const auto it = pushed.find(job.mAgentHalfExtents);
it->second.erase(job.mChangedTile);
if (it->second.empty())
pushed.erase(it);
return job; return job;
} }
@ -407,13 +409,10 @@ namespace DetourNavigator
} }
} }
void AsyncNavMeshUpdater::postThreadJob(Job&& job, Queue& queue) void AsyncNavMeshUpdater::postThreadJob(Job&& job, Jobs& queue)
{ {
if (queue.mPushed[job.mAgentHalfExtents].insert(job.mChangedTile).second) queue.push_back(std::move(job));
{ mHasJob.notify_all();
queue.mJobs.push_back(std::move(job));
mHasJob.notify_all();
}
} }
std::thread::id AsyncNavMeshUpdater::lockTile(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile) std::thread::id AsyncNavMeshUpdater::lockTile(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile)
@ -475,7 +474,7 @@ namespace DetourNavigator
std::size_t AsyncNavMeshUpdater::getTotalThreadJobsUnsafe() const std::size_t AsyncNavMeshUpdater::getTotalThreadJobsUnsafe() const
{ {
return std::accumulate(mThreadsQueues.begin(), mThreadsQueues.end(), std::size_t(0), return std::accumulate(mThreadsQueues.begin(), mThreadsQueues.end(), std::size_t(0),
[] (auto r, const auto& v) { return r + v.second.mJobs.size(); }); [] (auto r, const auto& v) { return r + v.second.size(); });
} }
void AsyncNavMeshUpdater::cleanupLastUpdates() void AsyncNavMeshUpdater::cleanupLastUpdates()

View file

@ -92,14 +92,6 @@ namespace DetourNavigator
using Jobs = std::deque<Job>; using Jobs = std::deque<Job>;
using Pushed = std::map<osg::Vec3f, std::set<TilePosition>>; using Pushed = std::map<osg::Vec3f, std::set<TilePosition>>;
struct Queue
{
Jobs mJobs;
Pushed mPushed;
Queue() = default;
};
std::reference_wrapper<const Settings> mSettings; std::reference_wrapper<const Settings> mSettings;
std::reference_wrapper<TileCachedRecastMeshManager> mRecastMeshManager; std::reference_wrapper<TileCachedRecastMeshManager> mRecastMeshManager;
std::reference_wrapper<OffMeshConnectionsManager> mOffMeshConnectionsManager; std::reference_wrapper<OffMeshConnectionsManager> mOffMeshConnectionsManager;
@ -115,7 +107,7 @@ namespace DetourNavigator
Misc::ScopeGuarded<std::map<osg::Vec3f, std::map<TilePosition, std::thread::id>>> mProcessingTiles; Misc::ScopeGuarded<std::map<osg::Vec3f, std::map<TilePosition, std::thread::id>>> mProcessingTiles;
std::map<osg::Vec3f, std::map<TilePosition, std::chrono::steady_clock::time_point>> mLastUpdates; std::map<osg::Vec3f, std::map<TilePosition, std::chrono::steady_clock::time_point>> mLastUpdates;
std::set<std::tuple<osg::Vec3f, TilePosition>> mPresentTiles; std::set<std::tuple<osg::Vec3f, TilePosition>> mPresentTiles;
std::map<std::thread::id, Queue> mThreadsQueues; std::map<std::thread::id, Jobs> mThreadsQueues;
std::vector<std::thread> mThreads; std::vector<std::thread> mThreads;
void process() noexcept; void process() noexcept;
@ -124,9 +116,9 @@ namespace DetourNavigator
std::optional<Job> getNextJob(); std::optional<Job> getNextJob();
std::optional<Job> getJob(Jobs& jobs, Pushed& pushed, bool changeLastUpdate); std::optional<Job> getJob(Jobs& jobs, bool changeLastUpdate);
void postThreadJob(Job&& job, Queue& queue); void postThreadJob(Job&& job, Jobs& queue);
void writeDebugFiles(const Job& job, const RecastMesh* recastMesh) const; void writeDebugFiles(const Job& job, const RecastMesh* recastMesh) const;