diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 5f55e15191..a0b27cbb1c 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -148,6 +148,7 @@ bool Framework::CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi p.m_surfaceWidth = factory->GetWidth(); p.m_surfaceHeight = factory->GetHeight(); p.m_visualScale = visualScale; + p.m_initialMyPositionState = m_currentMode; ASSERT(!m_guiPositions.empty(), ("GUI elements must be set-up before engine is created")); p.m_widgetsInitInfo = m_guiPositions; diff --git a/android/src/com/mapswithme/maps/MwmApplication.java b/android/src/com/mapswithme/maps/MwmApplication.java index bb0346f555..916a896498 100644 --- a/android/src/com/mapswithme/maps/MwmApplication.java +++ b/android/src/com/mapswithme/maps/MwmApplication.java @@ -251,7 +251,6 @@ public class MwmApplication extends Application public void runNativeFunctorOnUiThread(final long functorPointer) { - //TODO(android developer) implement categories of messages Message m = Message.obtain(mMainLoopHandler, new Runnable() { @Override diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index a547a5ac07..41ba1afd00 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -290,6 +290,13 @@ void DrapeEngine::InvalidateMyPosition() MessagePriority::High); } +void DrapeEngine::SetupMyPositionMode(location::EMyPositionMode mode) +{ + m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(ChangeMyPositionModeMessage::TYPE_SETUP, -1, mode), + MessagePriority::High); +} + void DrapeEngine::SetMyPositionModeListener(location::TMyPositionModeChanged const & fn) { m_myPositionModeChanged = fn; diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index a42e5152b2..20c30c4814 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -88,6 +88,7 @@ public: void CancelMyPosition(); void StopLocationFollow(); void InvalidateMyPosition(); + void SetupMyPositionMode(location::EMyPositionMode mode); void SetMyPositionModeListener(location::TMyPositionModeChanged const & fn); using TTapEventInfoFn = FrontendRenderer::TTapEventInfoFn; diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 5722df9b20..94e4f21d17 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -231,6 +231,9 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) ref_ptr msg = message; switch (msg->GetChangeType()) { + case ChangeMyPositionModeMessage::TYPE_SETUP: + m_myPositionController->Setup(msg->GetMode()); + break; case ChangeMyPositionModeMessage::TYPE_NEXT: m_myPositionController->NextMode(msg->GetPreferredZoomLevel()); break; diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index be785b7680..740bdf9c24 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -362,6 +362,7 @@ class ChangeMyPositionModeMessage : public Message public: enum EChangeType { + TYPE_SETUP, TYPE_NEXT, TYPE_CANCEL, TYPE_STOP_FOLLOW, @@ -378,15 +379,23 @@ public: , m_preferredZoomLevel(zoomLevel) {} + explicit ChangeMyPositionModeMessage(EChangeType changeType, int zoomLevel, + location::EMyPositionMode mode) + : m_changeType(changeType) + , m_preferredZoomLevel(zoomLevel) + , m_mode(mode) + {} + EChangeType GetChangeType() const { return m_changeType; } Type GetType() const override { return Message::ChangeMyPostitionMode; } - void SetPreferredZoomLevel(int zoomLevel) { m_preferredZoomLevel = zoomLevel; } int GetPreferredZoomLevel() const { return m_preferredZoomLevel; } + location::EMyPositionMode GetMode() const { return m_mode; } private: EChangeType const m_changeType; int m_preferredZoomLevel; + location::EMyPositionMode m_mode; }; class CompassInfoMessage : public Message diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index c04f70ea02..3ee642035e 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -250,7 +250,7 @@ void MyPositionController::NextMode(int preferredZoomLevel) newMode = IsRotationActive() ? location::MODE_ROTATE_AND_FOLLOW : location::MODE_FOLLOW; } - SetModeInfo(ChangeMode(m_modeInfo, newMode)); + SetModeInfo(ChangeMode(m_modeInfo, newMode), IsInRouting()); Follow(preferredZoomLevel); } @@ -278,6 +278,12 @@ void MyPositionController::Invalidate() } } +void MyPositionController::Setup(location::EMyPositionMode mode) +{ + SetModeInfo(ChangeMode(m_modeInfo, mode)); + Invalidate(); +} + void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen) { @@ -540,8 +546,11 @@ void MyPositionController::ActivateRouting() { if (!IsInRouting()) { - ASSERT(IsModeHasPosition(), ()); - SetModeInfo(ChangeMode(SetModeBit(m_modeInfo, RoutingSessionBit), location::MODE_NOT_FOLLOW)); + location::EMyPositionMode newMode = GetMode(); + if (IsModeHasPosition()) + newMode = location::MODE_NOT_FOLLOW; + + SetModeInfo(ChangeMode(SetModeBit(m_modeInfo, RoutingSessionBit), newMode)); } } diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index 42a913c509..7195606120 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -74,6 +74,7 @@ public: void NextMode(int preferredZoomLevel = -1); void TurnOff(); void Invalidate(); + void Setup(location::EMyPositionMode mode); void OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen); void OnCompassUpdate(location::CompassInfo const & info, ScreenBase const & screen); diff --git a/iphone/Maps/Classes/EAGLView.mm b/iphone/Maps/Classes/EAGLView.mm index ec165068d6..86fcbe7d0a 100644 --- a/iphone/Maps/Classes/EAGLView.mm +++ b/iphone/Maps/Classes/EAGLView.mm @@ -57,6 +57,7 @@ p.m_surfaceWidth = width; p.m_surfaceHeight = height; p.m_visualScale = self.contentScaleFactor; + p.m_initialMyPositionState = location::MODE_UNKNOWN_POSITION; [self.widgetsManager setupWidgets:p]; GetFramework().CreateDrapeEngine(make_ref(m_factory), move(p)); diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index 38e0bbbb5c..46e332888c 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -537,52 +537,20 @@ typedef NS_ENUM(NSUInteger, UserTouchesAction) f.SetRouteBuildingListener([self, &f](routing::IRouter::ResultCode code, vector const & absentCountries, vector const & absentRoutes) { - switch (code) + vector countries = absentCountries; + vector routes = absentRoutes; + dispatch_async(dispatch_get_main_queue(), ^ { - case routing::IRouter::ResultCode::NoError: - { - if (f.GetRouter() == routing::RouterType::Pedestrian) - [self countPedestrianRoute]; - self.controlsManager.routeBuildingProgress = 100.; - f.ActivateUserMark(nullptr, true); - [self.searchView setState:SearchViewStateHidden animated:YES]; - if (self.forceRoutingStateChange == ForceRoutingStateChangeStartFollowing) - [self.controlsManager routingNavigation]; - else - [self.controlsManager routingReady]; - [self updateRoutingInfo]; - self.forceRoutingStateChange = ForceRoutingStateChangeNone; - bool isDisclaimerApproved = false; - (void)Settings::Get("IsDisclaimerApproved", isDisclaimerApproved); - if (!isDisclaimerApproved) - { - [self presentRoutingDisclaimerAlert]; - Settings::Set("IsDisclaimerApproved", true); - } - break; - } - case routing::IRouter::RouteFileNotExist: - case routing::IRouter::InconsistentMWMandRoute: - case routing::IRouter::NeedMoreMaps: - case routing::IRouter::FileTooOld: - case routing::IRouter::RouteNotFound: - [self.controlsManager handleRoutingError]; - [self presentDownloaderAlert:code countries:absentCountries routes:absentRoutes]; - self.forceRoutingStateChange = ForceRoutingStateChangeNone; - break; - case routing::IRouter::Cancelled: - self.forceRoutingStateChange = ForceRoutingStateChangeNone; - break; - default: - [self.controlsManager handleRoutingError]; - [self presentDefaultAlert:code]; - self.forceRoutingStateChange = ForceRoutingStateChangeNone; - break; - } + [self processRoutingBuildingEvent:code countries:countries routes:routes]; + }); }); + f.SetRouteProgressListener([self](float progress) { - self.controlsManager.routeBuildingProgress = progress; + dispatch_async(dispatch_get_main_queue(), ^ + { + self.controlsManager.routeBuildingProgress = progress; + }); }); } @@ -590,6 +558,55 @@ typedef NS_ENUM(NSUInteger, UserTouchesAction) return self; } +- (void)processRoutingBuildingEvent:(routing::IRouter::ResultCode)code + countries:(vector const &)absentCountries + routes:(vector const &)absentRoutes +{ + Framework & f = GetFramework(); + switch (code) + { + case routing::IRouter::ResultCode::NoError: + { + if (f.GetRouter() == routing::RouterType::Pedestrian) + [self countPedestrianRoute]; + self.controlsManager.routeBuildingProgress = 100.; + f.ActivateUserMark(nullptr, true); + [self.searchView setState:SearchViewStateHidden animated:YES]; + if (self.forceRoutingStateChange == ForceRoutingStateChangeStartFollowing) + [self.controlsManager routingNavigation]; + else + [self.controlsManager routingReady]; + [self updateRoutingInfo]; + self.forceRoutingStateChange = ForceRoutingStateChangeNone; + bool isDisclaimerApproved = false; + (void)Settings::Get("IsDisclaimerApproved", isDisclaimerApproved); + if (!isDisclaimerApproved) + { + [self presentRoutingDisclaimerAlert]; + Settings::Set("IsDisclaimerApproved", true); + } + break; + } + case routing::IRouter::RouteFileNotExist: + case routing::IRouter::InconsistentMWMandRoute: + case routing::IRouter::NeedMoreMaps: + case routing::IRouter::FileTooOld: + case routing::IRouter::RouteNotFound: + [self.controlsManager handleRoutingError]; + [self presentDownloaderAlert:code countries:absentCountries routes:absentRoutes]; + self.forceRoutingStateChange = ForceRoutingStateChangeNone; + break; + case routing::IRouter::Cancelled: + self.forceRoutingStateChange = ForceRoutingStateChangeNone; + break; + default: + [self.controlsManager handleRoutingError]; + [self presentDefaultAlert:code]; + self.forceRoutingStateChange = ForceRoutingStateChangeNone; + break; + } +} + - (void)openBookmarks { BOOL const oneCategory = (GetFramework().GetBmCategoriesCount() == 1); diff --git a/map/framework.cpp b/map/framework.cpp index 99a1aa8dad..0ab7056cb6 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -1259,7 +1259,7 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, OnSize(params.m_surfaceWidth, params.m_surfaceHeight); m_drapeEngine->SetMyPositionModeListener(m_myPositionListener); - InvalidateMyPosition(); + m_drapeEngine->SetupMyPositionMode(params.m_initialMyPositionState); m_bmManager.InitBookmarks(); @@ -1781,8 +1781,6 @@ void Framework::BuildRoute(m2::PointD const & start, m2::PointD const & finish, auto readyCallback = [this] (Route const & route, IRouter::ResultCode code) { - ASSERT_THREAD_CHECKER(m_threadChecker, ("BuildRoute_ReadyCallback")); - vector absentCountries; vector absentRoutingIndexes; if (code == IRouter::NoError) @@ -1792,7 +1790,7 @@ void Framework::BuildRoute(m2::PointD const & start, m2::PointD const & finish, InsertRoute(route); m2::RectD routeRect = route.GetPoly().GetLimitRect(); routeRect.Scale(kRouteScaleMultiplier); - m_drapeEngine->SetModelViewRect(routeRect, true, -1, true); + ShowRect(routeRect, -1); } else { @@ -1811,12 +1809,7 @@ void Framework::BuildRoute(m2::PointD const & start, m2::PointD const & finish, CallRouteBuilded(code, absentCountries, absentRoutingIndexes); }; - m_routingSession.BuildRoute(start, finish, - [readyCallback](Route const & route, IRouter::ResultCode code) - { - GetPlatform().RunOnGuiThread(bind(readyCallback, route, code)); - }, - m_progressCallback, timeoutSec); + m_routingSession.BuildRoute(start, finish, readyCallback, m_progressCallback, timeoutSec); } void Framework::FollowRoute() @@ -1879,21 +1872,18 @@ void Framework::SetRouterImpl(RouterType type) void Framework::RemoveRoute(bool deactivateFollowing) { - ASSERT_THREAD_CHECKER(m_threadChecker, ("RemoveRoute")); if (m_drapeEngine != nullptr) m_drapeEngine->RemoveRoute(deactivateFollowing); } void Framework::CloseRouting() { - ASSERT_THREAD_CHECKER(m_threadChecker, ("CloseRouting")); m_routingSession.Reset(); RemoveRoute(true /* deactivateFollowing */); } void Framework::InsertRoute(Route const & route) { - ASSERT_THREAD_CHECKER(m_threadChecker, ("InsertRoute")); if (m_drapeEngine == nullptr) return; @@ -1934,10 +1924,7 @@ void Framework::CheckLocationForRouting(GpsInfo const & info) }; m2::PointD const & position = m_routingSession.GetUserCurrentPosition(); - m_routingSession.RebuildRoute(position, [readyCallback](Route const & route, IRouter::ResultCode code) - { - GetPlatform().RunOnGuiThread(bind(readyCallback, route, code)); - }, m_progressCallback, 0 /* timeoutSec */); + m_routingSession.RebuildRoute(position, readyCallback, m_progressCallback, 0 /* timeoutSec */); } else if (state == RoutingSession::RouteFinished) { diff --git a/map/framework.hpp b/map/framework.hpp index c48d1734ad..e1e284e4b3 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -301,6 +301,7 @@ public: int m_surfaceHeight; gui::TWidgetsInitInfo m_widgetsInitInfo; + location::EMyPositionMode m_initialMyPositionState; }; void CreateDrapeEngine(ref_ptr contextFactory, DrapeCreationParams && params); diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp index 3fc877ccf8..63229ca751 100644 --- a/qt/draw_widget.cpp +++ b/qt/draw_widget.cpp @@ -186,6 +186,7 @@ bool IsLocationEmulation(QMouseEvent * e) p.m_surfaceWidth = m_ratio * width(); p.m_surfaceHeight = m_ratio * height(); p.m_visualScale = m_ratio; + p.m_initialMyPositionState = location::MODE_UNKNOWN_POSITION; m_skin.reset(new gui::Skin(gui::ResolveGuiSkinFile("default"), m_ratio)); m_skin->Resize(p.m_surfaceWidth, p.m_surfaceHeight);