diff --git a/routing/routing_callbacks.hpp b/routing/routing_callbacks.hpp index fae327887d..45553866c6 100644 --- a/routing/routing_callbacks.hpp +++ b/routing/routing_callbacks.hpp @@ -43,30 +43,32 @@ enum class RouterResultCode enum class SessionState { - RoutingNotActive, - RouteBuilding, // we requested a route and wait when it will be builded - RouteNotReady, // routing was not build - RouteNotStarted, // route is builded but the user isn't on it - OnRoute, // user follows the route - RouteNeedRebuild, // user left the route - RouteFinished, // destination point is reached but the session isn't closed - RouteNoFollowing, // route is built but following mode has been disabled - RouteRebuilding, // we requested a route rebuild and wait when it will be rebuilded + RoutingNotActive, // No valid route: no route after application launching or the route was removed. + RouteBuilding, // We requested a route and wait when it will be built. User may be following + // the previous route. + RouteBuildingError, // The route was not built because of an error. + RouteNotStarted, // Route is built but the user isn't on it. + OnRoute, // User follows the route. + RouteNeedRebuild, // User left the route. + RouteFinished, // Destination point is reached but the session isn't closed. + RouteNoFollowing, // Route is built but following mode has been disabled. + RouteRebuilding, // We requested a route rebuild and wait when it will be rebuilt. + // User may following the previous route. }; /* * RoutingNotActive -> RouteBuilding // start route building - * RouteBuilding -> RouteNotReady // waiting for route in case of building a new route + * RouteBuilding -> RouteBuildingError // route was built with an error * RouteBuilding -> RouteNotStarted // route is built in case of building a new route - * RouteRebuilding -> RouteNotReady // waiting for route in case of rebuilding + * RouteRebuilding -> RouteBuildingError // waiting for route in case of rebuilding * RouteRebuilding -> RouteNotStarted // route is built in case of rebuilding * RouteNotStarted -> OnRoute // user started following the route * RouteNotStarted -> RouteNeedRebuild // user doesn't like the route. * OnRoute -> RouteNeedRebuild // user moves away from route - need to rebuild - * OnRoute -> RouteNoFollowing // following mode was disabled. Router doesn't track position. + * OnRoute -> RouteNoFollowing // following mode was disabled. Router doesn't track position * OnRoute -> RouteFinished // user reached the end of route - * RouteNeedRebuild -> RouteNotReady // start rebuild route - * RouteFinished -> RouteNotReady // start new route + * OnRoute -> RouteBuilding // while moving along a route user makes a new route + * RouteNeedRebuild -> RouteRebuilding // start rebuild route */ using CheckpointCallback = std::function; diff --git a/routing/routing_session.cpp b/routing/routing_session.cpp index c8da622c33..95ff977941 100644 --- a/routing/routing_session.cpp +++ b/routing/routing_session.cpp @@ -102,20 +102,18 @@ void RoutingSession::RebuildRoute(m2::PointD const & startPoint, { CHECK_THREAD_CHECKER(m_threadChecker, ()); CHECK(m_router, ()); - RemoveRoute(); SetState(routeRebuildingState); ++m_routingRebuildCount; - m_lastCompletionPercent = 0; - m_checkpoints.SetPointFrom(startPoint); - auto const & direction = m_routingSettings.m_useDirectionForRouteBuilding ? m_positionAccumulator.GetDirection() : m2::PointD::Zero(); + Checkpoints checkpoints(m_checkpoints); + checkpoints.SetPointFrom(startPoint); // Use old-style callback construction, because lambda constructs buggy function on Android // (callback param isn't captured by value). - m_router->CalculateRoute(m_checkpoints, direction, adjustToPrevRoute, + m_router->CalculateRoute(checkpoints, direction, adjustToPrevRoute, DoReadyCallback(*this, readyCallback), needMoreMapsCallback, removeRouteCallback, m_progressCallback, timeoutSec); } @@ -163,7 +161,7 @@ void RoutingSession::RebuildRouteOnTrafficUpdate() switch (m_state) { case SessionState::RoutingNotActive: - case SessionState::RouteNotReady: + case SessionState::RouteBuildingError: case SessionState::RouteFinished: return; case SessionState::RouteBuilding: @@ -226,7 +224,7 @@ bool RoutingSession::IsRebuildingOnly() const bool RoutingSession::IsNotReady() const { CHECK_THREAD_CHECKER(m_threadChecker, ()); - return m_state == SessionState::RouteNotReady; + return m_state == SessionState::RouteBuildingError; } bool RoutingSession::IsFinished() const @@ -280,13 +278,17 @@ SessionState RoutingSession::OnLocationPositionChanged(GpsInfo const & info) ASSERT_NOT_EQUAL(m_state, SessionState::RoutingNotActive, ()); ASSERT(m_router, ()); - if (m_state == SessionState::RouteNeedRebuild || m_state == SessionState::RouteFinished - || m_state == SessionState::RouteBuilding || m_state == SessionState::RouteRebuilding - || m_state == SessionState::RouteNotReady || m_state == SessionState::RouteNoFollowing) + if (m_state == SessionState::RouteFinished || m_state == SessionState::RouteBuilding + || m_state == SessionState::RouteBuildingError || m_state == SessionState::RouteNoFollowing) + { + return m_state; + } + + // If a route cancelled while the first building |m_route| is invalid and still may be rebuild. + if (!m_route->IsValid()) return m_state; ASSERT(m_route, ()); - ASSERT(m_route->IsValid(), ()); m_turnNotificationsMgr.SetSpeedMetersPerSecond(info.m_speedMpS); @@ -322,7 +324,7 @@ SessionState RoutingSession::OnLocationPositionChanged(GpsInfo const & info) return m_state; } - if (!iteratorAction.m_closerToFake) + if (!iteratorAction.m_closerToFake && m_state != SessionState::RouteNeedRebuild && m_state != SessionState::RouteRebuilding) { // Distance from the last known projection on route // (check if we are moving far from the last known projection). @@ -487,22 +489,22 @@ void RoutingSession::GenerateNotifications(vector & notifications) void RoutingSession::AssignRoute(shared_ptr route, RouterResultCode e) { CHECK_THREAD_CHECKER(m_threadChecker, ()); - if (e != RouterResultCode::Cancelled) + + if (e != RouterResultCode::NoError) { - if (route->IsValid()) - SetState(SessionState::RouteNotStarted); + // Route building was not success. If the former route is valid let's continue moving along it. + // If not, let's set corresponding state. + if (m_route->IsValid()) + SetState(SessionState::OnRoute); else SetState(SessionState::RoutingNotActive); - - if (e != RouterResultCode::NoError) - SetState(SessionState::RouteNotReady); - } - else - { - SetState(SessionState::RoutingNotActive); + return; } - ASSERT(m_route, ()); + RemoveRoute(); + m_lastCompletionPercent = 0; + m_checkpoints.SetPointFrom(route->GetPoly().Front()); + SetState(SessionState::RouteNotStarted); route->SetRoutingSettings(m_routingSettings); m_route = route; @@ -783,7 +785,7 @@ string DebugPrint(SessionState state) { case SessionState::RoutingNotActive: return "RoutingNotActive"; case SessionState::RouteBuilding: return "RouteBuilding"; - case SessionState::RouteNotReady: return "RouteNotReady"; + case SessionState::RouteBuildingError: return "RouteBuildingError"; case SessionState::RouteNotStarted: return "RouteNotStarted"; case SessionState::OnRoute: return "OnRoute"; case SessionState::RouteNeedRebuild: return "RouteNeedRebuild"; diff --git a/routing/routing_tests/routing_session_test.cpp b/routing/routing_tests/routing_session_test.cpp index b3867d0c24..8a67b8318e 100644 --- a/routing/routing_tests/routing_session_test.cpp +++ b/routing/routing_tests/routing_session_test.cpp @@ -220,7 +220,7 @@ UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestRouteRebuildingMovingA nullptr /* removeRouteCallback */); { SessionStateTest sessionStateTest( - {SessionState::OnRoute, SessionState::RoutingNotActive, SessionState::RouteBuilding}, + {SessionState::OnRoute, SessionState::RouteBuilding}, *m_session); m_session->BuildRoute(Checkpoints(kTestRoute.front(), kTestRoute.back()),