#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_ASYNCNAVMESHUPDATER_H #define OPENMW_COMPONENTS_DETOURNAVIGATOR_ASYNCNAVMESHUPDATER_H #include "navmeshcacheitem.hpp" #include "recastmesh.hpp" #include "tileposition.hpp" #include #include #include #include #include #include #include #include #include #include class dtNavMesh; namespace DetourNavigator { class AsyncNavMeshUpdater { public: AsyncNavMeshUpdater(const Settings& settings); ~AsyncNavMeshUpdater(); void post(const osg::Vec3f& agentHalfExtents, const std::shared_ptr& recastMesh, const std::shared_ptr& navMeshCacheItem, const TilePosition& playerTile, const std::set& changedTiles); void wait(); private: struct Job { osg::Vec3f mAgentHalfExtents; std::shared_ptr mNavMeshCacheItem; TilePosition mChangedTile; std::pair mPriority; friend inline bool operator <(const Job& lhs, const Job& rhs) { return lhs.mPriority > rhs.mPriority; } }; using Jobs = std::priority_queue>; std::reference_wrapper mSettings; std::atomic_bool mShouldStop; std::mutex mMutex; std::condition_variable mHasJob; std::condition_variable mDone; Jobs mJobs; std::mutex mRecastMeshMutex; std::shared_ptr mRecastMesh; std::thread mThread; void process() throw(); void processJob(const Job& job); boost::optional getNextJob(); void notifyHasJob(); void writeDebugFiles(const Job& job, const RecastMesh& recastMesh) const; std::shared_ptr getRecastMesh(); void setRecastMesh(const std::shared_ptr& value); }; } #endif