diff --git a/apps/openmw_test_suite/detournavigator/navigator.cpp b/apps/openmw_test_suite/detournavigator/navigator.cpp index 2883921432..8e76b31541 100644 --- a/apps/openmw_test_suite/detournavigator/navigator.cpp +++ b/apps/openmw_test_suite/detournavigator/navigator.cpp @@ -65,9 +65,10 @@ namespace } }; - TEST_F(DetourNavigatorNavigatorTest, find_path_for_empty_should_throw_exception) + TEST_F(DetourNavigatorNavigatorTest, find_path_for_empty_should_return_empty) { - EXPECT_THROW(mNavigator->findPath(mAgentHalfExtents, mStart, mEnd, Flag_walk, mOut), InvalidArgument); + mNavigator->findPath(mAgentHalfExtents, mStart, mEnd, Flag_walk, mOut); + EXPECT_EQ(mPath, std::deque()); } TEST_F(DetourNavigatorNavigatorTest, find_path_for_existing_agent_with_no_navmesh_should_throw_exception) @@ -76,11 +77,12 @@ namespace EXPECT_THROW(mNavigator->findPath(mAgentHalfExtents, mStart, mEnd, Flag_walk, mOut), NavigatorException); } - TEST_F(DetourNavigatorNavigatorTest, find_path_for_removed_agent_should_throw_exception) + TEST_F(DetourNavigatorNavigatorTest, find_path_for_removed_agent_should_return_empty) { mNavigator->addAgent(mAgentHalfExtents); mNavigator->removeAgent(mAgentHalfExtents); - EXPECT_THROW(mNavigator->findPath(mAgentHalfExtents, mStart, mEnd, Flag_walk, mOut), InvalidArgument); + mNavigator->findPath(mAgentHalfExtents, mStart, mEnd, Flag_walk, mOut); + EXPECT_EQ(mPath, std::deque()); } TEST_F(DetourNavigatorNavigatorTest, add_agent_should_count_each_agent) diff --git a/components/detournavigator/navigator.hpp b/components/detournavigator/navigator.hpp index 529b539c85..a06d97c563 100644 --- a/components/detournavigator/navigator.hpp +++ b/components/detournavigator/navigator.hpp @@ -171,6 +171,8 @@ namespace DetourNavigator "out is not an OutputIterator" ); const auto navMesh = getNavMesh(agentHalfExtents); + if (!navMesh) + return out; const auto settings = getSettings(); return findSmoothPath(navMesh.lock()->getValue(), toNavMeshCoordinates(settings, agentHalfExtents), toNavMeshCoordinates(settings, start), toNavMeshCoordinates(settings, end), includeFlags, diff --git a/components/detournavigator/navmeshmanager.cpp b/components/detournavigator/navmeshmanager.cpp index 66bf39aaf0..ddf0045a27 100644 --- a/components/detournavigator/navmeshmanager.cpp +++ b/components/detournavigator/navmeshmanager.cpp @@ -133,7 +133,13 @@ namespace DetourNavigator else lastPlayerTile->second = playerTile; std::map tilesToPost; - const auto& cached = getCached(agentHalfExtents); + const auto cached = getCached(agentHalfExtents); + if (!cached) + { + std::ostringstream stream; + stream << "Agent with half extents is not found: " << agentHalfExtents; + throw InvalidArgument(stream.str()); + } const auto changedTiles = mChangedTiles.find(agentHalfExtents); { const auto locked = cached.lock(); @@ -218,13 +224,11 @@ namespace DetourNavigator } } - const SharedNavMeshCacheItem& NavMeshManager::getCached(const osg::Vec3f& agentHalfExtents) const + SharedNavMeshCacheItem NavMeshManager::getCached(const osg::Vec3f& agentHalfExtents) const { const auto cached = mCache.find(agentHalfExtents); if (cached != mCache.end()) return cached->second; - std::ostringstream stream; - stream << "Agent with half extents is not found: " << agentHalfExtents; - throw InvalidArgument(stream.str()); + return SharedNavMeshCacheItem(); } } diff --git a/components/detournavigator/navmeshmanager.hpp b/components/detournavigator/navmeshmanager.hpp index f44cdd2515..ae006da735 100644 --- a/components/detournavigator/navmeshmanager.hpp +++ b/components/detournavigator/navmeshmanager.hpp @@ -67,7 +67,7 @@ namespace DetourNavigator void addChangedTile(const TilePosition& tilePosition, const ChangeType changeType); - const SharedNavMeshCacheItem& getCached(const osg::Vec3f& agentHalfExtents) const; + SharedNavMeshCacheItem getCached(const osg::Vec3f& agentHalfExtents) const; }; } diff --git a/components/misc/guarded.hpp b/components/misc/guarded.hpp index 4cb0564b16..114a77b106 100644 --- a/components/misc/guarded.hpp +++ b/components/misc/guarded.hpp @@ -106,6 +106,11 @@ namespace Misc return Locked(*mMutex, *mValue); } + operator bool() const + { + return static_cast(mValue); + } + private: std::shared_ptr mMutex; std::shared_ptr mValue;