From 03c1bb623d088b0c989cf8faffc7ba10de0879b6 Mon Sep 17 00:00:00 2001 From: VladiMihaylenko Date: Mon, 5 Jun 2017 12:37:04 +0300 Subject: [PATCH 1/7] Added routing manager --- map/routing_manager.cpp | 422 ++++++++++++++++++++++++++++++++++++++++ map/routing_manager.hpp | 195 +++++++++++++++++++ 2 files changed, 617 insertions(+) create mode 100644 map/routing_manager.cpp create mode 100644 map/routing_manager.hpp diff --git a/map/routing_manager.cpp b/map/routing_manager.cpp new file mode 100644 index 0000000000..ea8dbe0361 --- /dev/null +++ b/map/routing_manager.cpp @@ -0,0 +1,422 @@ +#include "routing_manager.hpp" + +#include "map/chart_generator.hpp" +#include "map/mwm_tree.hpp" + +#include "tracking/reporter.hpp" + +#include "routing/car_router.hpp" +#include "routing/index_router.hpp" +#include "routing/num_mwm_id.hpp" +#include "routing/online_absent_fetcher.hpp" +#include "routing/road_graph_router.hpp" +#include "routing/route.hpp" +#include "routing/routing_algorithm.hpp" +#include "routing/routing_helpers.hpp" + +#include "drape_frontend/drape_engine.hpp" + +#include "indexer/map_style_reader.hpp" +#include "indexer/scales.hpp" + +#include "storage/country_info_getter.hpp" +#include "storage/storage.hpp" + +#include "platform/country_file.hpp" +#include "platform/mwm_traits.hpp" +#include "platform/platform.hpp" + +#include "3party/Alohalytics/src/alohalytics.h" + +namespace +{ +char const kRouterTypeKey[] = "router"; +} // namespace + +namespace marketing +{ +char const * const kRoutingCalculatingRoute = "Routing_CalculatingRoute"; +} // namespace marketing + +using namespace routing; + +RoutingManager::RoutingManager(Callbacks && callbacks, Delegate & delegate) + : m_callbacks(std::move(callbacks)), m_delegate(delegate) +{ + auto const routingStatisticsFn = [](map const & statistics) { + alohalytics::LogEvent("Routing_CalculatingRoute", statistics); + GetPlatform().GetMarketingService().SendMarketingEvent(marketing::kRoutingCalculatingRoute, {}); + }; + + m_routingSession.Init(routingStatisticsFn, m_callbacks.m_visualizer); + m_routingSession.SetReadyCallbacks( + [&](Route const & route, IRouter::ResultCode code) { OnBuildRouteReady(route, code); }, + [&](Route const & route, IRouter::ResultCode code) { OnRebuildRouteReady(route, code); }); +} + +void RoutingManager::OnBuildRouteReady(Route const & route, IRouter::ResultCode code) +{ + storage::TCountriesVec absentCountries; + if (code == IRouter::NoError) + { + double const kRouteScaleMultiplier = 1.5; + + InsertRoute(route); + m_drapeEngine->StopLocationFollow(); + + // Validate route (in case of bicycle routing it can be invalid). + ASSERT(route.IsValid(), ()); + if (route.IsValid()) + { + m2::RectD routeRect = route.GetPoly().GetLimitRect(); + routeRect.Scale(kRouteScaleMultiplier); + m_drapeEngine->SetModelViewRect(routeRect, true /* applyRotation */, -1 /* zoom */, + true /* isAnim */); + } + } + else + { + absentCountries.assign(route.GetAbsentCountries().begin(), route.GetAbsentCountries().end()); + + if (code != IRouter::NeedMoreMaps) + RemoveRoute(true /* deactivateFollowing */); + } + CallRouteBuilded(code, absentCountries); +} + +void RoutingManager::OnRebuildRouteReady(Route const & route, IRouter::ResultCode code) +{ + if (code != IRouter::NoError) + return; + + RemoveRoute(false /* deactivateFollowing */); + InsertRoute(route); + CallRouteBuilded(code, storage::TCountriesVec()); +} + +RouterType RoutingManager::GetBestRouter(m2::PointD const & startPoint, + m2::PointD const & finalPoint) const +{ + // todo Implement something more sophisticated here (or delete the method). + return GetLastUsedRouter(); +} + +RouterType RoutingManager::GetLastUsedRouter() const +{ + string routerTypeStr; + if (!settings::Get(kRouterTypeKey, routerTypeStr)) + return RouterType::Vehicle; + + auto const routerType = routing::FromString(routerTypeStr); + + switch (routerType) + { + case RouterType::Pedestrian: + case RouterType::Bicycle: return routerType; + default: return RouterType::Vehicle; + } +} + +void RoutingManager::SetRouterImpl(routing::RouterType type) +{ + auto const indexGetterFn = m_callbacks.m_featureIndexGetter; + ASSERT(indexGetterFn, ()); + unique_ptr router; + unique_ptr fetcher; + + auto const countryFileGetter = [this](m2::PointD const & p) -> string { + // TODO (@gorshenin): fix CountryInfoGetter to return CountryFile + // instances instead of plain strings. + return m_callbacks.m_countryInfoGetter().GetRegionCountryId(p); + }; + + if (type == RouterType::Pedestrian) + { + router = CreatePedestrianAStarBidirectionalRouter(indexGetterFn(), countryFileGetter); + m_routingSession.SetRoutingSettings(routing::GetPedestrianRoutingSettings()); + } + else if (type == RouterType::Bicycle) + { + router = CreateBicycleAStarBidirectionalRouter(indexGetterFn(), countryFileGetter); + m_routingSession.SetRoutingSettings(routing::GetBicycleRoutingSettings()); + } + else + { + auto & index = m_callbacks.m_featureIndexGetter(); + + auto localFileChecker = [this](string const & countryFile) -> bool { + MwmSet::MwmId const mwmId = m_callbacks.m_featureIndexGetter().GetMwmIdByCountryFile( + platform::CountryFile(countryFile)); + if (!mwmId.IsAlive()) + return false; + + return version::MwmTraits(mwmId.GetInfo()->m_version).HasRoutingIndex(); + }; + + auto numMwmIds = make_shared(); + + m_delegate.RegisterCountryFiles(numMwmIds); + + auto const getMwmRectByName = [this](string const & countryId) -> m2::RectD { + return m_callbacks.m_countryInfoGetter().GetLimitRectForLeaf(countryId); + }; + + router.reset(new CarRouter( + index, countryFileGetter, + IndexRouter::CreateCarRouter(countryFileGetter, getMwmRectByName, numMwmIds, + MakeNumMwmTree(*numMwmIds, m_callbacks.m_countryInfoGetter()), + m_routingSession, index))); + fetcher.reset(new OnlineAbsentCountriesFetcher(countryFileGetter, localFileChecker)); + m_routingSession.SetRoutingSettings(routing::GetCarRoutingSettings()); + } + + m_routingSession.SetRouter(move(router), move(fetcher)); + m_currentRouterType = type; +} + +void RoutingManager::RemoveRoute(bool deactivateFollowing) +{ + if (m_drapeEngine != nullptr) + m_drapeEngine->RemoveRoute(deactivateFollowing); +} + +void RoutingManager::InsertRoute(routing::Route const & route) +{ + if (m_drapeEngine == nullptr) + return; + + if (route.GetPoly().GetSize() < 2) + { + LOG(LWARNING, ("Invalid track - only", route.GetPoly().GetSize(), "point(s).")); + return; + } + + vector turns; + if (m_currentRouterType == RouterType::Vehicle || m_currentRouterType == RouterType::Bicycle || + m_currentRouterType == RouterType::Taxi) + { + route.GetTurnsDistances(turns); + } + + df::ColorConstant routeColor = df::kRouteColor; + df::RoutePattern pattern; + if (m_currentRouterType == RouterType::Pedestrian) + { + routeColor = df::kRoutePedestrian; + pattern = df::RoutePattern(4.0, 2.0); + } + else if (m_currentRouterType == RouterType::Bicycle) + { + routeColor = df::kRouteBicycle; + pattern = df::RoutePattern(8.0, 2.0); + } + + m_drapeEngine->AddRoute(route.GetPoly(), turns, routeColor, route.GetTraffic(), pattern); +} + +void RoutingManager::FollowRoute() +{ + ASSERT(m_drapeEngine != nullptr, ()); + + if (!m_routingSession.EnableFollowMode()) + return; + + m_delegate.OnRouteFollow(m_currentRouterType); + m_drapeEngine->SetRoutePoint(m2::PointD(), true /* isStart */, false /* isValid */); +} + +void RoutingManager::CloseRouting() +{ + if (m_routingSession.IsBuilt()) + { + m_routingSession.EmitCloseRoutingEvent(); + } + m_routingSession.Reset(); + RemoveRoute(true /* deactivateFollowing */); +} + +void RoutingManager::SetLastUsedRouter(RouterType type) +{ + settings::Set(kRouterTypeKey, routing::ToString(type)); +} + +void RoutingManager::SetRouteStartPoint(m2::PointD const & pt, bool isValid) +{ + if (m_drapeEngine != nullptr) + m_drapeEngine->SetRoutePoint(pt, true /* isStart */, isValid); +} + +void RoutingManager::SetRouteFinishPoint(m2::PointD const & pt, bool isValid) +{ + if (m_drapeEngine != nullptr) + m_drapeEngine->SetRoutePoint(pt, false /* isStart */, isValid); +} + +void RoutingManager::GenerateTurnNotifications(vector & turnNotifications) +{ + if (m_currentRouterType == routing::RouterType::Taxi) + return; + + return m_routingSession.GenerateTurnNotifications(turnNotifications); +} + +void RoutingManager::BuildRoute(m2::PointD const & finish, uint32_t timeoutSec) +{ + ASSERT_THREAD_CHECKER(m_threadChecker, ("BuildRoute")); + ASSERT(m_drapeEngine != nullptr, ()); + + m2::PointD start; + if (!m_drapeEngine->GetMyPosition(start)) + { + CallRouteBuilded(IRouter::NoCurrentPosition, storage::TCountriesVec()); + return; + } + BuildRoute(start, finish, false /* isP2P */, timeoutSec); +} + +void RoutingManager::BuildRoute(m2::PointD const & start, m2::PointD const & finish, bool isP2P, + uint32_t timeoutSec) +{ + ASSERT_THREAD_CHECKER(m_threadChecker, ("BuildRoute")); + ASSERT(m_drapeEngine != nullptr, ()); + + // Send tag to Push Woosh. + { + string tag; + switch (m_currentRouterType) + { + case RouterType::Vehicle: + tag = isP2P ? marketing::kRoutingP2PVehicleDiscovered : marketing::kRoutingVehicleDiscovered; + break; + case RouterType::Pedestrian: + tag = isP2P ? marketing::kRoutingP2PPedestrianDiscovered + : marketing::kRoutingPedestrianDiscovered; + break; + case RouterType::Bicycle: + tag = isP2P ? marketing::kRoutingP2PBicycleDiscovered : marketing::kRoutingBicycleDiscovered; + break; + case RouterType::Taxi: + tag = isP2P ? marketing::kRoutingP2PTaxiDiscovered : marketing::kRoutingTaxiDiscovered; + break; + case RouterType::Count: CHECK(false, ("Bad router type", m_currentRouterType)); + } + GetPlatform().GetMarketingService().SendPushWooshTag(tag); + } + + if (IsRoutingActive()) + CloseRouting(); + + m_routingSession.SetUserCurrentPosition(start); + m_routingSession.BuildRoute(start, finish, timeoutSec); +} + +bool RoutingManager::DisableFollowMode() +{ + bool const disabled = m_routingSession.DisableFollowMode(); + if (disabled && m_drapeEngine != nullptr) + m_drapeEngine->DeactivateRouteFollowing(); + + return disabled; +} + +void RoutingManager::CheckLocationForRouting(location::GpsInfo const & info) +{ + if (!IsRoutingActive()) + return; + + auto const featureIndexGetterFn = m_callbacks.m_featureIndexGetter; + ASSERT(featureIndexGetterFn, ()); + RoutingSession::State const state = + m_routingSession.OnLocationPositionChanged(info, featureIndexGetterFn()); + if (state == RoutingSession::RouteNeedRebuild) + { + m_routingSession.RebuildRoute( + MercatorBounds::FromLatLon(info.m_latitude, info.m_longitude), + [&](Route const & route, IRouter::ResultCode code) { OnRebuildRouteReady(route, code); }, + 0 /* timeoutSec */, routing::RoutingSession::State::RouteRebuilding); + } +} + +void RoutingManager::CallRouteBuilded(routing::IRouter::ResultCode code, + storage::TCountriesVec const & absentCountries) +{ + if (code == IRouter::Cancelled) + return; + + m_routingCallback(code, absentCountries); +} + +void RoutingManager::MatchLocationToRoute(location::GpsInfo & location, + location::RouteMatchingInfo & routeMatchingInfo) const +{ + if (!IsRoutingActive()) + return; + + m_routingSession.MatchLocationToRoute(location, routeMatchingInfo); +} + +bool RoutingManager::HasRouteAltitude() const { return m_routingSession.HasRouteAltitude(); } +bool RoutingManager::GenerateRouteAltitudeChart(uint32_t width, uint32_t height, + vector & imageRGBAData, + int32_t & minRouteAltitude, + int32_t & maxRouteAltitude, + measurement_utils::Units & altitudeUnits) const +{ + feature::TAltitudes altitudes; + vector segDistance; + + if (!m_routingSession.GetRouteAltitudesAndDistancesM(segDistance, altitudes)) + return false; + segDistance.insert(segDistance.begin(), 0.0); + + if (altitudes.empty()) + return false; + + if (!maps::GenerateChart(width, height, segDistance, altitudes, + GetStyleReader().GetCurrentStyle(), imageRGBAData)) + return false; + + auto const minMaxIt = minmax_element(altitudes.cbegin(), altitudes.cend()); + feature::TAltitude const minRouteAltitudeM = *minMaxIt.first; + feature::TAltitude const maxRouteAltitudeM = *minMaxIt.second; + + if (!settings::Get(settings::kMeasurementUnits, altitudeUnits)) + altitudeUnits = measurement_utils::Units::Metric; + + switch (altitudeUnits) + { + case measurement_utils::Units::Imperial: + minRouteAltitude = measurement_utils::MetersToFeet(minRouteAltitudeM); + maxRouteAltitude = measurement_utils::MetersToFeet(maxRouteAltitudeM); + break; + case measurement_utils::Units::Metric: + minRouteAltitude = minRouteAltitudeM; + maxRouteAltitude = maxRouteAltitudeM; + break; + } + return true; +} + +bool RoutingManager::IsTrackingReporterEnabled() const +{ + if (m_currentRouterType != routing::RouterType::Vehicle) + return false; + + if (!m_routingSession.IsFollowing()) + return false; + + bool enableTracking = false; + UNUSED_VALUE(settings::Get(tracking::Reporter::kEnableTrackingKey, enableTracking)); + return enableTracking; +} + +void RoutingManager::SetRouter(RouterType type) +{ + ASSERT_THREAD_CHECKER(m_threadChecker, ("SetRouter")); + + if (m_currentRouterType == type) + return; + + SetLastUsedRouter(type); + SetRouterImpl(type); +} diff --git a/map/routing_manager.hpp b/map/routing_manager.hpp new file mode 100644 index 0000000000..2a0b7dfd2e --- /dev/null +++ b/map/routing_manager.hpp @@ -0,0 +1,195 @@ +#include "drape/pointers.hpp" + +#include "routing/route.hpp" +#include "routing/routing_session.hpp" + +#include "storage/index.hpp" + +#include "base/thread_checker.hpp" + +#include +#include + +namespace df +{ +class DrapeEngine; +} + +namespace storage +{ +class CountryInfoGetter; +class Storage; +} + +namespace routing +{ +class NumMwmIds; +} + +class Index; + +class RoutingManager final +{ +public: + class Delegate + { + public: + virtual void OnRouteFollow(routing::RouterType type) = 0; + virtual void RegisterCountryFiles(std::shared_ptr ptr) const = 0; + + virtual ~Delegate() = default; + }; + + struct Callbacks + { + using FeatureIndexGetterFn = std::function; + using CountryInfoGetterFn = std::function; + using VisualizerFn = std::function; + + Callbacks(FeatureIndexGetterFn && featureIndexGetter, CountryInfoGetterFn && countryInfoGetter, + VisualizerFn && visualizer) + : m_featureIndexGetter(std::move(featureIndexGetter)) + , m_countryInfoGetter(std::move(countryInfoGetter)) + , m_visualizer(std::move(visualizer)) + { + } + + FeatureIndexGetterFn m_featureIndexGetter; + CountryInfoGetterFn m_countryInfoGetter; + VisualizerFn m_visualizer; + }; + + using RouteBuildingCallback = + std::function; + using RouteProgressCallback = std::function; + + RoutingManager(Callbacks && callbacks, Delegate & delegate); + + routing::RoutingSession const & RoutingSession() const { return m_routingSession; } + routing::RoutingSession & RoutingSession() { return m_routingSession; } + void SetRouter(routing::RouterType type); + routing::RouterType GetRouter() const { return m_currentRouterType; } + bool IsRoutingActive() const { return m_routingSession.IsActive(); } + bool IsRouteBuilt() const { return m_routingSession.IsBuilt(); } + bool IsRouteBuilding() const { return m_routingSession.IsBuilding(); } + bool IsRouteRebuildingOnly() const { return m_routingSession.IsRebuildingOnly(); } + bool IsRouteNotReady() const { return m_routingSession.IsNotReady(); } + bool IsRouteFinished() const { return m_routingSession.IsFinished(); } + bool IsOnRoute() const { return m_routingSession.IsOnRoute(); } + void BuildRoute(m2::PointD const & finish, uint32_t timeoutSec); + void BuildRoute(m2::PointD const & start, m2::PointD const & finish, bool isP2P, + uint32_t timeoutSec); + // FollowRoute has a bug where the router follows the route even if the method hads't been called. + // This method was added because we do not want to break the behaviour that is familiar to our + // users. + bool DisableFollowMode(); + /// @TODO(AlexZ): Warning! These two routing callbacks are the only callbacks which are not called + /// in the main thread context. + /// UI code should take it into an account. This is a result of current implementation, that can + /// be improved: + /// Drape core calls some RunOnGuiThread with "this" pointers, and it causes crashes on Android, + /// when Drape engine is destroyed + /// while switching between activities. Current workaround cleans all callbacks when destroying + /// Drape engine + /// (@see MwmApplication.clearFunctorsOnUiThread on Android). Better soulution can be fair copying + /// of all needed information into + /// lambdas/functors before calling RunOnGuiThread. + void SetRouteBuildingListener(RouteBuildingCallback const & buildingCallback) + { + m_routingCallback = buildingCallback; + } + /// See warning above. + void SetRouteProgressListener(RouteProgressCallback const & progressCallback) + { + m_routingSession.SetProgressCallback(progressCallback); + } + void FollowRoute(); + void CloseRouting(); + void GetRouteFollowingInfo(location::FollowingInfo & info) const + { + m_routingSession.GetRouteFollowingInfo(info); + } + m2::PointD GetRouteEndPoint() const { return m_routingSession.GetEndPoint(); } + /// Returns the most situable router engine type. + routing::RouterType GetBestRouter(m2::PointD const & startPoint, + m2::PointD const & finalPoint) const; + routing::RouterType GetLastUsedRouter() const; + void SetLastUsedRouter(routing::RouterType type); + // Sound notifications for turn instructions. + void EnableTurnNotifications(bool enable) { m_routingSession.EnableTurnNotifications(enable); } + bool AreTurnNotificationsEnabled() const + { + return m_routingSession.AreTurnNotificationsEnabled(); + } + /// \brief Sets a locale for TTS. + /// \param locale is a string with locale code. For example "en", "ru", "zh-Hant" and so on. + /// \note See sound/tts/languages.txt for the full list of available locales. + void SetTurnNotificationsLocale(string const & locale) + { + m_routingSession.SetTurnNotificationsLocale(locale); + } + /// @return current TTS locale. For example "en", "ru", "zh-Hant" and so on. + /// In case of error returns an empty string. + /// \note The method returns correct locale after SetTurnNotificationsLocale has been called. + /// If not, it returns an empty string. + string GetTurnNotificationsLocale() const + { + return m_routingSession.GetTurnNotificationsLocale(); + } + /// \brief When an end user is going to a turn he gets sound turn instructions. + /// If C++ part wants the client to pronounce an instruction GenerateTurnNotifications (in + /// turnNotifications) returns + /// an array of one of more strings. C++ part assumes that all these strings shall be pronounced + /// by the client's TTS. + /// For example if C++ part wants the client to pronounce "Make a right turn." this method returns + /// an array with one string "Make a right turn.". The next call of the method returns nothing. + /// GenerateTurnNotifications shall be called by the client when a new position is available. + void GenerateTurnNotifications(vector & turnNotifications); + + void SetRouteStartPoint(m2::PointD const & pt, bool isValid); + void SetRouteFinishPoint(m2::PointD const & pt, bool isValid); + + void SetRouterImpl(routing::RouterType type); + void RemoveRoute(bool deactivateFollowing); + + void InsertRoute(routing::Route const & route); + void CheckLocationForRouting(location::GpsInfo const & info); + void CallRouteBuilded(routing::IRouter::ResultCode code, + storage::TCountriesVec const & absentCountries); + void MatchLocationToRoute(location::GpsInfo & info, + location::RouteMatchingInfo & routeMatchingInfo) const; + void OnBuildRouteReady(routing::Route const & route, routing::IRouter::ResultCode code); + void OnRebuildRouteReady(routing::Route const & route, routing::IRouter::ResultCode code); + + void SetDrapeEngine(ref_ptr engine) { m_drapeEngine = engine; }; + /// \returns true if altitude information along |m_route| is available and + /// false otherwise. + bool HasRouteAltitude() const; + + /// \brief Generates 4 bytes per point image (RGBA) and put the data to |imageRGBAData|. + /// \param width is width of chart shall be generated in pixels. + /// \param height is height of chart shall be generated in pixels. + /// \param imageRGBAData is bits of result image in RGBA. + /// \param minRouteAltitude is min altitude along the route in altitudeUnits. + /// \param maxRouteAltitude is max altitude along the route in altitudeUnits. + /// \param altitudeUnits is units (meters or feet) which is used to pass min and max altitudes. + /// \returns If there is valid route info and the chart was generated returns true + /// and false otherwise. If the method returns true it is guaranteed that the size of + /// |imageRGBAData| is not zero. + /// \note If HasRouteAltitude() method returns true, GenerateRouteAltitudeChart(...) + /// could return false if route was deleted or rebuilt between the calls. + bool GenerateRouteAltitudeChart(uint32_t width, uint32_t height, vector & imageRGBAData, + int32_t & minRouteAltitude, int32_t & maxRouteAltitude, + measurement_utils::Units & altitudeUnits) const; + + bool IsTrackingReporterEnabled() const; + +private: + RouteBuildingCallback m_routingCallback = nullptr; + Callbacks m_callbacks; + ref_ptr m_drapeEngine = nullptr; + routing::RouterType m_currentRouterType = routing::RouterType::Count; + routing::RoutingSession m_routingSession; + DECLARE_THREAD_CHECKER(m_threadChecker); + Delegate & m_delegate; +}; From 24fbd84759810427f50b033f38d24a51df254a27 Mon Sep 17 00:00:00 2001 From: VladiMihaylenko Date: Mon, 5 Jun 2017 12:37:30 +0300 Subject: [PATCH 2/7] Added routing manager to cmake and qmake --- map/CMakeLists.txt | 2 ++ map/map.pro | 2 ++ 2 files changed, 4 insertions(+) diff --git a/map/CMakeLists.txt b/map/CMakeLists.txt index 47a7e2eb54..64345ffe77 100644 --- a/map/CMakeLists.txt +++ b/map/CMakeLists.txt @@ -54,6 +54,8 @@ set( place_page_info.hpp reachable_by_taxi_checker.cpp reachable_by_taxi_checker.hpp + routing_manager.cpp + routing_manager.hpp track.cpp track.hpp traffic_manager.cpp diff --git a/map/map.pro b/map/map.pro index 9254108a8f..5d5c4f4b84 100644 --- a/map/map.pro +++ b/map/map.pro @@ -32,6 +32,7 @@ HEADERS += \ mwm_url.hpp \ place_page_info.hpp \ reachable_by_taxi_checker.hpp \ + routing_manager.hpp \ track.hpp \ traffic_manager.hpp \ user_mark.hpp \ @@ -61,6 +62,7 @@ SOURCES += \ mwm_url.cpp \ place_page_info.cpp \ reachable_by_taxi_checker.cpp \ + routing_manager.cpp \ track.cpp \ traffic_manager.cpp \ user_mark.cpp \ From 35ae9129559a3992912a3b6ad63f4304705b8186 Mon Sep 17 00:00:00 2001 From: VladiMihaylenko Date: Mon, 5 Jun 2017 12:38:12 +0300 Subject: [PATCH 3/7] Refactored --- map/framework.cpp | 513 +++++---------------------------- map/framework.hpp | 128 +------- platform/marketing_service.cpp | 1 - platform/marketing_service.hpp | 1 - 4 files changed, 81 insertions(+), 562 deletions(-) diff --git a/map/framework.cpp b/map/framework.cpp index aa30de587a..f0faa847c1 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -126,7 +126,6 @@ namespace { static const int BM_TOUCH_PIXEL_INCREASE = 20; static const int kKeepPedestrianDistanceMeters = 10000; -char const kRouterTypeKey[] = "router"; char const kMapStyleKey[] = "MapStyleKeyV1"; char const kAllow3dKey[] = "Allow3d"; char const kAllow3dBuildingsKey[] = "Buildings3d"; @@ -239,14 +238,15 @@ void Framework::OnLocationUpdate(GpsInfo const & info) #endif location::RouteMatchingInfo routeMatchingInfo; - CheckLocationForRouting(rInfo); + m_routingManager.CheckLocationForRouting(rInfo); - MatchLocationToRoute(rInfo, routeMatchingInfo); + m_routingManager.MatchLocationToRoute(rInfo, routeMatchingInfo); - CallDrapeFunction(bind(&df::DrapeEngine::SetGpsInfo, _1, rInfo, - m_routingSession.IsNavigable(), routeMatchingInfo)); - if (IsTrackingReporterEnabled()) - m_trackingReporter.AddLocation(info, m_routingSession.MatchTraffic(routeMatchingInfo)); + auto & routingSession = m_routingManager.RoutingSession(); + CallDrapeFunction(bind(&df::DrapeEngine::SetGpsInfo, _1, rInfo, routingSession.IsNavigable(), + routeMatchingInfo)); + if (m_routingManager.IsTrackingReporterEnabled()) + m_trackingReporter.AddLocation(info, routingSession.MatchTraffic(routeMatchingInfo)); } void Framework::OnCompassUpdate(CompassInfo const & info) @@ -281,26 +281,13 @@ LocalAdsManager & Framework::GetLocalAdsManager() return m_localAdsManager; } -bool Framework::IsTrackingReporterEnabled() const -{ - if (m_currentRouterType != routing::RouterType::Vehicle) - return false; - - if (!m_routingSession.IsFollowing()) - return false; - - bool enableTracking = false; - UNUSED_VALUE(settings::Get(tracking::Reporter::kEnableTrackingKey, enableTracking)); - return enableTracking; -} - void Framework::OnUserPositionChanged(m2::PointD const & position) { MyPositionMarkPoint * myPosition = UserMarkContainer::UserMarkForMyPostion(); myPosition->SetUserPosition(position); - if (IsRoutingActive()) - m_routingSession.SetUserCurrentPosition(position); + if (m_routingManager.IsRoutingActive()) + m_routingManager.RoutingSession().SetUserCurrentPosition(position); m_trafficManager.UpdateMyPosition(TrafficManager::MyPosition(position)); } @@ -407,10 +394,22 @@ Framework::Framework(FrameworkParams const & params) , m_isRenderingEnabled(true) , m_trackingReporter(platform::CreateSocket(), TRACKING_REALTIME_HOST, TRACKING_REALTIME_PORT, tracking::Reporter::kPushDelayMs) + , m_routingManager(RoutingManager::Callbacks([this]() -> Index & { return m_model.GetIndex(); }, + bind(&Framework::GetCountryInfoGetter, this), + [this](m2::PointD const & pt) { +#ifdef DEBUG + { + UserMarkControllerGuard guard( + m_bmManager, UserMarkType::DEBUG_MARK); + guard.m_controller.SetIsVisible(true); + guard.m_controller.SetIsDrawable(true); + guard.m_controller.CreateUserMark(pt); + } +#endif + }), + static_cast(*this)) , m_trafficManager(bind(&Framework::GetMwmsByRect, this, _1, false /* rough */), - kMaxTrafficCacheSizeBytes, - // Note. |m_routingSession| should be declared before |m_trafficManager|. - m_routingSession) + kMaxTrafficCacheSizeBytes, m_routingManager.RoutingSession()) , m_localAdsManager(bind(&Framework::GetMwmsByRect, this, _1, true /* rough */), bind(&Framework::GetMwmIdByName, this, _1)) , m_displacementModeManager([this](bool show) { @@ -476,28 +475,7 @@ Framework::Framework(FrameworkParams const & params) if (!params.m_disableLocalAds) m_localAdsManager.Startup(); - auto const routingStatisticsFn = [](map const & statistics) - { - alohalytics::LogEvent("Routing_CalculatingRoute", statistics); - GetPlatform().GetMarketingService().SendMarketingEvent(marketing::kRoutingCalculatingRoute, {}); - }; -#ifdef DEBUG - auto const routingVisualizerFn = [this](m2::PointD const & pt) - { - UserMarkControllerGuard guard(m_bmManager, UserMarkType::DEBUG_MARK); - guard.m_controller.SetIsVisible(true); - guard.m_controller.SetIsDrawable(true); - - guard.m_controller.CreateUserMark(pt); - }; -#else - routing::RouterDelegate::TPointCheckCallback const routingVisualizerFn = nullptr; -#endif - m_routingSession.Init(routingStatisticsFn, routingVisualizerFn); - m_routingSession.SetReadyCallbacks([&](Route const & route, IRouter::ResultCode code){ OnBuildRouteReady(route, code); }, - [&](Route const & route, IRouter::ResultCode code){ OnRebuildRouteReady(route, code); }); - - SetRouterImpl(RouterType::Vehicle); + m_routingManager.SetRouterImpl(RouterType::Vehicle); UpdateMinBuildingsTapZoom(); @@ -632,7 +610,7 @@ void Framework::ShowNode(storage::TCountryId const & countryId) void Framework::OnCountryFileDownloaded(storage::TCountryId const & countryId, storage::Storage::TLocalFilePtr const localFile) { // Soft reset to signal that mwm file may be out of date in routing caches. - m_routingSession.Reset(); + m_routingManager.RoutingSession().Reset(); m2::RectD rect = MercatorBounds::FullRect(); @@ -653,7 +631,7 @@ void Framework::OnCountryFileDownloaded(storage::TCountryId const & countryId, s bool Framework::OnCountryFileDelete(storage::TCountryId const & countryId, storage::Storage::TLocalFilePtr const localFile) { // Soft reset to signal that mwm file may be out of date in routing caches. - m_routingSession.Reset(); + m_routingManager.RoutingSession().Reset(); if (countryId == m_lastReportedCountry) m_lastReportedCountry = kInvalidCountryId; @@ -1877,6 +1855,8 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, double const fontsScaleFactor = LoadLargeFontsSize() ? kLargeFontsScaleFactor : 1.0; + auto const & routingSession = m_routingManager.RoutingSession(); + df::DrapeEngine::Params p( params.m_apiVersion, contextFactory, make_ref(&m_stringsBundle), dp::Viewport(0, 0, params.m_surfaceWidth, params.m_surfaceHeight), @@ -1885,7 +1865,7 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, make_pair(params.m_initialMyPositionState, params.m_hasMyPositionState), move(myPositionModeChangedFn), allow3dBuildings, trafficEnabled, params.m_isChoosePositionMode, params.m_isChoosePositionMode, GetSelectedFeatureTriangles(), - m_routingSession.IsActive() && m_routingSession.IsFollowing(), isAutozoomEnabled, + routingSession.IsActive() && routingSession.IsFollowing(), isAutozoomEnabled, simplifiedTrafficColors, move(overlaysShowStatsFn)); m_drapeEngine = make_unique_dp(move(p)); @@ -1913,10 +1893,10 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, SetVisibleViewport(m2::RectD(0, 0, params.m_surfaceWidth, params.m_surfaceHeight)); // In case of the engine reinitialization recover route. - if (m_routingSession.IsActive()) + if (routingSession.IsActive()) { - InsertRoute(*m_routingSession.GetRoute()); - if (allow3d && m_routingSession.IsFollowing()) + m_routingManager.InsertRoute(*routingSession.GetRoute()); + if (allow3d && routingSession.IsFollowing()) m_drapeEngine->EnablePerspective(); } @@ -1929,6 +1909,7 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, }); m_drapeApi.SetEngine(make_ref(m_drapeEngine)); + m_routingManager.SetDrapeEngine(make_ref(m_drapeEngine)); m_trafficManager.SetDrapeEngine(make_ref(m_drapeEngine)); m_localAdsManager.SetDrapeEngine(make_ref(m_drapeEngine)); @@ -2074,7 +2055,7 @@ void Framework::SetupMeasurementSystem() auto units = measurement_utils::Units::Metric; UNUSED_VALUE(settings::Get(settings::kMeasurementUnits, units)); - m_routingSession.SetTurnNotificationsUnits(units); + m_routingManager.RoutingSession().SetTurnNotificationsUnits(units); } void Framework::SetWidgetLayout(gui::TWidgetsLayoutInfo && layout) @@ -2573,355 +2554,6 @@ void Framework::UpdateSavedDataVersion() int64_t Framework::GetCurrentDataVersion() const { return m_storage.GetCurrentDataVersion(); } -void Framework::BuildRoute(m2::PointD const & finish, uint32_t timeoutSec) -{ - ASSERT_THREAD_CHECKER(m_threadChecker, ("BuildRoute")); - ASSERT(m_drapeEngine != nullptr, ()); - - m2::PointD start; - if (!m_drapeEngine->GetMyPosition(start)) - { - CallRouteBuilded(IRouter::NoCurrentPosition, storage::TCountriesVec()); - return; - } - BuildRoute(start, finish, false /* isP2P */, timeoutSec); -} - -void Framework::BuildRoute(m2::PointD const & start, m2::PointD const & finish, bool isP2P, uint32_t timeoutSec) -{ - ASSERT_THREAD_CHECKER(m_threadChecker, ("BuildRoute")); - ASSERT(m_drapeEngine != nullptr, ()); - - // Send tag to Push Woosh. - { - string tag; - switch (m_currentRouterType) - { - case RouterType::Vehicle: - tag = isP2P ? marketing::kRoutingP2PVehicleDiscovered : marketing::kRoutingVehicleDiscovered; - break; - case RouterType::Pedestrian: - tag = isP2P ? marketing::kRoutingP2PPedestrianDiscovered : marketing::kRoutingPedestrianDiscovered; - break; - case RouterType::Bicycle: - tag = isP2P ? marketing::kRoutingP2PBicycleDiscovered : marketing::kRoutingBicycleDiscovered; - break; - case RouterType::Taxi: - tag = isP2P ? marketing::kRoutingP2PTaxiDiscovered : marketing::kRoutingTaxiDiscovered; - break; - case RouterType::Count: - CHECK(false, ("Bad router type", m_currentRouterType)); - } - GetPlatform().GetMarketingService().SendPushWooshTag(tag); - } - - if (IsRoutingActive()) - CloseRouting(); - - m_routingSession.SetUserCurrentPosition(start); - m_routingSession.BuildRoute(start, finish, timeoutSec); -} - -void Framework::FollowRoute() -{ - ASSERT(m_drapeEngine != nullptr, ()); - - if (!m_routingSession.EnableFollowMode()) - return; - - bool const isPedestrianRoute = m_currentRouterType == RouterType::Pedestrian; - bool const enableAutoZoom = isPedestrianRoute ? false : LoadAutoZoom(); - int const scale = isPedestrianRoute ? scales::GetPedestrianNavigationScale() - : scales::GetNavigationScale(); - int scale3d = isPedestrianRoute ? scales::GetPedestrianNavigation3dScale() - : scales::GetNavigation3dScale(); - if (enableAutoZoom) - ++scale3d; - - bool const isBicycleRoute = m_currentRouterType == RouterType::Bicycle; - if ((isPedestrianRoute || isBicycleRoute) && LoadTrafficEnabled()) - { - m_trafficManager.SetEnabled(false /* enabled */); - SaveTrafficEnabled(false /* enabled */); - } - - m_drapeEngine->FollowRoute(scale, scale3d, enableAutoZoom); - m_drapeEngine->SetRoutePoint(m2::PointD(), true /* isStart */, false /* isValid */); -} - -bool Framework::DisableFollowMode() -{ - bool const disabled = m_routingSession.DisableFollowMode(); - if (disabled && m_drapeEngine != nullptr) - m_drapeEngine->DeactivateRouteFollowing(); - - return disabled; -} - -void Framework::SetRouter(RouterType type) -{ - ASSERT_THREAD_CHECKER(m_threadChecker, ("SetRouter")); - - if (m_currentRouterType == type) - return; - - SetLastUsedRouter(type); - SetRouterImpl(type); -} - -routing::RouterType Framework::GetRouter() const -{ - return m_currentRouterType; -} - -void Framework::SetRouterImpl(RouterType type) -{ - unique_ptr router; - unique_ptr fetcher; - - auto const countryFileGetter = [this](m2::PointD const & p) -> string - { - // TODO (@gorshenin): fix CountryInfoGetter to return CountryFile - // instances instead of plain strings. - return m_infoGetter->GetRegionCountryId(p); - }; - - if (type == RouterType::Pedestrian) - { - router = CreatePedestrianAStarBidirectionalRouter(m_model.GetIndex(), countryFileGetter); - m_routingSession.SetRoutingSettings(routing::GetPedestrianRoutingSettings()); - } - else if (type == RouterType::Bicycle) - { - router = CreateBicycleAStarBidirectionalRouter(m_model.GetIndex(), countryFileGetter); - m_routingSession.SetRoutingSettings(routing::GetBicycleRoutingSettings()); - } - else - { - auto localFileChecker = [this](string const & countryFile) -> bool { - MwmSet::MwmId const mwmId = - m_model.GetIndex().GetMwmIdByCountryFile(CountryFile(countryFile)); - if (!mwmId.IsAlive()) - return false; - - return version::MwmTraits(mwmId.GetInfo()->m_version).HasRoutingIndex(); - }; - - auto numMwmIds = make_shared(); - m_storage.ForEachCountryFile( - [&](platform::CountryFile const & file) { numMwmIds->RegisterFile(file); }); - - auto const getMwmRectByName = [this](string const & countryId) -> m2::RectD { - return m_infoGetter->GetLimitRectForLeaf(countryId); - }; - - router.reset( - new CarRouter(m_model.GetIndex(), countryFileGetter, - IndexRouter::CreateCarRouter(countryFileGetter, getMwmRectByName, numMwmIds, - MakeNumMwmTree(*numMwmIds, *m_infoGetter), - m_routingSession, m_model.GetIndex()))); - fetcher.reset(new OnlineAbsentCountriesFetcher(countryFileGetter, localFileChecker)); - m_routingSession.SetRoutingSettings(routing::GetCarRoutingSettings()); - } - - m_routingSession.SetRouter(move(router), move(fetcher)); - m_currentRouterType = type; -} - -void Framework::RemoveRoute(bool deactivateFollowing) -{ - if (m_drapeEngine != nullptr) - m_drapeEngine->RemoveRoute(deactivateFollowing); -} - -void Framework::CloseRouting() -{ - if (m_routingSession.IsBuilt()) - { - m_routingSession.EmitCloseRoutingEvent(); - } - m_routingSession.Reset(); - RemoveRoute(true /* deactivateFollowing */); -} - -void Framework::InsertRoute(Route const & route) -{ - if (m_drapeEngine == nullptr) - return; - - if (route.GetPoly().GetSize() < 2) - { - LOG(LWARNING, ("Invalid track - only", route.GetPoly().GetSize(), "point(s).")); - return; - } - - vector turns; - if (m_currentRouterType == RouterType::Vehicle || m_currentRouterType == RouterType::Bicycle || - m_currentRouterType == RouterType::Taxi) - { - route.GetTurnsDistances(turns); - } - - df::ColorConstant routeColor = df::kRouteColor; - df::RoutePattern pattern; - if (m_currentRouterType == RouterType::Pedestrian) - { - routeColor = df::kRoutePedestrian; - pattern = df::RoutePattern(4.0, 2.0); - } - else if (m_currentRouterType == RouterType::Bicycle) - { - routeColor = df::kRouteBicycle; - pattern = df::RoutePattern(8.0, 2.0); - } - - m_drapeEngine->AddRoute(route.GetPoly(), turns, routeColor, route.GetTraffic(), pattern); -} - -void Framework::CheckLocationForRouting(GpsInfo const & info) -{ - if (!IsRoutingActive()) - return; - - RoutingSession::State state = m_routingSession.OnLocationPositionChanged(info, m_model.GetIndex()); - if (state == RoutingSession::RouteNeedRebuild) - { - m_routingSession.RebuildRoute(MercatorBounds::FromLatLon(info.m_latitude, info.m_longitude), - [&](Route const & route, IRouter::ResultCode code){ OnRebuildRouteReady(route, code); }, - 0 /* timeoutSec */, - routing::RoutingSession::State::RouteRebuilding); - } -} - -void Framework::MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo) const -{ - if (!IsRoutingActive()) - return; - - m_routingSession.MatchLocationToRoute(location, routeMatchingInfo); -} - -void Framework::CallRouteBuilded(IRouter::ResultCode code, storage::TCountriesVec const & absentCountries) -{ - if (code == IRouter::Cancelled) - return; - m_routingCallback(code, absentCountries); -} - -string Framework::GetRoutingErrorMessage(IRouter::ResultCode code) -{ - string messageID = ""; - switch (code) - { - case IRouter::NoCurrentPosition: - messageID = "routing_failed_unknown_my_position"; - break; - case IRouter::InconsistentMWMandRoute: // the same as RouteFileNotExist - case IRouter::RouteFileNotExist: - messageID = "routing_failed_has_no_routing_file"; - break; - case IRouter::StartPointNotFound: - messageID = "routing_failed_start_point_not_found"; - break; - case IRouter::EndPointNotFound: - messageID = "routing_failed_dst_point_not_found"; - break; - case IRouter::PointsInDifferentMWM: - messageID = "routing_failed_cross_mwm_building"; - break; - case IRouter::RouteNotFound: - messageID = "routing_failed_route_not_found"; - break; - case IRouter::InternalError: - messageID = "routing_failed_internal_error"; - break; - default: - ASSERT(false, ()); - } - - return m_stringsBundle.GetString(messageID); -} - -void Framework::OnBuildRouteReady(Route const & route, IRouter::ResultCode code) -{ - storage::TCountriesVec absentCountries; - if (code == IRouter::NoError) - { - double const kRouteScaleMultiplier = 1.5; - - InsertRoute(route); - StopLocationFollow(); - - // Validate route (in case of bicycle routing it can be invalid). - ASSERT(route.IsValid(), ()); - if (route.IsValid()) - { - m2::RectD routeRect = route.GetPoly().GetLimitRect(); - routeRect.Scale(kRouteScaleMultiplier); - ShowRect(routeRect, -1); - } - } - else - { - absentCountries.assign(route.GetAbsentCountries().begin(), route.GetAbsentCountries().end()); - - if (code != IRouter::NeedMoreMaps) - RemoveRoute(true /* deactivateFollowing */); - } - CallRouteBuilded(code, absentCountries); -} - -void Framework::OnRebuildRouteReady(Route const & route, IRouter::ResultCode code) -{ - if (code != IRouter::NoError) - return; - - RemoveRoute(false /* deactivateFollowing */); - InsertRoute(route); - CallRouteBuilded(code, storage::TCountriesVec()); -} - -RouterType Framework::GetBestRouter(m2::PointD const & startPoint, m2::PointD const & finalPoint) const -{ - // todo Implement something more sophisticated here (or delete the method). - return GetLastUsedRouter(); -} - -RouterType Framework::GetLastUsedRouter() const -{ - string routerTypeStr; - if (!settings::Get(kRouterTypeKey, routerTypeStr)) - return RouterType::Vehicle; - - auto const routerType = routing::FromString(routerTypeStr); - - switch (routerType) - { - case RouterType::Pedestrian: - case RouterType::Bicycle: - return routerType; - default: - return RouterType::Vehicle; - } -} - -void Framework::SetLastUsedRouter(RouterType type) -{ - settings::Set(kRouterTypeKey, routing::ToString(type)); -} - -void Framework::SetRouteStartPoint(m2::PointD const & pt, bool isValid) -{ - if (m_drapeEngine != nullptr) - m_drapeEngine->SetRoutePoint(pt, true /* isStart */, isValid); -} - -void Framework::SetRouteFinishPoint(m2::PointD const & pt, bool isValid) -{ - if (m_drapeEngine != nullptr) - m_drapeEngine->SetRoutePoint(pt, false /* isStart */, isValid); -} - void Framework::AllowTransliteration(bool allowTranslit) { Transliteration::Instance().SetMode(allowTranslit ? Transliteration::Mode::Enabled @@ -3022,8 +2654,9 @@ bool Framework::LoadAutoZoom() void Framework::AllowAutoZoom(bool allowAutoZoom) { - bool const isPedestrianRoute = m_currentRouterType == RouterType::Pedestrian; - bool const isTaxiRoute = m_currentRouterType == RouterType::Taxi; + routing::RouterType const type = m_routingManager.GetRouter(); + bool const isPedestrianRoute = type == RouterType::Pedestrian; + bool const isTaxiRoute = type == RouterType::Taxi; CallDrapeFunction(bind(&df::DrapeEngine::AllowAutoZoom, _1, allowAutoZoom && !isPedestrianRoute && !isTaxiRoute)); @@ -3546,47 +3179,6 @@ bool Framework::OriginalFeatureHasDefaultName(FeatureID const & fid) const return osm::Editor::Instance().OriginalFeatureHasDefaultName(fid); } -bool Framework::HasRouteAltitude() const { return m_routingSession.HasRouteAltitude(); } - -bool Framework::GenerateRouteAltitudeChart(uint32_t width, uint32_t height, - vector & imageRGBAData, - int32_t & minRouteAltitude, int32_t & maxRouteAltitude, - measurement_utils::Units & altitudeUnits) const -{ - feature::TAltitudes altitudes; - vector segDistance; - - if (!m_routingSession.GetRouteAltitudesAndDistancesM(segDistance, altitudes)) - return false; - segDistance.insert(segDistance.begin(), 0.0); - - if (altitudes.empty()) - return false; - - if (!maps::GenerateChart(width, height, segDistance, altitudes, GetMapStyle(), imageRGBAData)) - return false; - - auto const minMaxIt = minmax_element(altitudes.cbegin(), altitudes.cend()); - feature::TAltitude const minRouteAltitudeM = *minMaxIt.first; - feature::TAltitude const maxRouteAltitudeM = *minMaxIt.second; - - if (!settings::Get(settings::kMeasurementUnits, altitudeUnits)) - altitudeUnits = measurement_utils::Units::Metric; - - switch (altitudeUnits) - { - case measurement_utils::Units::Imperial: - minRouteAltitude = measurement_utils::MetersToFeet(minRouteAltitudeM); - maxRouteAltitude = measurement_utils::MetersToFeet(maxRouteAltitudeM); - break; - case measurement_utils::Units::Metric: - minRouteAltitude = minRouteAltitudeM; - maxRouteAltitude = maxRouteAltitudeM; - break; - } - return true; -} - namespace { vector colorList = { dp::Color(255, 0, 0, 255), dp::Color(0, 255, 0, 255), dp::Color(0, 0, 255, 255), @@ -3657,3 +3249,32 @@ MwmSet::MwmId Framework::GetMwmIdByName(std::string const & name) const { return m_model.GetIndex().GetMwmIdByCountryFile(platform::CountryFile(name)); } + +// RoutingManager::Delegate +void Framework::OnRouteFollow(routing::RouterType type) +{ + bool const isPedestrianRoute = type == RouterType::Pedestrian; + bool const enableAutoZoom = isPedestrianRoute ? false : LoadAutoZoom(); + int const scale = + isPedestrianRoute ? scales::GetPedestrianNavigationScale() : scales::GetNavigationScale(); + int scale3d = + isPedestrianRoute ? scales::GetPedestrianNavigation3dScale() : scales::GetNavigation3dScale(); + if (enableAutoZoom) + ++scale3d; + + bool const isBicycleRoute = type == RouterType::Bicycle; + if ((isPedestrianRoute || isBicycleRoute) && LoadTrafficEnabled()) + { + m_trafficManager.SetEnabled(false /* enabled */); + SaveTrafficEnabled(false /* enabled */); + } + + m_drapeEngine->FollowRoute(scale, scale3d, enableAutoZoom); +} + +// RoutingManager::Delegate +void Framework::RegisterCountryFiles(std::shared_ptr ptr) const +{ + m_storage.ForEachCountryFile( + [&ptr](platform::CountryFile const & file) { ptr->RegisterFile(file); }); +} diff --git a/map/framework.hpp b/map/framework.hpp index 8248cbba23..2b6e7cd00a 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -9,6 +9,7 @@ #include "map/local_ads_manager.hpp" #include "map/mwm_url.hpp" #include "map/place_page_info.hpp" +#include "map/routing_manager.hpp" #include "map/track.hpp" #include "map/traffic_manager.hpp" @@ -113,7 +114,8 @@ struct FrameworkParams class Framework : public search::ViewportSearchCallback::Delegate, public search::DownloaderSearchCallback::Delegate, - public search::EverywhereSearchCallback::Delegate + public search::EverywhereSearchCallback::Delegate, + public RoutingManager::Delegate { DISALLOW_COPY(Framework); @@ -162,8 +164,6 @@ protected: using TViewportChanged = df::DrapeEngine::TModelViewListenerFn; TViewportChanged m_viewportChanged; - routing::RoutingSession m_routingSession; - drape_ptr m_drapeEngine; drape_ptr m_cpuDrawer; @@ -185,6 +185,9 @@ protected: bool m_isRenderingEnabled; tracking::Reporter m_trackingReporter; + // Note. |m_routingManager| should be declared before |m_trafficManager| + RoutingManager m_routingManager; + TrafficManager m_trafficManager; LocalAdsManager m_localAdsManager; @@ -455,7 +458,6 @@ public: void SetMyPositionModeListener(location::TMyPositionModeChanged && fn); private: - bool IsTrackingReporterEnabled() const; void OnUserPositionChanged(m2::PointD const & position); //@} @@ -744,77 +746,6 @@ public: //@} public: - using TRouteBuildingCallback = function; - using TRouteProgressCallback = function; - - /// @name Routing mode - //@{ - void SetRouter(routing::RouterType type); - routing::RouterType GetRouter() const; - bool IsRoutingActive() const { return m_routingSession.IsActive(); } - bool IsRouteBuilt() const { return m_routingSession.IsBuilt(); } - bool IsRouteBuilding() const { return m_routingSession.IsBuilding(); } - bool IsRouteBuildingOnly() const { return m_routingSession.IsBuildingOnly(); } - bool IsRouteRebuildingOnly() const { return m_routingSession.IsRebuildingOnly(); } - bool IsRouteNotReady() const { return m_routingSession.IsNotReady(); } - bool IsRouteFinished() const { return m_routingSession.IsFinished(); } - bool IsRouteNoFollowing() const { return m_routingSession.IsNoFollowing(); } - bool IsOnRoute() const { return m_routingSession.IsOnRoute(); } - bool IsRouteNavigable() const { return m_routingSession.IsNavigable(); } - - void BuildRoute(m2::PointD const & finish, uint32_t timeoutSec); - void BuildRoute(m2::PointD const & start, m2::PointD const & finish, bool isP2P, uint32_t timeoutSec); - // FollowRoute has a bug where the router follows the route even if the method hads't been called. - // This method was added because we do not want to break the behaviour that is familiar to our users. - bool DisableFollowMode(); - /// @TODO(AlexZ): Warning! These two routing callbacks are the only callbacks which are not called in the main thread context. - /// UI code should take it into an account. This is a result of current implementation, that can be improved: - /// Drape core calls some RunOnGuiThread with "this" pointers, and it causes crashes on Android, when Drape engine is destroyed - /// while switching between activities. Current workaround cleans all callbacks when destroying Drape engine - /// (@see MwmApplication.clearFunctorsOnUiThread on Android). Better soulution can be fair copying of all needed information into - /// lambdas/functors before calling RunOnGuiThread. - void SetRouteBuildingListener(TRouteBuildingCallback const & buildingCallback) { m_routingCallback = buildingCallback; } - /// See warning above. - void SetRouteProgressListener(TRouteProgressCallback const & progressCallback) { m_routingSession.SetProgressCallback(progressCallback); } - void FollowRoute(); - void CloseRouting(); - void GetRouteFollowingInfo(location::FollowingInfo & info) const { m_routingSession.GetRouteFollowingInfo(info); } - m2::PointD GetRouteEndPoint() const { return m_routingSession.GetEndPoint(); } - /// Returns the most situable router engine type. - routing::RouterType GetBestRouter(m2::PointD const & startPoint, m2::PointD const & finalPoint) const; - routing::RouterType GetLastUsedRouter() const; - void SetLastUsedRouter(routing::RouterType type); - // Sound notifications for turn instructions. - inline void EnableTurnNotifications(bool enable) { m_routingSession.EnableTurnNotifications(enable); } - inline bool AreTurnNotificationsEnabled() const { return m_routingSession.AreTurnNotificationsEnabled(); } - /// \brief Sets a locale for TTS. - /// \param locale is a string with locale code. For example "en", "ru", "zh-Hant" and so on. - /// \note See sound/tts/languages.txt for the full list of available locales. - inline void SetTurnNotificationsLocale(string const & locale) { m_routingSession.SetTurnNotificationsLocale(locale); } - /// @return current TTS locale. For example "en", "ru", "zh-Hant" and so on. - /// In case of error returns an empty string. - /// \note The method returns correct locale after SetTurnNotificationsLocale has been called. - /// If not, it returns an empty string. - inline string GetTurnNotificationsLocale() const { return m_routingSession.GetTurnNotificationsLocale(); } - /// \brief When an end user is going to a turn he gets sound turn instructions. - /// If C++ part wants the client to pronounce an instruction GenerateTurnNotifications (in - /// turnNotifications) returns - /// an array of one of more strings. C++ part assumes that all these strings shall be pronounced - /// by the client's TTS. - /// For example if C++ part wants the client to pronounce "Make a right turn." this method returns - /// an array with one string "Make a right turn.". The next call of the method returns nothing. - /// GenerateTurnNotifications shall be called by the client when a new position is available. - inline void GenerateTurnNotifications(vector & turnNotifications) - { - if (m_currentRouterType == routing::RouterType::Taxi) - return; - - return m_routingSession.GenerateTurnNotifications(turnNotifications); - } - - void SetRouteStartPoint(m2::PointD const & pt, bool isValid); - void SetRouteFinishPoint(m2::PointD const & pt, bool isValid); void AllowTransliteration(bool allowTranslit); bool LoadTransliteration(); @@ -842,25 +773,14 @@ public: bool LoadTrafficSimplifiedColors(); void SaveTrafficSimplifiedColors(bool simplified); - /// \returns true if altitude information along |m_route| is available and - /// false otherwise. - bool HasRouteAltitude() const; - /// \brief Generates 4 bytes per point image (RGBA) and put the data to |imageRGBAData|. - /// \param width is width of chart shall be generated in pixels. - /// \param height is height of chart shall be generated in pixels. - /// \param imageRGBAData is bits of result image in RGBA. - /// \param minRouteAltitude is min altitude along the route in altitudeUnits. - /// \param maxRouteAltitude is max altitude along the route in altitudeUnits. - /// \param altitudeUnits is units (meters or feet) which is used to pass min and max altitudes. - /// \returns If there is valid route info and the chart was generated returns true - /// and false otherwise. If the method returns true it is guaranteed that the size of - /// |imageRGBAData| is not zero. - /// \note If HasRouteAltitude() method returns true, GenerateRouteAltitudeChart(...) - /// could return false if route was deleted or rebuilt between the calls. - bool GenerateRouteAltitudeChart(uint32_t width, uint32_t height, - vector & imageRGBAData, - int32_t & minRouteAltitude, int32_t & maxRouteAltitude, - measurement_utils::Units & altitudeUnits) const; +public: + /// Routing Manager + RoutingManager & GetRoutingManager() { return m_routingManager; } + RoutingManager const & GetRoutingManager() const { return m_routingManager; } +protected: + /// RoutingManager::Delegate + void OnRouteFollow(routing::RouterType type) override; + void RegisterCountryFiles(std::shared_ptr ptr) const override; public: /// @name Editor interface. @@ -878,24 +798,6 @@ public: bool RollBackChanges(FeatureID const & fid); void CreateNote(osm::MapObject const & mapObject, osm::Editor::NoteProblemType const type, string const & note); - - //@} - -private: - void SetRouterImpl(routing::RouterType type); - void RemoveRoute(bool deactivateFollowing); - - void InsertRoute(routing::Route const & route); - void CheckLocationForRouting(location::GpsInfo const & info); - void CallRouteBuilded(routing::IRouter::ResultCode code, - storage::TCountriesVec const & absentCountries); - void MatchLocationToRoute(location::GpsInfo & info, location::RouteMatchingInfo & routeMatchingInfo) const; - string GetRoutingErrorMessage(routing::IRouter::ResultCode code); - void OnBuildRouteReady(routing::Route const & route, routing::IRouter::ResultCode code); - void OnRebuildRouteReady(routing::Route const & route, routing::IRouter::ResultCode code); - - TRouteBuildingCallback m_routingCallback; - routing::RouterType m_currentRouterType; //@} public: @@ -926,6 +828,4 @@ public: private: std::unique_ptr m_cityFinder; unique_ptr m_adsEngine; - - DECLARE_THREAD_CHECKER(m_threadChecker); }; diff --git a/platform/marketing_service.cpp b/platform/marketing_service.cpp index d7d5f1337a..7ffd24fe6e 100644 --- a/platform/marketing_service.cpp +++ b/platform/marketing_service.cpp @@ -24,7 +24,6 @@ char const * const kTrafficDiscovered = "traffic_discovered"; // Events. char const * const kDownloaderMapActionFinished = "Downloader_Map_action_finished"; char const * const kSearchEmitResultsAndCoords = "searchEmitResultsAndCoords"; -char const * const kRoutingCalculatingRoute = "Routing_CalculatingRoute"; char const * const kBookmarksBookmarkAction = "Bookmarks_Bookmark_action"; char const * const kPlacepageHotelBook = "Placepage_Hotel_book"; char const * const kEditorAddStart = "EditorAdd_start"; diff --git a/platform/marketing_service.hpp b/platform/marketing_service.hpp index 26db60aa97..be8a57b5a1 100644 --- a/platform/marketing_service.hpp +++ b/platform/marketing_service.hpp @@ -29,7 +29,6 @@ extern char const * const kTrafficDiscovered; // Events. extern char const * const kDownloaderMapActionFinished; extern char const * const kSearchEmitResultsAndCoords; -extern char const * const kRoutingCalculatingRoute; extern char const * const kBookmarksBookmarkAction; extern char const * const kPlacepageHotelBook; extern char const * const kEditorAddStart; From 4132af577f019346d4c966d8cc7bb7258e258bc9 Mon Sep 17 00:00:00 2001 From: VladiMihaylenko Date: Mon, 5 Jun 2017 12:38:44 +0300 Subject: [PATCH 4/7] Fixed qt build --- qt/draw_widget.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp index 4f92c650e4..5abc5fbcab 100644 --- a/qt/draw_widget.cpp +++ b/qt/draw_widget.cpp @@ -45,7 +45,7 @@ DrawWidget::DrawWidget(Framework & framework, bool apiOpenGLES3, QWidget * paren [this](place_page::Info const & info) { ShowPlacePage(info); }, [](bool /* switchFullScreenMode */) {}); // Empty deactivation listener. - m_framework.SetRouteBuildingListener( + m_framework.GetRoutingManager().SetRouteBuildingListener( [](routing::IRouter::ResultCode, storage::TCountriesVec const &) {}); m_framework.SetCurrentCountryChangedListener([this](storage::TCountryId const & countryId) { @@ -314,10 +314,10 @@ void DrawWidget::SubmitFakeLocationPoint(m2::PointD const & pt) m_framework.OnLocationUpdate(info); - if (m_framework.IsRoutingActive()) + if (m_framework.GetRoutingManager().IsRoutingActive()) { location::FollowingInfo loc; - m_framework.GetRouteFollowingInfo(loc); + m_framework.GetRoutingManager().GetRouteFollowingInfo(loc); LOG(LDEBUG, ("Distance:", loc.m_distToTarget, loc.m_targetUnitsSuffix, "Time:", loc.m_time, "Turn:", routing::turns::GetTurnString(loc.m_turn), "(", loc.m_distToTurn, loc.m_turnUnitsSuffix, ") Roundabout exit number:", loc.m_exitNum)); @@ -326,10 +326,11 @@ void DrawWidget::SubmitFakeLocationPoint(m2::PointD const & pt) void DrawWidget::SubmitRoutingPoint(m2::PointD const & pt) { - if (m_framework.IsRoutingActive()) - m_framework.CloseRouting(); + auto & routingManager = m_framework.GetRoutingManager(); + if (routingManager.IsRoutingActive()) + routingManager.CloseRouting(); else - m_framework.BuildRoute(m_framework.PtoG(pt), 0 /* timeoutSec */); + routingManager.BuildRoute(m_framework.PtoG(pt), 0 /* timeoutSec */); } void DrawWidget::ShowPlacePage(place_page::Info const & info) @@ -399,7 +400,7 @@ void DrawWidget::ShowInfoPopup(QMouseEvent * e, m2::PointD const & pt) void DrawWidget::SetRouter(routing::RouterType routerType) { - m_framework.SetRouter(routerType); + m_framework.GetRoutingManager().SetRouter(routerType); } void DrawWidget::SetSelectionMode(bool mode) { m_selectionMode = mode; } From 337806ef5621c2d78fc4b07c03792e8c578aa65a Mon Sep 17 00:00:00 2001 From: VladiMihaylenko Date: Mon, 5 Jun 2017 13:31:17 +0300 Subject: [PATCH 5/7] Fixed Android build --- android/jni/com/mapswithme/maps/Framework.cpp | 53 ++++++++++--------- android/jni/com/mapswithme/maps/Framework.hpp | 10 ++-- android/jni/com/mapswithme/maps/sound/tts.cpp | 8 +-- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index d0dbfc5e56..f91f3c5e5e 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -891,25 +891,25 @@ Java_com_mapswithme_maps_Framework_nativeLoadBookmarks(JNIEnv * env, jclass) JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_Framework_nativeIsRoutingActive(JNIEnv * env, jclass) { - return frm()->IsRoutingActive(); + return frm()->GetRoutingManager().IsRoutingActive(); } JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_Framework_nativeIsRouteBuilding(JNIEnv * env, jclass) { - return frm()->IsRouteBuilding(); + return frm()->GetRoutingManager().IsRouteBuilding(); } JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_Framework_nativeIsRouteBuilt(JNIEnv * env, jclass) { - return frm()->IsRouteBuilt(); + return frm()->GetRoutingManager().IsRouteBuilt(); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeCloseRouting(JNIEnv * env, jclass) { - frm()->CloseRouting(); + frm()->GetRoutingManager().CloseRouting(); } JNIEXPORT void JNICALL @@ -918,33 +918,32 @@ Java_com_mapswithme_maps_Framework_nativeBuildRoute(JNIEnv * env, jclass, jdouble finishLat, jdouble finishLon, jboolean isP2P) { - frm()->BuildRoute(MercatorBounds::FromLatLon(startLat, startLon), - MercatorBounds::FromLatLon(finishLat, finishLon), - isP2P, 0 /* timeoutSec */); - + frm()->GetRoutingManager().BuildRoute(MercatorBounds::FromLatLon(startLat, startLon), + MercatorBounds::FromLatLon(finishLat, finishLon), isP2P, + 0 /* timeoutSec */); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeFollowRoute(JNIEnv * env, jclass) { - frm()->FollowRoute(); + frm()->GetRoutingManager().FollowRoute(); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeDisableFollowing(JNIEnv * env, jclass) { - frm()->DisableFollowMode(); + frm()->GetRoutingManager().DisableFollowMode(); } JNIEXPORT jobjectArray JNICALL Java_com_mapswithme_maps_Framework_nativeGenerateTurnNotifications(JNIEnv * env, jclass) { ::Framework * fr = frm(); - if (!fr->IsRoutingActive()) + if (!fr->GetRoutingManager().IsRoutingActive()) return nullptr; vector turnNotifications; - fr->GenerateTurnNotifications(turnNotifications); + fr->GetRoutingManager().GenerateTurnNotifications(turnNotifications); if (turnNotifications.empty()) return nullptr; @@ -955,11 +954,11 @@ JNIEXPORT jobject JNICALL Java_com_mapswithme_maps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jclass) { ::Framework * fr = frm(); - if (!fr->IsRoutingActive()) + if (!fr->GetRoutingManager().IsRoutingActive()) return nullptr; location::FollowingInfo info; - fr->GetRouteFollowingInfo(info); + fr->GetRoutingManager().GetRouteFollowingInfo(info); if (!info.IsValid()) return nullptr; @@ -1016,7 +1015,8 @@ Java_com_mapswithme_maps_Framework_nativeGenerateRouteAltitudeChartBits(JNIEnv * int32_t minRouteAltitude = 0; int32_t maxRouteAltitude = 0; measurement_utils::Units units = measurement_utils::Units::Metric; - if (!fr->GenerateRouteAltitudeChart(width, height, imageRGBAData, minRouteAltitude, maxRouteAltitude, units)) + if (!fr->GetRoutingManager().GenerateRouteAltitudeChart( + width, height, imageRGBAData, minRouteAltitude, maxRouteAltitude, units)) { LOG(LWARNING, ("Can't generate route altitude image.")); return nullptr; @@ -1078,14 +1078,16 @@ JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeSetRoutingListener(JNIEnv * env, jclass, jobject listener) { CHECK(g_framework, ("Framework isn't created yet!")); - frm()->SetRouteBuildingListener(bind(&CallRoutingListener, jni::make_global_ref(listener), _1, _2)); + frm()->GetRoutingManager().SetRouteBuildingListener( + bind(&CallRoutingListener, jni::make_global_ref(listener), _1, _2)); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeSetRouteProgressListener(JNIEnv * env, jclass, jobject listener) { CHECK(g_framework, ("Framework isn't created yet!")); - frm()->SetRouteProgressListener(bind(&CallRouteProgressListener, jni::make_global_ref(listener), _1)); + frm()->GetRoutingManager().SetRouteProgressListener( + bind(&CallRouteProgressListener, jni::make_global_ref(listener), _1)); } JNIEXPORT void JNICALL @@ -1119,37 +1121,40 @@ Java_com_mapswithme_maps_Framework_nativeMarkMapStyle(JNIEnv * env, jclass, jint JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeSetRouter(JNIEnv * env, jclass, jint routerType) { - g_framework->SetRouter(static_cast(routerType)); + g_framework->GetRoutingManager().SetRouter(static_cast(routerType)); } JNIEXPORT jint JNICALL Java_com_mapswithme_maps_Framework_nativeGetRouter(JNIEnv * env, jclass) { - return static_cast(g_framework->GetRouter()); + return static_cast(g_framework->GetRoutingManager().GetRouter()); } JNIEXPORT jint JNICALL Java_com_mapswithme_maps_Framework_nativeGetLastUsedRouter(JNIEnv * env, jclass) { - return static_cast(g_framework->GetLastUsedRouter()); + return static_cast(g_framework->GetRoutingManager().GetLastUsedRouter()); } JNIEXPORT jint JNICALL Java_com_mapswithme_maps_Framework_nativeGetBestRouter(JNIEnv * env, jclass, jdouble srcLat, jdouble srcLon, jdouble dstLat, jdouble dstLon) { - return static_cast(frm()->GetBestRouter(MercatorBounds::FromLatLon(srcLat, srcLon), MercatorBounds::FromLatLon(dstLat, dstLon))); + return static_cast(frm()->GetRoutingManager().GetBestRouter( + MercatorBounds::FromLatLon(srcLat, srcLon), MercatorBounds::FromLatLon(dstLat, dstLon))); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeSetRouteStartPoint(JNIEnv * env, jclass, jdouble lat, jdouble lon, jboolean valid) { - frm()->SetRouteStartPoint(m2::PointD(MercatorBounds::FromLatLon(lat, lon)), static_cast(valid)); + frm()->GetRoutingManager().SetRouteStartPoint(m2::PointD(MercatorBounds::FromLatLon(lat, lon)), + static_cast(valid)); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeSetRouteEndPoint(JNIEnv * env, jclass, jdouble lat, jdouble lon, jboolean valid) { - frm()->SetRouteFinishPoint(m2::PointD(MercatorBounds::FromLatLon(lat, lon)), static_cast(valid)); + frm()->GetRoutingManager().SetRouteFinishPoint(m2::PointD(MercatorBounds::FromLatLon(lat, lon)), + static_cast(valid)); } JNIEXPORT void JNICALL @@ -1289,7 +1294,7 @@ Java_com_mapswithme_maps_Framework_nativeSetVisibleRect(JNIEnv * env, jclass, ji JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_Framework_nativeIsRouteFinished(JNIEnv * env, jclass) { - return frm()->IsRouteFinished(); + return frm()->GetRoutingManager().IsRouteFinished(); } JNIEXPORT void JNICALL diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index 781161fe6c..e83860979e 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -90,9 +90,13 @@ namespace android void SetupMeasurementSystem(); - void SetRouter(routing::RouterType type) { m_work.SetRouter(type); } - routing::RouterType GetRouter() const { return m_work.GetRouter(); } - routing::RouterType GetLastUsedRouter() const { return m_work.GetLastUsedRouter(); } + RoutingManager & GetRoutingManager() { return m_work.GetRoutingManager(); } + void SetRouter(routing::RouterType type) { m_work.GetRoutingManager().SetRouter(type); } + routing::RouterType GetRouter() const { return m_work.GetRoutingManager().GetRouter(); } + routing::RouterType GetLastUsedRouter() const + { + return m_work.GetRoutingManager().GetLastUsedRouter(); + } void Resize(int w, int h); diff --git a/android/jni/com/mapswithme/maps/sound/tts.cpp b/android/jni/com/mapswithme/maps/sound/tts.cpp index 56261334d6..ae923fbeec 100644 --- a/android/jni/com/mapswithme/maps/sound/tts.cpp +++ b/android/jni/com/mapswithme/maps/sound/tts.cpp @@ -13,24 +13,24 @@ extern "C" JNIEXPORT void JNICALL Java_com_mapswithme_maps_sound_TtsPlayer_nativeEnableTurnNotifications(JNIEnv * env, jclass thiz, jboolean enable) { - return frm()->EnableTurnNotifications(static_cast(enable)); + return frm()->GetRoutingManager().EnableTurnNotifications(static_cast(enable)); } JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_sound_TtsPlayer_nativeAreTurnNotificationsEnabled(JNIEnv * env, jclass clazz) { - return static_cast(frm()->AreTurnNotificationsEnabled()); + return static_cast(frm()->GetRoutingManager().AreTurnNotificationsEnabled()); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_sound_TtsPlayer_nativeSetTurnNotificationsLocale(JNIEnv * env, jclass thiz, jstring jLocale) { - frm()->SetTurnNotificationsLocale(jni::ToNativeString(env, jLocale)); + frm()->GetRoutingManager().SetTurnNotificationsLocale(jni::ToNativeString(env, jLocale)); } JNIEXPORT jstring JNICALL Java_com_mapswithme_maps_sound_TtsPlayer_nativeGetTurnNotificationsLocale(JNIEnv * env, jclass thiz) { - return jni::ToJavaString(env, frm()->GetTurnNotificationsLocale().c_str()); + return jni::ToJavaString(env, frm()->GetRoutingManager().GetTurnNotificationsLocale().c_str()); } } // extern "C" From 8c2a0f67ae869a20f2d79adb2987890285287466 Mon Sep 17 00:00:00 2001 From: VladiMihaylenko Date: Mon, 5 Jun 2017 13:31:31 +0300 Subject: [PATCH 6/7] Fixed iOS build --- .../MWMMapViewControlsManager.mm | 4 +- .../SideButtons/MWMSideButtons.mm | 2 +- .../MWMNavigationDashboardEntity.mm | 4 +- .../MWMNavigationDashboardManager.mm | 2 +- .../Sound/MWMTextToSpeech.mm | 15 +++--- iphone/Maps/Classes/MapsAppDelegate.mm | 4 +- .../Classes/Widgets/MWMMapDownloadDialog.mm | 2 +- .../Core/Framework/MWMFrameworkListener.mm | 4 +- .../Maps/Core/Location/MWMLocationManager.mm | 12 ++--- iphone/Maps/Core/Routing/MWMRouter.mm | 46 ++++++++++--------- .../Maps/Core/Routing/MWMRouterSavedState.mm | 8 ++-- iphone/Maps/Core/Storage/MWMStorage.mm | 2 +- .../BottomMenu/MWMBottomMenuViewController.mm | 7 +-- xcode/map/map.xcodeproj/project.pbxproj | 8 ++++ 14 files changed, 68 insertions(+), 52 deletions(-) diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm index 88a2803fe8..b9e3003f78 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/MWMMapViewControlsManager.mm @@ -264,7 +264,7 @@ extern NSString * const kAlohalyticsTapEventKey; MapViewController * ownerController = self.ownerController; if (platform::migrate::NeedMigrate()) { - if (GetFramework().IsRoutingActive()) + if (GetFramework().GetRoutingManager().IsRoutingActive()) { [Statistics logEvent:kStatDownloaderMigrationProhibitedDialogue withParameters:@{kStatFrom : kStatDownloader}]; @@ -441,7 +441,7 @@ extern NSString * const kAlohalyticsTapEventKey; if (![MWMRouter router].startPoint.isMyPosition) { dispatch_async(dispatch_get_main_queue(), ^{ - GetFramework().DisableFollowMode(); + GetFramework().GetRoutingManager().DisableFollowMode(); [self.navigationManager updateDashboard]; }); } diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm index 8608db559f..34f3dba034 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm @@ -206,7 +206,7 @@ NSArray * animationImages(NSString * animationTemplate, NSUInteger im - (BOOL)zoomHidden { return self.sideView.zoomHidden; } - (void)setZoomHidden:(BOOL)zoomHidden { - if (GetFramework().IsRoutingActive()) + if (GetFramework().GetRoutingManager().IsRoutingActive()) self.sideView.zoomHidden = NO; else self.sideView.zoomHidden = [MWMSettings zoomButtonsEnabled] ? zoomHidden : YES; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm index 430400966b..f659097189 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardEntity.mm @@ -23,7 +23,7 @@ using namespace routing::turns; _progress = info.m_completionPercent; auto & f = GetFramework(); CLLocation * lastLocation = [MWMLocationManager lastLocation]; - if (lastLocation && f.GetRouter() == routing::RouterType::Pedestrian) + if (lastLocation && f.GetRoutingManager().GetRouter() == routing::RouterType::Pedestrian) { _isPedestrian = YES; string distance; @@ -78,7 +78,7 @@ using namespace routing::turns; UIImage * image(routing::turns::TurnDirection t, bool isNextTurn) { - if (GetFramework().GetRouter() == routing::RouterType::Pedestrian) + if (GetFramework().GetRoutingManager().GetRouter() == routing::RouterType::Pedestrian) return [UIImage imageNamed:@"ic_direction"]; NSString * imageName; diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm index 78d8f5f104..982a8310d5 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/MWMNavigationDashboardManager.mm @@ -65,7 +65,7 @@ using TInfoDisplays = NSHashTable<__kindof TInfoDisplay>; - (void)updateFollowingInfo:(location::FollowingInfo const &)info { - if (GetFramework().IsRouteFinished()) + if (GetFramework().GetRoutingManager().IsRouteFinished()) { [MWMRouter stopRouting]; AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); diff --git a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm index e6cecc93c0..2b40017448 100644 --- a/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm +++ b/iphone/Maps/Classes/CustomViews/NavigationDashboard/Sound/MWMTextToSpeech.mm @@ -153,7 +153,7 @@ vector> availableLanguages() if (active && ![self isValid]) [self createSynthesizer]; [self setAudioSessionActive:active]; - GetFramework().EnableTurnNotifications(active ? true : false); + GetFramework().GetRoutingManager().EnableTurnNotifications(active ? true : false); runAsyncOnMainQueue(^{ [[NSNotificationCenter defaultCenter] postNotificationName:[[self class] ttsStatusNotificationKey] @@ -164,7 +164,10 @@ vector> availableLanguages() - (BOOL)active { - return [[self class] isTTSEnabled] && GetFramework().AreTurnNotificationsEnabled() ? YES : NO; + return [[self class] isTTSEnabled] && + GetFramework().GetRoutingManager().AreTurnNotificationsEnabled() + ? YES + : NO; } + (NSString *)savedLanguage @@ -222,7 +225,7 @@ vector> availableLanguages() LOG(LERROR, ("Cannot convert UI locale or default locale to twine language. MWMTextToSpeech " "is invalid.")); else - GetFramework().SetTurnNotificationsLocale(twineLang); + GetFramework().GetRoutingManager().SetTurnNotificationsLocale(twineLang); } else { @@ -242,12 +245,12 @@ vector> availableLanguages() - (void)playTurnNotifications { - Framework & frm = GetFramework(); - if (!frm.IsRoutingActive()) + auto & routingManager = GetFramework().GetRoutingManager(); + if (!routingManager.IsRoutingActive()) return; vector notifications; - frm.GenerateTurnNotifications(notifications); + routingManager.GenerateTurnNotifications(notifications); if (![self isValid]) return; diff --git a/iphone/Maps/Classes/MapsAppDelegate.mm b/iphone/Maps/Classes/MapsAppDelegate.mm index c081cef0de..16d31f49e7 100644 --- a/iphone/Maps/Classes/MapsAppDelegate.mm +++ b/iphone/Maps/Classes/MapsAppDelegate.mm @@ -235,7 +235,7 @@ using namespace osm_auth_ios; case ParsedMapApi::ParsingResult::Route: { auto const parsedData = f.GetParsedRoutingData(); - f.SetRouter(parsedData.m_type); + f.GetRoutingManager().SetRouter(parsedData.m_type); auto const points = parsedData.m_points; auto const & p1 = points[0]; auto const & p2 = points[1]; @@ -944,7 +944,7 @@ using namespace osm_auth_ios; - (void)showAlert:(BOOL)isRate { - if (!Platform::IsConnected() || GetFramework().IsRoutingActive()) + if (!Platform::IsConnected() || GetFramework().GetRoutingManager().IsRoutingActive()) return; if (isRate) diff --git a/iphone/Maps/Classes/Widgets/MWMMapDownloadDialog.mm b/iphone/Maps/Classes/Widgets/MWMMapDownloadDialog.mm index e00fe0f6a9..d287cb6320 100644 --- a/iphone/Maps/Classes/Widgets/MWMMapDownloadDialog.mm +++ b/iphone/Maps/Classes/Widgets/MWMMapDownloadDialog.mm @@ -98,7 +98,7 @@ using namespace storage; NodeAttrs nodeAttrs; s.GetNodeAttrs(m_countryId, nodeAttrs); - if (!nodeAttrs.m_present && !f.IsRoutingActive()) + if (!nodeAttrs.m_present && !f.GetRoutingManager().IsRoutingActive()) { BOOL const isMultiParent = nodeAttrs.m_parentInfo.size() > 1; BOOL const noParrent = (nodeAttrs.m_parentInfo[0].m_id == s.GetRootId()); diff --git a/iphone/Maps/Core/Framework/MWMFrameworkListener.mm b/iphone/Maps/Core/Framework/MWMFrameworkListener.mm index 76ad0afd84..c1204dbec9 100644 --- a/iphone/Maps/Core/Framework/MWMFrameworkListener.mm +++ b/iphone/Maps/Core/Framework/MWMFrameworkListener.mm @@ -106,13 +106,13 @@ void loopWrappers(TObservers * observers, TLoopBlock block) // This will help to avoid unnecessary parameters copying and will make all our framework // callbacks // consistent: every notification to UI will run on a main UI thread. - f.SetRouteBuildingListener( + f.GetRoutingManager().SetRouteBuildingListener( [observers](IRouter::ResultCode code, TCountriesVec const & absentCountries) { loopWrappers(observers, [code, absentCountries](TRouteBuildingObserver observer) { [observer processRouteBuilderEvent:code countries:absentCountries]; }); }); - f.SetRouteProgressListener([observers](float progress) { + f.GetRoutingManager().SetRouteProgressListener([observers](float progress) { loopWrappers(observers, [progress](TRouteBuildingObserver observer) { if ([observer respondsToSelector:@selector(processRouteBuilderProgress:)]) [observer processRouteBuilderProgress:progress]; diff --git a/iphone/Maps/Core/Location/MWMLocationManager.mm b/iphone/Maps/Core/Location/MWMLocationManager.mm index 07f7cd26ff..f70e179e50 100644 --- a/iphone/Maps/Core/Location/MWMLocationManager.mm +++ b/iphone/Maps/Core/Location/MWMLocationManager.mm @@ -123,10 +123,10 @@ BOOL keepRunningInBackground() if (needGPSForTrackRecorder) return YES; - auto const & f = GetFramework(); - bool const isRouteBuilt = f.IsRouteBuilt(); - bool const isRouteFinished = f.IsRouteFinished(); - bool const isRouteRebuildingOnly = f.IsRouteRebuildingOnly(); + auto const & routingManager = GetFramework().GetRoutingManager(); + bool const isRouteBuilt = routingManager.IsRouteBuilt(); + bool const isRouteFinished = routingManager.IsRouteFinished(); + bool const isRouteRebuildingOnly = routingManager.IsRouteRebuildingOnly(); bool const needGPSForRouting = ((isRouteBuilt || isRouteRebuildingOnly) && !isRouteFinished); if (needGPSForRouting) return YES; @@ -333,9 +333,9 @@ void setPermissionRequested() [manager.predictor setMyPositionMode:mode]; [manager processLocationStatus:manager.lastLocationStatus]; auto const & f = GetFramework(); - if (f.IsRoutingActive()) + if (f.GetRoutingManager().IsRoutingActive()) { - switch (f.GetRouter()) + switch (f.GetRoutingManager().GetRouter()) { case routing::RouterType::Vehicle: manager.geoMode = GeoMode::VehicleRouting; break; case routing::RouterType::Pedestrian: manager.geoMode = GeoMode::PedestrianRouting; break; diff --git a/iphone/Maps/Core/Routing/MWMRouter.mm b/iphone/Maps/Core/Routing/MWMRouter.mm index 8d386b4bd4..d7abb0aa47 100644 --- a/iphone/Maps/Core/Routing/MWMRouter.mm +++ b/iphone/Maps/Core/Routing/MWMRouter.mm @@ -64,8 +64,11 @@ bool isMarkerPoint(MWMRoutePoint * point) { return point.isValid && !point.isMyP return router; } -+ (BOOL)hasRouteAltitude { return GetFramework().HasRouteAltitude(); } -+ (BOOL)isTaxi { return GetFramework().GetRouter() == routing::RouterType::Taxi; } ++ (BOOL)hasRouteAltitude { return GetFramework().GetRoutingManager().HasRouteAltitude(); } ++ (BOOL)isTaxi +{ + return GetFramework().GetRoutingManager().GetRouter() == routing::RouterType::Taxi; +} + (void)startRouting { auto router = [self router]; @@ -97,7 +100,7 @@ bool isMarkerPoint(MWMRoutePoint * point) { return point.isValid && !point.isMyP [MWMNavigationDashboardManager manager].taxiDataSource = nil; } -+ (BOOL)isRoutingActive { return GetFramework().IsRoutingActive(); } ++ (BOOL)isRoutingActive { return GetFramework().GetRoutingManager().IsRoutingActive(); } - (instancetype)initRouter { self = [super init]; @@ -124,10 +127,10 @@ bool isMarkerPoint(MWMRoutePoint * point) { return point.isValid && !point.isMyP if (type == self.type) return; [self doStop]; - GetFramework().SetRouter(coreRouterType(type)); + GetFramework().GetRoutingManager().SetRouter(coreRouterType(type)); } -- (MWMRouterType)type { return routerType(GetFramework().GetRouter()); } +- (MWMRouterType)type { return routerType(GetFramework().GetRoutingManager().GetRouter()); } - (BOOL)arePointsValidForRouting { return self.startPoint.isValid && self.finishPoint.isValid && self.startPoint != self.finishPoint; @@ -196,10 +199,11 @@ bool isMarkerPoint(MWMRoutePoint * point) { return point.isValid && !point.isMyP auto finishPoint = mercatorMWMRoutePoint(self.finishPoint); // Taxi can't be used as best router. if (bestRouter && ![[self class] isTaxi]) - self.type = routerType(GetFramework().GetBestRouter(startPoint, finishPoint)); - f.BuildRoute(startPoint, finishPoint, isP2P, 0 /* timeoutSec */); - f.SetRouteStartPoint(startPoint, isMarkerPoint(self.startPoint)); - f.SetRouteFinishPoint(finishPoint, isMarkerPoint(self.finishPoint)); + self.type = + routerType(GetFramework().GetRoutingManager().GetBestRouter(startPoint, finishPoint)); + f.GetRoutingManager().BuildRoute(startPoint, finishPoint, isP2P, 0 /* timeoutSec */); + f.GetRoutingManager().SetRouteStartPoint(startPoint, isMarkerPoint(self.startPoint)); + f.GetRoutingManager().SetRouteFinishPoint(finishPoint, isMarkerPoint(self.finishPoint)); [mapViewControlsManager onRouteRebuild]; } @@ -218,7 +222,7 @@ bool isMarkerPoint(MWMRoutePoint * point) { return point.isValid && !point.isMyP if (self.startPoint.isMyPosition) { - GetFramework().FollowRoute(); + GetFramework().GetRoutingManager().FollowRoute(); [[MWMMapViewControlsManager manager] onRouteStart]; MapsAppDelegate * app = [MapsAppDelegate theApp]; app.routingPlaneMode = MWMRoutingPlaneModeNone; @@ -265,10 +269,10 @@ bool isMarkerPoint(MWMRoutePoint * point) { return point.isValid && !point.isMyP { // Don't save taxi routing type as default. if ([[self class] isTaxi]) - GetFramework().SetRouter(routing::RouterType::Vehicle); + GetFramework().GetRoutingManager().SetRouter(routing::RouterType::Vehicle); [self clearAltitudeImagesData]; - GetFramework().CloseRouting(); + GetFramework().GetRoutingManager().CloseRouting(); MapsAppDelegate * app = [MapsAppDelegate theApp]; app.routingPlaneMode = MWMRoutingPlaneModeNone; [MWMRouterSavedState remove]; @@ -278,11 +282,11 @@ bool isMarkerPoint(MWMRoutePoint * point) { return point.isValid && !point.isMyP - (void)updateFollowingInfo { - auto & f = GetFramework(); - if (!f.IsRoutingActive()) + auto const & f = GetFramework(); + if (!f.GetRoutingManager().IsRoutingActive()) return; location::FollowingInfo info; - f.GetRouteFollowingInfo(info); + f.GetRoutingManager().GetRouteFollowingInfo(info); if (info.IsValid()) [[MWMNavigationDashboardManager manager] updateFollowingInfo:info]; } @@ -308,8 +312,8 @@ bool isMarkerPoint(MWMRoutePoint * point) { return point.isValid && !point.isMyP int32_t minRouteAltitude = 0; int32_t maxRouteAltitude = 0; measurement_utils::Units units = measurement_utils::Units::Metric; - if (!GetFramework().GenerateRouteAltitudeChart(width, height, imageRGBAData, - minRouteAltitude, maxRouteAltitude, units)) + if (!GetFramework().GetRoutingManager().GenerateRouteAltitudeChart( + width, height, imageRGBAData, minRouteAltitude, maxRouteAltitude, units)) { return; } @@ -343,11 +347,11 @@ bool isMarkerPoint(MWMRoutePoint * point) { return point.isValid && !point.isMyP - (void)onLocationUpdate:(location::GpsInfo const &)info { - auto & f = GetFramework(); - if (f.IsRoutingActive()) + auto const & routingManager = GetFramework().GetRoutingManager(); + if (routingManager.IsRoutingActive()) { MWMTextToSpeech * tts = [MWMTextToSpeech tts]; - if (f.IsOnRoute() && tts.active) + if (routingManager.IsOnRoute() && tts.active) [tts playTurnNotifications]; [self updateFollowingInfo]; @@ -358,7 +362,7 @@ bool isMarkerPoint(MWMRoutePoint * point) { return point.isValid && !point.isMyP if (state.forceStateChange == MWMRouterForceStateChange::Rebuild) { state.forceStateChange = MWMRouterForceStateChange::Start; - self.type = routerType(GetFramework().GetLastUsedRouter()); + self.type = routerType(GetFramework().GetRoutingManager().GetLastUsedRouter()); [self buildToPoint:state.restorePoint bestRouter:NO]; } } diff --git a/iphone/Maps/Core/Routing/MWMRouterSavedState.mm b/iphone/Maps/Core/Routing/MWMRouterSavedState.mm index 451559dff0..a88ea6b043 100644 --- a/iphone/Maps/Core/Routing/MWMRouterSavedState.mm +++ b/iphone/Maps/Core/Routing/MWMRouterSavedState.mm @@ -49,11 +49,11 @@ static NSString * const kETAKey = @"eta"; + (void)store { Framework & f = GetFramework(); - if (!f.IsOnRoute()) + if (!f.GetRoutingManager().IsOnRoute()) return; location::FollowingInfo routeInfo; - f.GetRouteFollowingInfo(routeInfo); - m2::PointD const endPoint = f.GetRouteEndPoint(); + f.GetRoutingManager().GetRouteFollowingInfo(routeInfo); + m2::PointD const endPoint = f.GetRoutingManager().GetRouteEndPoint(); NSMutableDictionary * const stateDict = [NSMutableDictionary dictionary]; NSUInteger size; NSGetSizeAndAlignment(@encode(m2::PointD), &size, nullptr); @@ -75,7 +75,7 @@ static NSString * const kETAKey = @"eta"; + (void)restore { - if (GetFramework().IsRoutingActive()) + if (GetFramework().GetRoutingManager().IsRoutingActive()) return; if ([MWMRouterSavedState state].forceStateChange == MWMRouterForceStateChange::None) [self remove]; diff --git a/iphone/Maps/Core/Storage/MWMStorage.mm b/iphone/Maps/Core/Storage/MWMStorage.mm index 25b2e108fc..f1b8a9e750 100644 --- a/iphone/Maps/Core/Storage/MWMStorage.mm +++ b/iphone/Maps/Core/Storage/MWMStorage.mm @@ -51,7 +51,7 @@ using namespace storage; + (void)deleteNode:(TCountryId const &)countryId { auto & f = GetFramework(); - if (f.IsRoutingActive()) + if (f.GetRoutingManager().IsRoutingActive()) { [[MWMAlertViewController activeAlertController] presentDeleteMapProhibitedAlert]; return; diff --git a/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm b/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm index 9dc83ad223..8b21134432 100644 --- a/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm +++ b/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm @@ -287,10 +287,11 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { - (void)ttsButtonStatusChanged:(NSNotification *)notification { - auto & f = GetFramework(); - if (!f.IsRoutingActive()) + auto const & f = GetFramework(); + if (!f.GetRoutingManager().IsRoutingActive()) return; - BOOL const isPedestrianRouting = f.GetRouter() == routing::RouterType::Pedestrian; + BOOL const isPedestrianRouting = + f.GetRoutingManager().GetRouter() == routing::RouterType::Pedestrian; MWMButton * ttsButton = self.ttsSoundButton; ttsButton.hidden = isPedestrianRouting || ![MWMTextToSpeech isTTSEnabled]; if (!ttsButton.hidden) diff --git a/xcode/map/map.xcodeproj/project.pbxproj b/xcode/map/map.xcodeproj/project.pbxproj index ff17411488..98d059feb5 100644 --- a/xcode/map/map.xcodeproj/project.pbxproj +++ b/xcode/map/map.xcodeproj/project.pbxproj @@ -109,6 +109,8 @@ F6B283081C1B03320081957A /* gps_track_storage.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6B283001C1B03320081957A /* gps_track_storage.hpp */; }; F6B283091C1B03320081957A /* gps_track.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6B283011C1B03320081957A /* gps_track.cpp */; }; F6B2830A1C1B03320081957A /* gps_track.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6B283021C1B03320081957A /* gps_track.hpp */; }; + F6D2CE7E1EDEB7F500636DFD /* routing_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6D2CE7C1EDEB7F500636DFD /* routing_manager.cpp */; }; + F6D2CE7F1EDEB7F500636DFD /* routing_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6D2CE7D1EDEB7F500636DFD /* routing_manager.hpp */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -236,6 +238,8 @@ F6B283001C1B03320081957A /* gps_track_storage.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gps_track_storage.hpp; sourceTree = ""; }; F6B283011C1B03320081957A /* gps_track.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gps_track.cpp; sourceTree = ""; }; F6B283021C1B03320081957A /* gps_track.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gps_track.hpp; sourceTree = ""; }; + F6D2CE7C1EDEB7F500636DFD /* routing_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = routing_manager.cpp; sourceTree = ""; }; + F6D2CE7D1EDEB7F500636DFD /* routing_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = routing_manager.hpp; sourceTree = ""; }; F6DA2A961CCE24DB00F087B5 /* libdrape_frontend.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdrape_frontend.a; path = "../../../omim-xcode-build/Debug/libdrape_frontend.a"; sourceTree = ""; }; F6DA2A981CCE252600F087B5 /* libeditor.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libeditor.a; path = "../../../omim-xcode-build/Debug/libeditor.a"; sourceTree = ""; }; F6DA2A991CCE252600F087B5 /* liboauthcpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liboauthcpp.a; path = "../../../omim-xcode-build/Debug/liboauthcpp.a"; sourceTree = ""; }; @@ -418,6 +422,8 @@ 45580ABC1E2CBD5E00CD535D /* benchmark_tools.cpp */, F63421F61DF9BF9100A96868 /* reachable_by_taxi_checker.cpp */, F63421F71DF9BF9100A96868 /* reachable_by_taxi_checker.hpp */, + F6D2CE7C1EDEB7F500636DFD /* routing_manager.cpp */, + F6D2CE7D1EDEB7F500636DFD /* routing_manager.hpp */, 347B60741DD9926D0050FA24 /* traffic_manager.cpp */, 347B60751DD9926D0050FA24 /* traffic_manager.hpp */, 348AB57A1D7EE0C6009F8301 /* chart_generator.cpp */, @@ -495,6 +501,7 @@ 6753469C1A4054E800A0A8C3 /* track.hpp in Headers */, 675346651A4054E800A0A8C3 /* framework.hpp in Headers */, 674A2A381B2715FB001A525C /* osm_opening_hours.hpp in Headers */, + F6D2CE7F1EDEB7F500636DFD /* routing_manager.hpp in Headers */, 670E39411C46C5C700E9C0A6 /* gps_tracker.hpp in Headers */, 45580ABF1E2CBD5E00CD535D /* benchmark_tools.hpp in Headers */, 342D833B1D5233E8000D8AEA /* displacement_mode_manager.hpp in Headers */, @@ -619,6 +626,7 @@ 342D833A1D5233E8000D8AEA /* displacement_mode_manager.cpp in Sources */, 45201E931CE4AC90008A4842 /* api_mark_point.cpp in Sources */, 675346661A4054E800A0A8C3 /* ge0_parser.cpp in Sources */, + F6D2CE7E1EDEB7F500636DFD /* routing_manager.cpp in Sources */, 3D74ABBE1EA76F1D0063A898 /* local_ads_supported_types.cpp in Sources */, 0C2B73DE1E92AB9900530BB8 /* local_ads_manager.cpp in Sources */, F6B283071C1B03320081957A /* gps_track_storage.cpp in Sources */, From e71f055fefe09a9e9b6ed5df513b070bfe30b04c Mon Sep 17 00:00:00 2001 From: VladiMihaylenko Date: Mon, 5 Jun 2017 14:42:37 +0300 Subject: [PATCH 7/7] Review fixes --- map/framework.cpp | 58 +++++++++------------------------ map/framework.hpp | 3 +- map/routing_manager.cpp | 72 ++++++++++++++++++++++++++++++++--------- map/routing_manager.hpp | 34 +++++++++++++------ 4 files changed, 98 insertions(+), 69 deletions(-) diff --git a/map/framework.cpp b/map/framework.cpp index f0faa847c1..f07544087c 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -237,16 +237,7 @@ void Framework::OnLocationUpdate(GpsInfo const & info) GpsInfo rInfo(info); #endif - location::RouteMatchingInfo routeMatchingInfo; - m_routingManager.CheckLocationForRouting(rInfo); - - m_routingManager.MatchLocationToRoute(rInfo, routeMatchingInfo); - - auto & routingSession = m_routingManager.RoutingSession(); - CallDrapeFunction(bind(&df::DrapeEngine::SetGpsInfo, _1, rInfo, routingSession.IsNavigable(), - routeMatchingInfo)); - if (m_routingManager.IsTrackingReporterEnabled()) - m_trackingReporter.AddLocation(info, routingSession.MatchTraffic(routeMatchingInfo)); + m_routingManager.OnLocationUpdate(rInfo); } void Framework::OnCompassUpdate(CompassInfo const & info) @@ -285,10 +276,7 @@ void Framework::OnUserPositionChanged(m2::PointD const & position) { MyPositionMarkPoint * myPosition = UserMarkContainer::UserMarkForMyPostion(); myPosition->SetUserPosition(position); - - if (m_routingManager.IsRoutingActive()) - m_routingManager.RoutingSession().SetUserCurrentPosition(position); - + m_routingManager.SetUserCurrentPosition(position); m_trafficManager.UpdateMyPosition(TrafficManager::MyPosition(position)); } @@ -392,19 +380,15 @@ Framework::Framework(FrameworkParams const & params) , m_storage(platform::migrate::NeedMigrate() ? COUNTRIES_OBSOLETE_FILE : COUNTRIES_FILE) , m_bmManager(*this) , m_isRenderingEnabled(true) - , m_trackingReporter(platform::CreateSocket(), TRACKING_REALTIME_HOST, TRACKING_REALTIME_PORT, - tracking::Reporter::kPushDelayMs) , m_routingManager(RoutingManager::Callbacks([this]() -> Index & { return m_model.GetIndex(); }, bind(&Framework::GetCountryInfoGetter, this), [this](m2::PointD const & pt) { #ifdef DEBUG - { - UserMarkControllerGuard guard( - m_bmManager, UserMarkType::DEBUG_MARK); - guard.m_controller.SetIsVisible(true); - guard.m_controller.SetIsDrawable(true); - guard.m_controller.CreateUserMark(pt); - } + UserMarkControllerGuard guard( + m_bmManager, UserMarkType::DEBUG_MARK); + guard.m_controller.SetIsVisible(true); + guard.m_controller.SetIsDrawable(true); + guard.m_controller.CreateUserMark(pt); #endif }), static_cast(*this)) @@ -610,7 +594,7 @@ void Framework::ShowNode(storage::TCountryId const & countryId) void Framework::OnCountryFileDownloaded(storage::TCountryId const & countryId, storage::Storage::TLocalFilePtr const localFile) { // Soft reset to signal that mwm file may be out of date in routing caches. - m_routingManager.RoutingSession().Reset(); + m_routingManager.ResetRoutingSession(); m2::RectD rect = MercatorBounds::FullRect(); @@ -631,7 +615,7 @@ void Framework::OnCountryFileDownloaded(storage::TCountryId const & countryId, s bool Framework::OnCountryFileDelete(storage::TCountryId const & countryId, storage::Storage::TLocalFilePtr const localFile) { // Soft reset to signal that mwm file may be out of date in routing caches. - m_routingManager.RoutingSession().Reset(); + m_routingManager.ResetRoutingSession(); if (countryId == m_lastReportedCountry) m_lastReportedCountry = kInvalidCountryId; @@ -1385,7 +1369,7 @@ void Framework::EnterBackground() SaveViewport(); m_trafficManager.OnEnterBackground(); - m_trackingReporter.SetAllowSendingPoints(false); + m_routingManager.SetAllowSendingPoints(false); ms::LatLon const ll = MercatorBounds::ToLatLon(GetViewportCenter()); alohalytics::Stats::Instance().LogEvent("Framework::EnterBackground", {{"zoom", strings::to_string(GetDrawScale())}, @@ -1407,7 +1391,7 @@ void Framework::EnterForeground() CallDrapeFunction(bind(&df::DrapeEngine::SetTimeInBackground, _1, time)); m_trafficManager.OnEnterForeground(); - m_trackingReporter.SetAllowSendingPoints(true); + m_routingManager.SetAllowSendingPoints(true); } bool Framework::GetCurrentPosition(double & lat, double & lon) const @@ -1855,8 +1839,6 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, double const fontsScaleFactor = LoadLargeFontsSize() ? kLargeFontsScaleFactor : 1.0; - auto const & routingSession = m_routingManager.RoutingSession(); - df::DrapeEngine::Params p( params.m_apiVersion, contextFactory, make_ref(&m_stringsBundle), dp::Viewport(0, 0, params.m_surfaceWidth, params.m_surfaceHeight), @@ -1865,8 +1847,8 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, make_pair(params.m_initialMyPositionState, params.m_hasMyPositionState), move(myPositionModeChangedFn), allow3dBuildings, trafficEnabled, params.m_isChoosePositionMode, params.m_isChoosePositionMode, GetSelectedFeatureTriangles(), - routingSession.IsActive() && routingSession.IsFollowing(), isAutozoomEnabled, - simplifiedTrafficColors, move(overlaysShowStatsFn)); + m_routingManager.IsRoutingActive() && m_routingManager.IsRoutingFollowing(), + isAutozoomEnabled, simplifiedTrafficColors, move(overlaysShowStatsFn)); m_drapeEngine = make_unique_dp(move(p)); m_drapeEngine->SetModelViewListener([this](ScreenBase const & screen) @@ -1892,14 +1874,6 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, SetVisibleViewport(m2::RectD(0, 0, params.m_surfaceWidth, params.m_surfaceHeight)); - // In case of the engine reinitialization recover route. - if (routingSession.IsActive()) - { - m_routingManager.InsertRoute(*routingSession.GetRoute()); - if (allow3d && routingSession.IsFollowing()) - m_drapeEngine->EnablePerspective(); - } - if (m_connectToGpsTrack) GpsTracker::Instance().Connect(bind(&Framework::OnUpdateGpsTrackPointsCallback, this, _1, _2)); @@ -1909,7 +1883,7 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, }); m_drapeApi.SetEngine(make_ref(m_drapeEngine)); - m_routingManager.SetDrapeEngine(make_ref(m_drapeEngine)); + m_routingManager.SetDrapeEngine(make_ref(m_drapeEngine), allow3d); m_trafficManager.SetDrapeEngine(make_ref(m_drapeEngine)); m_localAdsManager.SetDrapeEngine(make_ref(m_drapeEngine)); @@ -2055,7 +2029,7 @@ void Framework::SetupMeasurementSystem() auto units = measurement_utils::Units::Metric; UNUSED_VALUE(settings::Get(settings::kMeasurementUnits, units)); - m_routingManager.RoutingSession().SetTurnNotificationsUnits(units); + m_routingManager.SetTurnNotificationsUnits(units); } void Framework::SetWidgetLayout(gui::TWidgetsLayoutInfo && layout) @@ -3273,7 +3247,7 @@ void Framework::OnRouteFollow(routing::RouterType type) } // RoutingManager::Delegate -void Framework::RegisterCountryFiles(std::shared_ptr ptr) const +void Framework::RegisterCountryFilesOnRoute(std::shared_ptr ptr) const { m_storage.ForEachCountryFile( [&ptr](platform::CountryFile const & file) { ptr->RegisterFile(file); }); diff --git a/map/framework.hpp b/map/framework.hpp index 2b6e7cd00a..fb18b5a624 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -183,7 +183,6 @@ protected: df::DrapeApi m_drapeApi; bool m_isRenderingEnabled; - tracking::Reporter m_trackingReporter; // Note. |m_routingManager| should be declared before |m_trafficManager| RoutingManager m_routingManager; @@ -780,7 +779,7 @@ public: protected: /// RoutingManager::Delegate void OnRouteFollow(routing::RouterType type) override; - void RegisterCountryFiles(std::shared_ptr ptr) const override; + void RegisterCountryFilesOnRoute(std::shared_ptr ptr) const override; public: /// @name Editor interface. diff --git a/map/routing_manager.cpp b/map/routing_manager.cpp index ea8dbe0361..3ce9ad5e9b 100644 --- a/map/routing_manager.cpp +++ b/map/routing_manager.cpp @@ -3,6 +3,8 @@ #include "map/chart_generator.hpp" #include "map/mwm_tree.hpp" +#include "private.h" + #include "tracking/reporter.hpp" #include "routing/car_router.hpp" @@ -25,9 +27,12 @@ #include "platform/country_file.hpp" #include "platform/mwm_traits.hpp" #include "platform/platform.hpp" +#include "platform/socket.hpp" #include "3party/Alohalytics/src/alohalytics.h" +#include + namespace { char const kRouterTypeKey[] = "router"; @@ -41,17 +46,20 @@ char const * const kRoutingCalculatingRoute = "Routing_CalculatingRoute"; using namespace routing; RoutingManager::RoutingManager(Callbacks && callbacks, Delegate & delegate) - : m_callbacks(std::move(callbacks)), m_delegate(delegate) + : m_callbacks(std::move(callbacks)) + , m_delegate(delegate) + , m_trackingReporter(platform::CreateSocket(), TRACKING_REALTIME_HOST, TRACKING_REALTIME_PORT, + tracking::Reporter::kPushDelayMs) { - auto const routingStatisticsFn = [](map const & statistics) { + auto const routingStatisticsFn = [](std::map const & statistics) { alohalytics::LogEvent("Routing_CalculatingRoute", statistics); GetPlatform().GetMarketingService().SendMarketingEvent(marketing::kRoutingCalculatingRoute, {}); }; m_routingSession.Init(routingStatisticsFn, m_callbacks.m_visualizer); m_routingSession.SetReadyCallbacks( - [&](Route const & route, IRouter::ResultCode code) { OnBuildRouteReady(route, code); }, - [&](Route const & route, IRouter::ResultCode code) { OnRebuildRouteReady(route, code); }); + [this](Route const & route, IRouter::ResultCode code) { OnBuildRouteReady(route, code); }, + [this](Route const & route, IRouter::ResultCode code) { OnRebuildRouteReady(route, code); }); } void RoutingManager::OnBuildRouteReady(Route const & route, IRouter::ResultCode code) @@ -103,7 +111,7 @@ RouterType RoutingManager::GetBestRouter(m2::PointD const & startPoint, RouterType RoutingManager::GetLastUsedRouter() const { - string routerTypeStr; + std::string routerTypeStr; if (!settings::Get(kRouterTypeKey, routerTypeStr)) return RouterType::Vehicle; @@ -121,10 +129,10 @@ void RoutingManager::SetRouterImpl(routing::RouterType type) { auto const indexGetterFn = m_callbacks.m_featureIndexGetter; ASSERT(indexGetterFn, ()); - unique_ptr router; - unique_ptr fetcher; + std::unique_ptr router; + std::unique_ptr fetcher; - auto const countryFileGetter = [this](m2::PointD const & p) -> string { + auto const countryFileGetter = [this](m2::PointD const & p) -> std::string { // TODO (@gorshenin): fix CountryInfoGetter to return CountryFile // instances instead of plain strings. return m_callbacks.m_countryInfoGetter().GetRegionCountryId(p); @@ -144,7 +152,7 @@ void RoutingManager::SetRouterImpl(routing::RouterType type) { auto & index = m_callbacks.m_featureIndexGetter(); - auto localFileChecker = [this](string const & countryFile) -> bool { + auto localFileChecker = [this](std::string const & countryFile) -> bool { MwmSet::MwmId const mwmId = m_callbacks.m_featureIndexGetter().GetMwmIdByCountryFile( platform::CountryFile(countryFile)); if (!mwmId.IsAlive()) @@ -155,9 +163,9 @@ void RoutingManager::SetRouterImpl(routing::RouterType type) auto numMwmIds = make_shared(); - m_delegate.RegisterCountryFiles(numMwmIds); + m_delegate.RegisterCountryFilesOnRoute(numMwmIds); - auto const getMwmRectByName = [this](string const & countryId) -> m2::RectD { + auto const getMwmRectByName = [this](std::string const & countryId) -> m2::RectD { return m_callbacks.m_countryInfoGetter().GetLimitRectForLeaf(countryId); }; @@ -191,7 +199,7 @@ void RoutingManager::InsertRoute(routing::Route const & route) return; } - vector turns; + std::vector turns; if (m_currentRouterType == RouterType::Vehicle || m_currentRouterType == RouterType::Bicycle || m_currentRouterType == RouterType::Taxi) { @@ -252,7 +260,7 @@ void RoutingManager::SetRouteFinishPoint(m2::PointD const & pt, bool isValid) m_drapeEngine->SetRoutePoint(pt, false /* isStart */, isValid); } -void RoutingManager::GenerateTurnNotifications(vector & turnNotifications) +void RoutingManager::GenerateTurnNotifications(std::vector & turnNotifications) { if (m_currentRouterType == routing::RouterType::Taxi) return; @@ -282,7 +290,7 @@ void RoutingManager::BuildRoute(m2::PointD const & start, m2::PointD const & fin // Send tag to Push Woosh. { - string tag; + std::string tag; switch (m_currentRouterType) { case RouterType::Vehicle: @@ -310,6 +318,12 @@ void RoutingManager::BuildRoute(m2::PointD const & start, m2::PointD const & fin m_routingSession.BuildRoute(start, finish, timeoutSec); } +void RoutingManager::SetUserCurrentPosition(m2::PointD const & position) +{ + if (IsRoutingActive()) + m_routingSession.SetUserCurrentPosition(position); +} + bool RoutingManager::DisableFollowMode() { bool const disabled = m_routingSession.DisableFollowMode(); @@ -355,15 +369,41 @@ void RoutingManager::MatchLocationToRoute(location::GpsInfo & location, m_routingSession.MatchLocationToRoute(location, routeMatchingInfo); } +void RoutingManager::OnLocationUpdate(location::GpsInfo & info) +{ + location::RouteMatchingInfo routeMatchingInfo; + CheckLocationForRouting(info); + + MatchLocationToRoute(info, routeMatchingInfo); + + m_drapeEngine->SetGpsInfo(info, m_routingSession.IsNavigable(), routeMatchingInfo); + if (IsTrackingReporterEnabled()) + m_trackingReporter.AddLocation(info, m_routingSession.MatchTraffic(routeMatchingInfo)); +} + +void RoutingManager::SetDrapeEngine(ref_ptr engine, bool is3dAllowed) +{ + m_drapeEngine = engine; + + // In case of the engine reinitialization recover route. + if (IsRoutingActive()) + { + InsertRoute(*m_routingSession.GetRoute()); + if (is3dAllowed && m_routingSession.IsFollowing()) + m_drapeEngine->EnablePerspective(); + } +} + bool RoutingManager::HasRouteAltitude() const { return m_routingSession.HasRouteAltitude(); } + bool RoutingManager::GenerateRouteAltitudeChart(uint32_t width, uint32_t height, - vector & imageRGBAData, + std::vector & imageRGBAData, int32_t & minRouteAltitude, int32_t & maxRouteAltitude, measurement_utils::Units & altitudeUnits) const { feature::TAltitudes altitudes; - vector segDistance; + std::vector segDistance; if (!m_routingSession.GetRouteAltitudesAndDistancesM(segDistance, altitudes)) return false; diff --git a/map/routing_manager.hpp b/map/routing_manager.hpp index 2a0b7dfd2e..35e43a36fc 100644 --- a/map/routing_manager.hpp +++ b/map/routing_manager.hpp @@ -5,10 +5,15 @@ #include "storage/index.hpp" +#include "tracking/reporter.hpp" + #include "base/thread_checker.hpp" #include #include +#include +#include +#include namespace df { @@ -35,7 +40,7 @@ public: { public: virtual void OnRouteFollow(routing::RouterType type) = 0; - virtual void RegisterCountryFiles(std::shared_ptr ptr) const = 0; + virtual void RegisterCountryFilesOnRoute(std::shared_ptr ptr) const = 0; virtual ~Delegate() = default; }; @@ -76,9 +81,12 @@ public: bool IsRouteNotReady() const { return m_routingSession.IsNotReady(); } bool IsRouteFinished() const { return m_routingSession.IsFinished(); } bool IsOnRoute() const { return m_routingSession.IsOnRoute(); } + bool IsRoutingFollowing() const { return m_routingSession.IsFollowing(); } void BuildRoute(m2::PointD const & finish, uint32_t timeoutSec); void BuildRoute(m2::PointD const & start, m2::PointD const & finish, bool isP2P, uint32_t timeoutSec); + void SetUserCurrentPosition(m2::PointD const & position); + void ResetRoutingSession() { m_routingSession.Reset(); } // FollowRoute has a bug where the router follows the route even if the method hads't been called. // This method was added because we do not want to break the behaviour that is familiar to our // users. @@ -124,7 +132,7 @@ public: /// \brief Sets a locale for TTS. /// \param locale is a string with locale code. For example "en", "ru", "zh-Hant" and so on. /// \note See sound/tts/languages.txt for the full list of available locales. - void SetTurnNotificationsLocale(string const & locale) + void SetTurnNotificationsLocale(std::string const & locale) { m_routingSession.SetTurnNotificationsLocale(locale); } @@ -132,7 +140,7 @@ public: /// In case of error returns an empty string. /// \note The method returns correct locale after SetTurnNotificationsLocale has been called. /// If not, it returns an empty string. - string GetTurnNotificationsLocale() const + std::string GetTurnNotificationsLocale() const { return m_routingSession.GetTurnNotificationsLocale(); } @@ -144,7 +152,7 @@ public: /// For example if C++ part wants the client to pronounce "Make a right turn." this method returns /// an array with one string "Make a right turn.". The next call of the method returns nothing. /// GenerateTurnNotifications shall be called by the client when a new position is available. - void GenerateTurnNotifications(vector & turnNotifications); + void GenerateTurnNotifications(std::vector & turnNotifications); void SetRouteStartPoint(m2::PointD const & pt, bool isValid); void SetRouteFinishPoint(m2::PointD const & pt, bool isValid); @@ -152,16 +160,19 @@ public: void SetRouterImpl(routing::RouterType type); void RemoveRoute(bool deactivateFollowing); - void InsertRoute(routing::Route const & route); void CheckLocationForRouting(location::GpsInfo const & info); void CallRouteBuilded(routing::IRouter::ResultCode code, storage::TCountriesVec const & absentCountries); - void MatchLocationToRoute(location::GpsInfo & info, - location::RouteMatchingInfo & routeMatchingInfo) const; void OnBuildRouteReady(routing::Route const & route, routing::IRouter::ResultCode code); void OnRebuildRouteReady(routing::Route const & route, routing::IRouter::ResultCode code); + void OnLocationUpdate(location::GpsInfo & info); + void SetAllowSendingPoints(bool isAllowed) + { + m_trackingReporter.SetAllowSendingPoints(isAllowed); + } - void SetDrapeEngine(ref_ptr engine) { m_drapeEngine = engine; }; + void SetTurnNotificationsUnits(measurement_utils::Units const units) { m_routingSession.SetTurnNotificationsUnits(units); } + void SetDrapeEngine(ref_ptr engine, bool is3dAllowed); /// \returns true if altitude information along |m_route| is available and /// false otherwise. bool HasRouteAltitude() const; @@ -178,11 +189,15 @@ public: /// |imageRGBAData| is not zero. /// \note If HasRouteAltitude() method returns true, GenerateRouteAltitudeChart(...) /// could return false if route was deleted or rebuilt between the calls. - bool GenerateRouteAltitudeChart(uint32_t width, uint32_t height, vector & imageRGBAData, + bool GenerateRouteAltitudeChart(uint32_t width, uint32_t height, std::vector & imageRGBAData, int32_t & minRouteAltitude, int32_t & maxRouteAltitude, measurement_utils::Units & altitudeUnits) const; +private: + void InsertRoute(routing::Route const & route); bool IsTrackingReporterEnabled() const; + void MatchLocationToRoute(location::GpsInfo & info, + location::RouteMatchingInfo & routeMatchingInfo) const; private: RouteBuildingCallback m_routingCallback = nullptr; @@ -192,4 +207,5 @@ private: routing::RoutingSession m_routingSession; DECLARE_THREAD_CHECKER(m_threadChecker); Delegate & m_delegate; + tracking::Reporter m_trackingReporter; };