From 85f0ffaff1d39088cbd105c102df9cb4e3bad62c Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Fri, 14 Jul 2017 09:49:28 +0300 Subject: [PATCH] Added new local ads rendering --- drape/glstate.hpp | 1 + drape_frontend/CMakeLists.txt | 2 +- drape_frontend/apply_feature_functors.cpp | 24 +-- drape_frontend/apply_feature_functors.hpp | 4 +- drape_frontend/backend_renderer.cpp | 40 ++-- drape_frontend/custom_features_context.hpp | 27 +++ drape_frontend/custom_symbol.hpp | 35 ---- drape_frontend/drape_engine.cpp | 19 +- drape_frontend/drape_engine.hpp | 9 +- drape_frontend/drape_frontend.pro | 2 +- drape_frontend/engine_context.cpp | 4 +- drape_frontend/engine_context.hpp | 8 +- drape_frontend/frontend_renderer.cpp | 20 +- drape_frontend/frontend_renderer.hpp | 1 + drape_frontend/message.hpp | 6 +- drape_frontend/message_subclasses.hpp | 33 ++- drape_frontend/read_manager.cpp | 56 +++-- drape_frontend/read_manager.hpp | 10 +- drape_frontend/render_group.cpp | 5 +- drape_frontend/rule_drawer.cpp | 11 +- drape_frontend/rule_drawer.hpp | 4 +- drape_frontend/shape_view_params.hpp | 2 +- drape_frontend/tile_info.hpp | 2 +- drape_frontend/user_mark_shapes.cpp | 14 +- drape_frontend/user_mark_shapes.hpp | 5 +- drape_frontend/user_marks_provider.hpp | 9 +- map/CMakeLists.txt | 2 + map/bookmark_manager.cpp | 4 +- map/framework.cpp | 21 +- map/framework.hpp | 3 + map/local_ads_manager.cpp | 229 ++++++++++++++------- map/local_ads_manager.hpp | 32 +-- map/local_ads_mark.cpp | 71 +++++++ map/local_ads_mark.hpp | 52 +++++ map/map.pro | 2 + map/routing_mark.hpp | 4 +- map/user_mark.cpp | 1 + map/user_mark.hpp | 9 +- map/user_mark_container.hpp | 3 +- xcode/map/map.xcodeproj/project.pbxproj | 8 + 40 files changed, 525 insertions(+), 269 deletions(-) create mode 100644 drape_frontend/custom_features_context.hpp delete mode 100644 drape_frontend/custom_symbol.hpp create mode 100644 map/local_ads_mark.cpp create mode 100644 map/local_ads_mark.hpp diff --git a/drape/glstate.hpp b/drape/glstate.hpp index 2e185639f2..a5773550b8 100644 --- a/drape/glstate.hpp +++ b/drape/glstate.hpp @@ -40,6 +40,7 @@ public: GeometryLayer, UserLineLayer, OverlayLayer, + LocalAdsMarkLayer, UserMarkLayer, NavigationLayer, RoutingMarkLayer, diff --git a/drape_frontend/CMakeLists.txt b/drape_frontend/CMakeLists.txt index e57debecff..3fd99afa8f 100644 --- a/drape_frontend/CMakeLists.txt +++ b/drape_frontend/CMakeLists.txt @@ -72,7 +72,7 @@ set( color_constants.hpp colored_symbol_shape.cpp colored_symbol_shape.hpp - custom_symbol.hpp + custom_features_context.hpp drape_api.cpp drape_api.hpp drape_api_builder.cpp diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index 24f76100e6..3139c311ba 100644 --- a/drape_frontend/apply_feature_functors.cpp +++ b/drape_frontend/apply_feature_functors.cpp @@ -63,6 +63,7 @@ int const kLineSimplifyLevelEnd = 12; uint32_t const kPathTextBaseTextIndex = 128; uint32_t const kShieldBaseTextIndex = 0; +int const kShieldMinVisibleZoomLevel = 10; #ifdef CALC_FILTERED_POINTS class LinesStat @@ -552,8 +553,7 @@ void ApplyPointFeature::ProcessPointRule(Stylist::TRuleWrapper const & rule) } } -void ApplyPointFeature::Finish(ref_ptr texMng, - CustomSymbolsContextPtr const & customSymbolsContext) +void ApplyPointFeature::Finish(ref_ptr texMng) { m2::PointF symbolSize(0.0f, 0.0f); @@ -580,24 +580,12 @@ void ApplyPointFeature::Finish(ref_ptr texMng, params.m_depthLayer = m_depthLayer; params.m_minVisibleScale = m_minVisibleScale; params.m_rank = m_rank; - params.m_symbolName = m_symbolRule->name(); - bool prioritized = false; - if (customSymbolsContext) - { - auto customSymbolIt = customSymbolsContext->m_symbols.find(m_id); - if (customSymbolIt != customSymbolsContext->m_symbols.end()) - { - params.m_symbolName = customSymbolIt->second.m_symbolName; - prioritized = customSymbolIt->second.m_prioritized; - } - } - double const mainScale = df::VisualParams::Instance().GetVisualScale(); params.m_extendingSize = static_cast(mainScale * m_symbolRule->min_distance()); params.m_posZ = m_posZ; params.m_hasArea = m_hasArea; - params.m_prioritized = prioritized || m_createdByEditor; + params.m_prioritized = m_createdByEditor; params.m_obsoleteInEditor = m_obsoleteInEditor; params.m_specialDisplacement = specialDisplacementMode ? SpecialDisplacement::SpecialMode : SpecialDisplacement::None; @@ -991,7 +979,7 @@ void ApplyLineFeatureAdditional::GetRoadShieldsViewParams(ref_ptr texMng, - CustomSymbolsContextPtr const & customSymbolsContext); + void Finish(ref_ptr texMng); protected: float const m_posZ; diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index cea24828bf..d885bbe8e9 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -442,31 +442,35 @@ void BackendRenderer::AcceptMessage(ref_ptr message) break; } - case Message::AddCustomSymbols: + case Message::SetCustomFeatures: { - ref_ptr msg = message; - CustomSymbols customSymbols = msg->AcceptSymbols(); - std::vector features; - for (auto const & symbol : customSymbols) - features.push_back(symbol.first); - m_readManager->UpdateCustomSymbols(std::move(customSymbols)); - m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(std::move(features)), - MessagePriority::Normal); + ref_ptr msg = message; + if (m_readManager->SetCustomFeatures(msg->AcceptFeatures())) + { + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp( + m_readManager->GetCustomFeaturesArray()), + MessagePriority::Normal); + } break; } - case Message::RemoveCustomSymbols: + case Message::RemoveCustomFeatures: { - ref_ptr msg = message; - std::vector leftoverIds; + ref_ptr msg = message; + bool changed = false; if (msg->NeedRemoveAll()) - m_readManager->RemoveAllCustomSymbols(); + changed = m_readManager->RemoveAllCustomFeatures(); else - m_readManager->RemoveCustomSymbols(msg->GetMwmId(), leftoverIds); - m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(std::move(leftoverIds)), - MessagePriority::Normal); + changed = m_readManager->RemoveCustomFeatures(msg->GetMwmId()); + + if (changed) + { + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp( + m_readManager->GetCustomFeaturesArray()), + MessagePriority::Normal); + } break; } diff --git a/drape_frontend/custom_features_context.hpp b/drape_frontend/custom_features_context.hpp new file mode 100644 index 0000000000..3d250e912f --- /dev/null +++ b/drape_frontend/custom_features_context.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include "indexer/feature_decl.hpp" + +#include +#include +#include + +namespace df +{ +struct CustomFeaturesContext +{ + std::set const m_features; + + explicit CustomFeaturesContext(std::set && features) + : m_features(std::move(features)) + {} + + bool Contains(FeatureID const & id) const + { + return m_features.find(id) != m_features.cend(); + } +}; + +using CustomFeaturesContextPtr = std::shared_ptr; +using CustomFeaturesContextWeakPtr = std::weak_ptr; +} // namespace df diff --git a/drape_frontend/custom_symbol.hpp b/drape_frontend/custom_symbol.hpp deleted file mode 100644 index 9344eba715..0000000000 --- a/drape_frontend/custom_symbol.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "indexer/feature_decl.hpp" - -#include -#include -#include - -namespace df -{ -struct CustomSymbol -{ - std::string m_symbolName; - bool m_prioritized = false; - - CustomSymbol() = default; - CustomSymbol(std::string const & name, bool prioritized) - : m_symbolName(name), m_prioritized(prioritized) - {} -}; - -using CustomSymbols = std::map; - -struct CustomSymbolsContext -{ - CustomSymbols m_symbols; - - explicit CustomSymbolsContext(CustomSymbols && symbols) - : m_symbols(std::move(symbols)) - {} -}; - -using CustomSymbolsContextPtr = std::shared_ptr; -using CustomSymbolsContextWeakPtr = std::weak_ptr; -} // namespace df diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index aafea5c9e0..c94652ad8b 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -230,9 +230,10 @@ void DrapeEngine::UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provi renderInfo->m_runCreationAnim = mark->HasCreationAnimation(); renderInfo->m_symbolName = mark->GetSymbolName(); renderInfo->m_titleDecl = mark->GetTitleDecl(); - renderInfo->m_symbolHasPriority = mark->SymbolHasPriority(); - renderInfo->m_titleHasPriority = mark->TitleHasPriority(); - renderInfo->m_priority = mark->GetProirity(); + renderInfo->m_hasSymbolPriority = mark->HasSymbolPriority(); + renderInfo->m_hasTitlePriority = mark->HasTitlePriority(); + renderInfo->m_priority = mark->GetPriority(); + renderInfo->m_featureId = mark->GetFeatureID(); marksRenderCollection->emplace(mark->GetId(), std::move(renderInfo)); mark->AcceptChanges(); } @@ -674,24 +675,24 @@ void DrapeEngine::RunScenario(ScenarioManager::ScenarioData && scenarioData, manager->RunScenario(std::move(scenarioData), onStartFn, onFinishFn); } -void DrapeEngine::AddCustomSymbols(CustomSymbols && symbols) +void DrapeEngine::SetCustomFeatures(std::set && ids) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(std::move(symbols)), + make_unique_dp(std::move(ids)), MessagePriority::Normal); } -void DrapeEngine::RemoveCustomSymbols(MwmSet::MwmId const & mwmId) +void DrapeEngine::RemoveCustomFeatures(MwmSet::MwmId const & mwmId) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(mwmId), + make_unique_dp(mwmId), MessagePriority::Normal); } -void DrapeEngine::RemoveAllCustomSymbols() +void DrapeEngine::RemoveAllCustomFeatures() { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(), + make_unique_dp(), MessagePriority::Normal); } diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index c04dea981c..a02d201b6e 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -2,7 +2,6 @@ #include "drape_frontend/backend_renderer.hpp" #include "drape_frontend/color_constants.hpp" -#include "drape_frontend/custom_symbol.hpp" #include "drape_frontend/drape_hints.hpp" #include "drape_frontend/frontend_renderer.hpp" #include "drape_frontend/route_shape.hpp" @@ -202,9 +201,11 @@ public: ScenarioManager::ScenarioCallback const & onStartFn, ScenarioManager::ScenarioCallback const & onFinishFn); - void AddCustomSymbols(CustomSymbols && symbols); - void RemoveCustomSymbols(MwmSet::MwmId const & mwmId); - void RemoveAllCustomSymbols(); + // Custom features are features which we do not render usual way. + // All these features will be skipped in process of geometry generation. + void SetCustomFeatures(std::set && ids); + void RemoveCustomFeatures(MwmSet::MwmId const & mwmId); + void RemoveAllCustomFeatures(); void SetPosteffectEnabled(PostprocessRenderer::Effect effect, bool enabled); diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro index 9323e38ffa..92fd09af9f 100755 --- a/drape_frontend/drape_frontend.pro +++ b/drape_frontend/drape_frontend.pro @@ -155,7 +155,7 @@ HEADERS += \ circles_pack_shape.hpp \ color_constants.hpp \ colored_symbol_shape.hpp \ - custom_symbol.hpp \ + custom_features_context.hpp \ drape_api.hpp \ drape_api_builder.hpp \ drape_api_renderer.hpp \ diff --git a/drape_frontend/engine_context.cpp b/drape_frontend/engine_context.cpp index 2c2419e1b2..72b3bc21b0 100644 --- a/drape_frontend/engine_context.cpp +++ b/drape_frontend/engine_context.cpp @@ -12,7 +12,7 @@ EngineContext::EngineContext(TileKey tileKey, ref_ptr commutator, ref_ptr texMng, ref_ptr metalineMng, - CustomSymbolsContextWeakPtr customSymbolsContext, + CustomFeaturesContextWeakPtr customFeaturesContext, bool is3dBuildingsEnabled, bool isTrafficEnabled, int displacementMode) @@ -20,7 +20,7 @@ EngineContext::EngineContext(TileKey tileKey, , m_commutator(commutator) , m_texMng(texMng) , m_metalineMng(metalineMng) - , m_customSymbolsContext(customSymbolsContext) + , m_customFeaturesContext(customFeaturesContext) , m_3dBuildingsEnabled(is3dBuildingsEnabled) , m_trafficEnabled(isTrafficEnabled) , m_displacementMode(displacementMode) diff --git a/drape_frontend/engine_context.hpp b/drape_frontend/engine_context.hpp index 948b78d6a1..71a3af3ca9 100644 --- a/drape_frontend/engine_context.hpp +++ b/drape_frontend/engine_context.hpp @@ -1,6 +1,6 @@ #pragma once -#include "drape_frontend/custom_symbol.hpp" +#include "drape_frontend/custom_features_context.hpp" #include "drape_frontend/map_shape.hpp" #include "drape_frontend/tile_utils.hpp" #include "drape_frontend/threads_commutator.hpp" @@ -26,7 +26,7 @@ public: ref_ptr commutator, ref_ptr texMng, ref_ptr metalineMng, - CustomSymbolsContextWeakPtr customSymbolsContext, + CustomFeaturesContextWeakPtr customFeaturesContext, bool is3dBuildingsEnabled, bool isTrafficEnabled, int displacementMode); @@ -35,7 +35,7 @@ public: bool Is3dBuildingsEnabled() const { return m_3dBuildingsEnabled; } bool IsTrafficEnabled() const { return m_trafficEnabled; } int GetDisplacementMode() const { return m_displacementMode; } - CustomSymbolsContextWeakPtr GetCustomSymbolsContext() const { return m_customSymbolsContext; } + CustomFeaturesContextWeakPtr GetCustomFeaturesContext() const { return m_customFeaturesContext; } ref_ptr GetTextureManager() const; ref_ptr GetMetalineManager() const; @@ -52,7 +52,7 @@ private: ref_ptr m_commutator; ref_ptr m_texMng; ref_ptr m_metalineMng; - CustomSymbolsContextWeakPtr m_customSymbolsContext; + CustomFeaturesContextWeakPtr m_customFeaturesContext; bool m_3dBuildingsEnabled; bool m_trafficEnabled; int m_displacementMode; diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 7cfd064c73..5011095674 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -732,14 +732,10 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) } case Message::InvalidateUserMarks: { - auto removePredicate = [](drape_ptr const & group) + RemoveRenderGroupsLater([](drape_ptr const & group) { - RenderLayer::RenderLayerID id = RenderLayer::GetLayerID(group->GetState()); - return id == RenderLayer::UserLineID || - id == RenderLayer::UserMarkID || - id == RenderLayer::RoutingMarkID; - }; - RemoveRenderGroupsLater(removePredicate); + return group->IsUserMark(); + }); m_forceUpdateUserMarks = true; break; } @@ -776,10 +772,10 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) break; } - case Message::UpdateCustomSymbols: + case Message::UpdateCustomFeatures: { - ref_ptr msg = message; - m_overlaysTracker->SetTrackedOverlaysFeatures(msg->AcceptSymbolsFeatures()); + ref_ptr msg = message; + m_overlaysTracker->SetTrackedOverlaysFeatures(msg->AcceptFeatures()); m_forceUpdateScene = true; break; } @@ -1164,6 +1160,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) { StencilWriterGuard guard(make_ref(m_postprocessRenderer)); RenderOverlayLayer(modelView); + RenderUserMarksLayer(modelView, RenderLayer::LocalAdsMarkID); } m_gpsTrackRenderer->RenderTrack(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), @@ -1312,6 +1309,7 @@ void FrontendRenderer::RenderUserLinesLayer(ScreenBase const & modelView) void FrontendRenderer::BuildOverlayTree(ScreenBase const & modelView) { static std::vector layers = {RenderLayer::OverlayID, + RenderLayer::LocalAdsMarkID, RenderLayer::NavigationID, RenderLayer::RoutingMarkID}; BeginUpdateOverlayTree(modelView); @@ -2059,6 +2057,8 @@ FrontendRenderer::RenderLayer::RenderLayerID FrontendRenderer::RenderLayer::GetL case dp::GLState::UserLineLayer: return UserLineID; case dp::GLState::RoutingMarkLayer: return RoutingMarkID; case dp::GLState::NavigationLayer: return NavigationID; + case dp::GLState::LocalAdsMarkLayer: return LocalAdsMarkID; + default: break; } if (state.GetProgram3dIndex() == gpu::AREA_3D_PROGRAM || diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index fe90dbbc9c..ea86495283 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -152,6 +152,7 @@ private: Geometry2dID, UserLineID, OverlayID, + LocalAdsMarkID, Geometry3dID, UserMarkID, NavigationID, diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index 51c1ac0149..911739e7bd 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -74,9 +74,9 @@ public: DrapeApiAddLines, DrapeApiRemove, DrapeApiFlush, - AddCustomSymbols, - RemoveCustomSymbols, - UpdateCustomSymbols, + SetCustomFeatures, + RemoveCustomFeatures, + UpdateCustomFeatures, SetPostprocessStaticTextures, SetPosteffectEnabled, RunFirstLaunchAnimation, diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 950afa949d..7acdf7972f 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -2,7 +2,6 @@ #include "drape_frontend/circles_pack_shape.hpp" #include "drape_frontend/color_constants.hpp" -#include "drape_frontend/custom_symbol.hpp" #include "drape_frontend/drape_api.hpp" #include "drape_frontend/drape_api_builder.hpp" #include "drape_frontend/gps_track_point.hpp" @@ -1110,30 +1109,30 @@ private: TProperties m_properties; }; -class AddCustomSymbolsMessage : public Message +class SetCustomFeaturesMessage : public Message { public: - explicit AddCustomSymbolsMessage(CustomSymbols && symbols) - : m_symbols(std::move(symbols)) + explicit SetCustomFeaturesMessage(std::set && ids) + : m_features(std::move(ids)) {} - Type GetType() const override { return Message::AddCustomSymbols; } + Type GetType() const override { return Message::SetCustomFeatures; } - CustomSymbols && AcceptSymbols() { return std::move(m_symbols); } + std::set && AcceptFeatures() { return std::move(m_features); } private: - CustomSymbols m_symbols; + std::set m_features; }; -class RemoveCustomSymbolsMessage : public Message +class RemoveCustomFeaturesMessage : public Message { public: - RemoveCustomSymbolsMessage() = default; - explicit RemoveCustomSymbolsMessage(MwmSet::MwmId const & mwmId) + RemoveCustomFeaturesMessage() = default; + explicit RemoveCustomFeaturesMessage(MwmSet::MwmId const & mwmId) : m_mwmId(mwmId), m_removeAll(false) {} - Type GetType() const override { return Message::RemoveCustomSymbols; } + Type GetType() const override { return Message::RemoveCustomFeatures; } bool NeedRemoveAll() const { return m_removeAll; } MwmSet::MwmId const & GetMwmId() const { return m_mwmId; } @@ -1142,19 +1141,19 @@ private: bool m_removeAll = true; }; -class UpdateCustomSymbolsMessage : public Message +class UpdateCustomFeaturesMessage : public Message { public: - explicit UpdateCustomSymbolsMessage(std::vector && symbolsFeatures) - : m_symbolsFeatures(std::move(symbolsFeatures)) + explicit UpdateCustomFeaturesMessage(std::vector && features) + : m_features(std::move(features)) {} - Type GetType() const override { return Message::UpdateCustomSymbols; } + Type GetType() const override { return Message::UpdateCustomFeatures; } - std::vector && AcceptSymbolsFeatures() { return std::move(m_symbolsFeatures); } + std::vector && AcceptFeatures() { return std::move(m_features); } private: - std::vector m_symbolsFeatures; + std::vector m_features; }; class SetPostprocessStaticTexturesMessage : public Message diff --git a/drape_frontend/read_manager.cpp b/drape_frontend/read_manager.cpp index 9ed42af240..3b374da994 100755 --- a/drape_frontend/read_manager.cpp +++ b/drape_frontend/read_manager.cpp @@ -221,7 +221,7 @@ void ReadManager::PushTaskBackForTileKey(TileKey const & tileKey, ASSERT(m_pool != nullptr, ()); auto context = make_unique_dp(TileKey(tileKey, m_generationCounter, m_userMarksGenerationCounter), m_commutator, texMng, metalineMng, - m_customSymbolsContext, + m_customFeaturesContext, m_have3dBuildings && m_allow3dBuildings, m_trafficEnabled, m_displacementMode); std::shared_ptr tileInfo = std::make_shared(std::move(context)); @@ -315,35 +315,49 @@ void ReadManager::SetDisplacementMode(int displacementMode) } } -void ReadManager::UpdateCustomSymbols(CustomSymbols const & symbols) +bool ReadManager::SetCustomFeatures(std::set && ids) { - CustomSymbols currentSymbols = m_customSymbolsContext ? m_customSymbolsContext->m_symbols : - CustomSymbols(); - for (auto const & s : symbols) - currentSymbols[s.first] = s.second; - m_customSymbolsContext = std::make_shared(std::move(currentSymbols)); + size_t const sz = m_customFeaturesContext ? m_customFeaturesContext->m_features.size() : 0; + m_customFeaturesContext = std::make_shared(std::move(ids)); + + return sz != m_customFeaturesContext->m_features.size(); } -void ReadManager::RemoveCustomSymbols(MwmSet::MwmId const & mwmId, std::vector & leftoverIds) +std::vector ReadManager::GetCustomFeaturesArray() const { - if (!m_customSymbolsContext) - return; + if (!m_customFeaturesContext) + return {}; + std::vector features; + features.reserve(m_customFeaturesContext->m_features.size()); + for (auto const & s : m_customFeaturesContext->m_features) + features.push_back(s); + return features; +} - CustomSymbols currentSymbols; - leftoverIds.reserve(m_customSymbolsContext->m_symbols.size()); - for (auto const & s : m_customSymbolsContext->m_symbols) +bool ReadManager::RemoveCustomFeatures(MwmSet::MwmId const & mwmId) +{ + if (!m_customFeaturesContext) + return false; + + std::set features; + for (auto const & s : m_customFeaturesContext->m_features) { - if (s.first.m_mwmId != mwmId) - { - currentSymbols.insert(std::make_pair(s.first, s.second)); - leftoverIds.push_back(s.first); - } + if (s.m_mwmId != mwmId) + features.insert(s); } - m_customSymbolsContext = std::make_shared(std::move(currentSymbols)); + if (features.size() == m_customFeaturesContext->m_features.size()) + return false; + + m_customFeaturesContext = std::make_shared(std::move(features)); + return true; } -void ReadManager::RemoveAllCustomSymbols() +bool ReadManager::RemoveAllCustomFeatures() { - m_customSymbolsContext = std::make_shared(CustomSymbols()); + if (!m_customFeaturesContext || m_customFeaturesContext->m_features.empty()) + return false; + + m_customFeaturesContext = std::make_shared(std::set()); + return true; } } // namespace df diff --git a/drape_frontend/read_manager.hpp b/drape_frontend/read_manager.hpp index 759b2a0ece..5cf839a923 100755 --- a/drape_frontend/read_manager.hpp +++ b/drape_frontend/read_manager.hpp @@ -1,6 +1,5 @@ #pragma once -#include "drape_frontend/custom_symbol.hpp" #include "drape_frontend/engine_context.hpp" #include "drape_frontend/read_mwm_task.hpp" #include "drape_frontend/tile_info.hpp" @@ -54,9 +53,10 @@ public: void SetDisplacementMode(int displacementMode); - void UpdateCustomSymbols(CustomSymbols const & symbols); - void RemoveCustomSymbols(MwmSet::MwmId const & mwmId, std::vector & leftoverIds); - void RemoveAllCustomSymbols(); + bool SetCustomFeatures(std::set && ids); + std::vector GetCustomFeaturesArray() const; + bool RemoveCustomFeatures(MwmSet::MwmId const & mwmId); + bool RemoveAllCustomFeatures(); bool IsModeChanged() const { return m_modeChanged; } @@ -99,7 +99,7 @@ private: using TTileInfoCollection = buffer_vector, 8>; TTilesCollection m_activeTiles; - CustomSymbolsContextPtr m_customSymbolsContext; + CustomFeaturesContextPtr m_customFeaturesContext; void CancelTileInfo(std::shared_ptr const & tileToCancel); void ClearTileInfo(std::shared_ptr const & tileToClear); diff --git a/drape_frontend/render_group.cpp b/drape_frontend/render_group.cpp index ed89d6ee55..1e0b32b683 100755 --- a/drape_frontend/render_group.cpp +++ b/drape_frontend/render_group.cpp @@ -161,8 +161,9 @@ bool RenderGroup::IsOverlay() const bool RenderGroup::IsUserMark() const { return m_state.GetDepthLayer() == dp::GLState::UserLineLayer || - m_state.GetDepthLayer() == dp::GLState::UserMarkLayer || - m_state.GetDepthLayer() == dp::GLState::RoutingMarkLayer; + m_state.GetDepthLayer() == dp::GLState::UserMarkLayer || + m_state.GetDepthLayer() == dp::GLState::RoutingMarkLayer || + m_state.GetDepthLayer() == dp::GLState::LocalAdsMarkLayer; } bool RenderGroup::UpdateCanBeDeletedStatus(bool canBeDeleted, int currentZoom, ref_ptr tree) diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp index 5555678459..ff22dec0c1 100644 --- a/drape_frontend/rule_drawer.cpp +++ b/drape_frontend/rule_drawer.cpp @@ -173,7 +173,7 @@ RuleDrawer::RuleDrawer(TDrawerCallback const & drawerFn, , m_checkCancelled(checkCancelled) , m_isLoadedFn(isLoadedFn) , m_context(engineContext) - , m_customSymbolsContext(engineContext->GetCustomSymbolsContext().lock()) + , m_customFeaturesContext(engineContext->GetCustomFeaturesContext().lock()) , m_wasCancelled(false) { ASSERT(m_callback != nullptr, ()); @@ -322,7 +322,9 @@ void RuleDrawer::ProcessAreaStyle(FeatureType const & f, Stylist const & s, return; s.ForEachRule(std::bind(&ApplyAreaFeature::ProcessAreaRule, &apply, _1)); - apply.Finish(m_context->GetTextureManager(), m_customSymbolsContext); + + if (!m_customFeaturesContext || !m_customFeaturesContext->Contains(f.GetID())) + apply.Finish(m_context->GetTextureManager()); } void RuleDrawer::ProcessLineStyle(FeatureType const & f, Stylist const & s, @@ -417,6 +419,9 @@ void RuleDrawer::ProcessLineStyle(FeatureType const & f, Stylist const & s, void RuleDrawer::ProcessPointStyle(FeatureType const & f, Stylist const & s, TInsertShapeFn const & insertShape, int & minVisibleScale) { + if (m_customFeaturesContext && m_customFeaturesContext->Contains(f.GetID())) + return; + int const zoomLevel = m_context->GetTileKey().m_zoomLevel; bool const isSpeedCamera = ftypes::IsSpeedCamChecker::Instance()(f); if (isSpeedCamera && !GetStyleReader().IsCarNavigationStyle()) @@ -437,7 +442,7 @@ void RuleDrawer::ProcessPointStyle(FeatureType const & f, Stylist const & s, TIn return; s.ForEachRule(bind(&ApplyPointFeature::ProcessPointRule, &apply, _1)); - apply.Finish(m_context->GetTextureManager(), m_customSymbolsContext); + apply.Finish(m_context->GetTextureManager()); } void RuleDrawer::operator()(FeatureType const & f) diff --git a/drape_frontend/rule_drawer.hpp b/drape_frontend/rule_drawer.hpp index 674540b6bf..7fed3f8284 100644 --- a/drape_frontend/rule_drawer.hpp +++ b/drape_frontend/rule_drawer.hpp @@ -1,6 +1,6 @@ #pragma once -#include "drape_frontend/custom_symbol.hpp" +#include "drape_frontend/custom_features_context.hpp" #include "drape_frontend/map_shape.hpp" #include "drape_frontend/metaline_manager.hpp" #include "drape_frontend/tile_key.hpp" @@ -63,7 +63,7 @@ private: TIsCountryLoadedByNameFn m_isLoadedFn; ref_ptr m_context; - CustomSymbolsContextPtr m_customSymbolsContext; + CustomFeaturesContextPtr m_customFeaturesContext; std::unordered_set m_usedMetalines; m2::RectD m_globalRect; diff --git a/drape_frontend/shape_view_params.hpp b/drape_frontend/shape_view_params.hpp index 33aa3df74f..25e6ae09b5 100644 --- a/drape_frontend/shape_view_params.hpp +++ b/drape_frontend/shape_view_params.hpp @@ -45,7 +45,7 @@ struct PoiSymbolViewParams : CommonOverlayViewParams FeatureID m_id; std::string m_symbolName; - uint32_t m_extendingSize; + uint32_t m_extendingSize = 0; float m_posZ = 0.0f; bool m_hasArea = false; bool m_prioritized = false; diff --git a/drape_frontend/tile_info.hpp b/drape_frontend/tile_info.hpp index 2cab45c011..43f245cbc8 100644 --- a/drape_frontend/tile_info.hpp +++ b/drape_frontend/tile_info.hpp @@ -1,6 +1,6 @@ #pragma once -#include "drape_frontend/custom_symbol.hpp" +#include "drape_frontend/custom_features_context.hpp" #include "drape_frontend/engine_context.hpp" #include "drape_frontend/tile_key.hpp" diff --git a/drape_frontend/user_mark_shapes.cpp b/drape_frontend/user_mark_shapes.cpp index 002677f2af..eddb131328 100644 --- a/drape_frontend/user_mark_shapes.cpp +++ b/drape_frontend/user_mark_shapes.cpp @@ -106,14 +106,16 @@ void CacheUserMarks(TileKey const & tileKey, ref_ptr texture m2::PointD const tileCenter = tileKey.GetGlobalRect().Center(); depthLayer = renderInfo.m_depthLayer; - if (renderInfo.m_symbolHasPriority) + if (renderInfo.m_hasSymbolPriority) { - PoiSymbolViewParams params((FeatureID())); + PoiSymbolViewParams params(renderInfo.m_featureId); + params.m_tileCenter = tileCenter; params.m_depth = renderInfo.m_depth; params.m_depthLayer = renderInfo.m_depthLayer; params.m_minVisibleScale = renderInfo.m_minZoom; params.m_specialDisplacement = SpecialDisplacement::UserMark; params.m_specialPriority = renderInfo.m_priority; + params.m_symbolName = renderInfo.m_symbolName; PoiSymbolShape(renderInfo.m_pivot, params, tileKey, 0 /* textIndex */).Draw(&batcher, textures); } @@ -147,12 +149,13 @@ void CacheUserMarks(TileKey const & tileKey, ref_ptr texture if (renderInfo.m_titleDecl != nullptr && !renderInfo.m_titleDecl->m_primaryText.empty()) { TextViewParams params; + params.m_featureID = renderInfo.m_featureId; params.m_tileCenter = tileCenter; params.m_titleDecl = *renderInfo.m_titleDecl; params.m_depth = renderInfo.m_depth; params.m_depthLayer = renderInfo.m_depthLayer; params.m_minVisibleScale = renderInfo.m_minZoom; - if (renderInfo.m_titleHasPriority) + if (renderInfo.m_hasTitlePriority) { params.m_specialDisplacement = SpecialDisplacement::UserMark; params.m_specialPriority = renderInfo.m_priority; @@ -162,9 +165,8 @@ void CacheUserMarks(TileKey const & tileKey, ref_ptr texture textures->GetSymbolRegion(renderInfo.m_symbolName, region); m2::PointF const symbolSize = region.GetPixelSize(); - TextShape(renderInfo.m_pivot, params, tileKey, false /* hasPOI */, - symbolSize, renderInfo.m_anchor, - 0 /* textIndex */).Draw(&batcher, textures); + TextShape(renderInfo.m_pivot, params, tileKey, renderInfo.m_hasSymbolPriority /* hasPOI */, + symbolSize, renderInfo.m_anchor, 0 /* textIndex */).Draw(&batcher, textures); } } diff --git a/drape_frontend/user_mark_shapes.hpp b/drape_frontend/user_mark_shapes.hpp index 8001770111..f1721a88a9 100644 --- a/drape_frontend/user_mark_shapes.hpp +++ b/drape_frontend/user_mark_shapes.hpp @@ -20,13 +20,14 @@ struct UserMarkRenderParams std::string m_symbolName; dp::Anchor m_anchor = dp::Center; drape_ptr m_titleDecl; - bool m_symbolHasPriority = false; - bool m_titleHasPriority = false; + bool m_hasSymbolPriority = false; + bool m_hasTitlePriority = false; uint16_t m_priority = 0; float m_depth = 0.0; dp::GLState::DepthLayer m_depthLayer = dp::GLState::UserMarkLayer; bool m_runCreationAnim = false; bool m_isVisible = true; + FeatureID m_featureId; }; struct LineLayer diff --git a/drape_frontend/user_marks_provider.hpp b/drape_frontend/user_marks_provider.hpp index f5f51a412a..6f4105f10e 100644 --- a/drape_frontend/user_marks_provider.hpp +++ b/drape_frontend/user_marks_provider.hpp @@ -4,6 +4,8 @@ #include "drape/glstate.hpp" #include "drape/pointers.hpp" +#include "indexer/feature_decl.hpp" + #include "geometry/polyline2d.hpp" #include "base/mutex.hpp" @@ -34,10 +36,11 @@ public: virtual bool HasCreationAnimation() const = 0; virtual bool IsVisible() const = 0; virtual drape_ptr GetTitleDecl() const = 0; - virtual uint16_t GetProirity() const = 0; - virtual bool SymbolHasPriority() const = 0; - virtual bool TitleHasPriority() const = 0; + virtual uint16_t GetPriority() const = 0; + virtual bool HasSymbolPriority() const = 0; + virtual bool HasTitlePriority() const = 0; virtual int GetMinZoom() const = 0; + virtual FeatureID GetFeatureID() const = 0; private: uint32_t m_id; diff --git a/map/CMakeLists.txt b/map/CMakeLists.txt index 131d8c13b3..1325aebf6f 100644 --- a/map/CMakeLists.txt +++ b/map/CMakeLists.txt @@ -47,6 +47,8 @@ set( gps_tracker.hpp local_ads_manager.cpp local_ads_manager.hpp + local_ads_mark.cpp + local_ads_mark.hpp local_ads_supported_types.cpp mwm_tree.cpp mwm_tree.hpp diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index a79403ce40..e67ea94310 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -1,5 +1,6 @@ #include "map/bookmark_manager.hpp" #include "map/framework.hpp" +#include "map/local_ads_mark.hpp" #include "map/routing_mark.hpp" #include "map/user_mark.hpp" @@ -20,11 +21,12 @@ BookmarkManager::BookmarkManager(Framework & f) : m_framework(f) { - m_userMarkLayers.reserve(4); + m_userMarkLayers.reserve(5); m_userMarkLayers.emplace_back(new SearchUserMarkContainer(0.0 /* activePinDepth */, m_framework)); m_userMarkLayers.emplace_back(new ApiUserMarkContainer(0.0 /* activePinDepth */, m_framework)); m_userMarkLayers.emplace_back(new DebugUserMarkContainer(0.0 /* debugDepth */, m_framework)); m_userMarkLayers.emplace_back(new RouteUserMarkContainer(0.0 /* activePinDepth */, m_framework)); + m_userMarkLayers.emplace_back(new LocalAdsMarkContainer(0.0 /* activePinDepth */, m_framework)); UserMarkContainer::InitStaticMarks(FindUserMarksContainer(UserMarkType::SEARCH_MARK)); } diff --git a/map/framework.cpp b/map/framework.cpp index 072689195d..2e6a2725b2 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -389,10 +389,11 @@ Framework::Framework(FrameworkParams const & params) , m_routingManager(RoutingManager::Callbacks([this]() -> Index & { return m_model.GetIndex(); }, std::bind(&Framework::GetCountryInfoGetter, this)), static_cast(*this)) - , m_trafficManager(bind(&Framework::GetMwmsByRect, this, _1, false /* rough */), + , m_trafficManager(std::bind(&Framework::GetMwmsByRect, this, _1, false /* rough */), kMaxTrafficCacheSizeBytes, m_routingManager.RoutingSession()) - , m_localAdsManager(bind(&Framework::GetMwmsByRect, this, _1, true /* rough */), - bind(&Framework::GetMwmIdByName, this, _1)) + , m_localAdsManager(std::bind(&Framework::GetMwmsByRect, this, _1, true /* rough */), + std::bind(&Framework::GetMwmIdByName, this, _1), + std::bind(&Framework::ReadFeatures, this, _1, _2)) , m_displacementModeManager([this](bool show) { int const mode = show ? dp::displacement::kHotelMode : dp::displacement::kDefaultMode; CallDrapeFunction(bind(&df::DrapeEngine::SetDisplacementMode, _1, mode)); @@ -462,7 +463,10 @@ Framework::Framework(FrameworkParams const & params) // Local ads manager should be initialized after storage initialization. if (!params.m_disableLocalAds) + { + m_localAdsManager.SetBookmarkManager(&m_bmManager); m_localAdsManager.Startup(); + } m_routingManager.SetRouterImpl(RouterType::Vehicle); @@ -1911,7 +1915,7 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, for (auto const & event : events) { auto const & mwmInfo = event.m_feature.m_mwmId.GetInfo(); - if (!mwmInfo) + if (!mwmInfo || !m_localAdsManager.Contains(event.m_feature)) continue; statEvents.emplace_back(local_ads::EventType::ShowPoint, @@ -2381,7 +2385,8 @@ void Framework::InvalidateUserMarks() m_bmManager.InitBookmarks(); std::vector const types = {UserMarkType::SEARCH_MARK, UserMarkType::API_MARK, - UserMarkType::DEBUG_MARK, UserMarkType::ROUTING_MARK}; + UserMarkType::DEBUG_MARK, UserMarkType::ROUTING_MARK, + UserMarkType::LOCAL_ADS_MARK}; for (size_t typeIndex = 0; typeIndex < types.size(); typeIndex++) m_bmManager.GetUserMarksController(types[typeIndex]).NotifyChanges(); } @@ -3356,6 +3361,12 @@ MwmSet::MwmId Framework::GetMwmIdByName(std::string const & name) const return m_model.GetIndex().GetMwmIdByCountryFile(platform::CountryFile(name)); } +void Framework::ReadFeatures(std::function const & reader, + std::set const & features) +{ + m_model.ReadFeatures(reader, std::vector(features.begin(), features.end())); +} + // RoutingManager::Delegate void Framework::OnRouteFollow(routing::RouterType type) { diff --git a/map/framework.hpp b/map/framework.hpp index a64cb747ed..24f80fbf98 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -413,6 +413,9 @@ public: vector GetMwmsByRect(m2::RectD const & rect, bool rough) const; MwmSet::MwmId GetMwmIdByName(std::string const & name) const; + void ReadFeatures(std::function const & reader, + std::set const & features); + private: struct TapEvent { diff --git a/map/local_ads_manager.cpp b/map/local_ads_manager.cpp index e0699f7f62..fd16295845 100644 --- a/map/local_ads_manager.cpp +++ b/map/local_ads_manager.cpp @@ -1,4 +1,6 @@ #include "map/local_ads_manager.hpp" +#include "map/bookmark_manager.hpp" +#include "map/local_ads_mark.hpp" #include "local_ads/campaign_serialization.hpp" #include "local_ads/config.hpp" @@ -8,15 +10,18 @@ #include "drape_frontend/drape_engine.hpp" #include "drape_frontend/visual_params.hpp" +#include "indexer/feature_algo.hpp" #include "indexer/feature_data.hpp" #include "indexer/scales.hpp" #include "platform/http_client.hpp" #include "platform/marketing_service.hpp" #include "platform/platform.hpp" +#include "platform/preferred_languages.hpp" #include "platform/settings.hpp" #include "coding/file_name_utils.hpp" +#include "coding/multilang_utf8_string.hpp" #include "coding/url_encode.hpp" #include "coding/zlib.hpp" @@ -82,11 +87,12 @@ std::string MakeCampaignDownloadingURL(MwmSet::MwmId const & mwmId) return ss.str(); } -df::CustomSymbols ParseCampaign(std::vector const & rawData, MwmSet::MwmId const & mwmId, - LocalAdsManager::Timestamp timestamp) -{ - df::CustomSymbols symbols; +using CampaignData = std::map; +CampaignData ParseCampaign(std::vector const & rawData, MwmSet::MwmId const & mwmId, + LocalAdsManager::Timestamp timestamp) +{ + CampaignData data; auto campaigns = local_ads::Deserialize(rawData); for (local_ads::Campaign const & campaign : campaigns) { @@ -94,11 +100,89 @@ df::CustomSymbols ParseCampaign(std::vector const & rawData, MwmSet::Mw auto const expiration = timestamp + std::chrono::hours(24 * campaign.m_daysBeforeExpired); if (iconName.empty() || local_ads::Clock::now() > expiration) continue; - symbols.insert(std::make_pair(FeatureID(mwmId, campaign.m_featureId), - df::CustomSymbol(iconName, campaign.m_priorityBit))); + + LocalAdsMarkData markData; + markData.m_symbolName = iconName; + markData.m_minZoomLevel = 10; // TODO(@milchakov): Set value received from server. + data.insert(std::make_pair(FeatureID(mwmId, campaign.m_featureId), std::move(markData))); } - return symbols; + return data; +} + +std::set ReadCampaignFeatures(LocalAdsManager::ReadFeaturesFn const & reader, + CampaignData & campaignData) +{ + ASSERT(reader != nullptr, ()); + + std::set features; + for (auto const & data : campaignData) + features.insert(data.first); + + auto const deviceLang = StringUtf8Multilang::GetLangIndex(languages::GetCurrentNorm()); + reader([&campaignData, deviceLang](FeatureType const & ft) + { + auto it = campaignData.find(ft.GetID()); + CHECK(it != campaignData.end(), ()); + it->second.m_position = feature::GetCenter(ft, scales::GetUpperScale()); + ft.GetPreferredNames(true /* allowTranslit */, deviceLang, + it->second.m_mainText, it->second.m_auxText); + }, features); + + return features; +} + +void CreateLocalAdsMarks(BookmarkManager * bmManager, CampaignData const & campaignData) +{ + if (bmManager == nullptr) + return; + + // Here we copy campaign data, because we can create user marks only from UI thread. + GetPlatform().RunOnGuiThread([bmManager, campaignData]() + { + UserMarkNotificationGuard guard(*bmManager, UserMarkType::LOCAL_ADS_MARK); + for (auto const & data : campaignData) + { + auto userMark = guard.m_controller.CreateUserMark(data.second.m_position); + ASSERT(dynamic_cast(userMark) != nullptr, ()); + LocalAdsMark * mark = static_cast(userMark); + mark->SetData(LocalAdsMarkData(data.second)); + mark->SetFeatureId(data.first); + } + }); +} + +void DeleteLocalAdsMarks(BookmarkManager * bmManager, MwmSet::MwmId const & mwmId) +{ + if (bmManager == nullptr) + return; + + GetPlatform().RunOnGuiThread([bmManager, mwmId]() + { + UserMarkNotificationGuard guard(*bmManager, UserMarkType::LOCAL_ADS_MARK); + for (size_t i = 0; i < guard.m_controller.GetUserMarkCount();) + { + auto userMark = guard.m_controller.GetUserMark(i); + ASSERT(dynamic_cast(userMark) != nullptr, ()); + LocalAdsMark const * mark = static_cast(userMark); + if (mark->GetFeatureID().m_mwmId == mwmId) + guard.m_controller.DeleteUserMark(i); + else + ++i; + } + }); +} + +void DeleteAllLocalAdsMarks(BookmarkManager * bmManager) +{ + if (bmManager == nullptr) + return; + + GetPlatform().RunOnGuiThread([bmManager]() + { + UserMarkNotificationGuard guard(*bmManager, UserMarkType::LOCAL_ADS_MARK); + guard.m_controller.Clear(); + }); } #ifdef TEMPORARY_LOCAL_ADS_JSON_SERIALIZATION @@ -170,12 +254,17 @@ std::string MakeCampaignPageURL(FeatureID const & featureId) } } // namespace -LocalAdsManager::LocalAdsManager(GetMwmsByRectFn const & getMwmsByRectFn, - GetMwmIdByName const & getMwmIdByName) - : m_getMwmsByRectFn(getMwmsByRectFn), m_getMwmIdByNameFn(getMwmIdByName) +LocalAdsManager::LocalAdsManager(GetMwmsByRectFn && getMwmsByRectFn, + GetMwmIdByNameFn && getMwmIdByName, + ReadFeaturesFn && readFeaturesFn) + : m_getMwmsByRectFn(std::move(getMwmsByRectFn)) + , m_getMwmIdByNameFn(std::move(getMwmIdByName)) + , m_readFeaturesFn(std::move(readFeaturesFn)) + , m_bmManager(nullptr) { CHECK(m_getMwmsByRectFn != nullptr, ()); CHECK(m_getMwmIdByNameFn != nullptr, ()); + CHECK(m_readFeaturesFn != nullptr, ()); m_statistics.SetUserId(GetPlatform().UniqueClientId()); @@ -220,20 +309,18 @@ void LocalAdsManager::Teardown() m_statistics.Teardown(); } +void LocalAdsManager::SetBookmarkManager(BookmarkManager * bmManager) +{ + m_bmManager = bmManager; +} + void LocalAdsManager::SetDrapeEngine(ref_ptr engine) { { std::lock_guard lock(m_drapeEngineMutex); m_drapeEngine = engine; } - { - std::lock_guard lock(m_symbolsCacheMutex); - if (m_symbolsCache.empty()) - return; - - m_drapeEngine->AddCustomSymbols(std::move(m_symbolsCache)); - m_symbolsCache.clear(); - } + UpdateFeaturesCache({}); } void LocalAdsManager::UpdateViewport(ScreenBase const & screen) @@ -377,25 +464,17 @@ void LocalAdsManager::ThreadRoutine() if (!DownloadCampaign(mwm.first, info.m_data)) continue; - // Parse data and send symbols to rendering (or delete from rendering). + // Parse data and recreate marks. + ClearLocalAdsForMwm(mwm.first); if (!info.m_data.empty()) { - auto symbols = ParseCampaign(std::move(info.m_data), mwm.first, info.m_created); - if (symbols.empty()) + auto campaignData = ParseCampaign(std::move(info.m_data), mwm.first, info.m_created); + if (!campaignData.empty()) { - DeleteSymbolsFromRendering(mwm.first); - } - else - { - UpdateFeaturesCache(symbols); - SendSymbolsToRendering(std::move(symbols)); + UpdateFeaturesCache(ReadCampaignFeatures(m_readFeaturesFn, campaignData)); + CreateLocalAdsMarks(m_bmManager, campaignData); } } - else - { - DeleteSymbolsFromRendering(mwm.first); - } - info.m_created = local_ads::Clock::now(); // Update run-time data. { @@ -409,7 +488,7 @@ void LocalAdsManager::ThreadRoutine() std::lock_guard lock(m_mutex); m_campaigns.erase(countryName); m_info.erase(countryName); - DeleteSymbolsFromRendering(mwm.first); + ClearLocalAdsForMwm(mwm.first); } } campaignMwms.clear(); @@ -489,62 +568,68 @@ void LocalAdsManager::WriteCampaignFile(std::string const & campaignFile) } } -void LocalAdsManager::SendSymbolsToRendering(df::CustomSymbols && symbols) -{ - if (symbols.empty()) - return; - - // Send symbols if drape engine is available. - { - std::lock_guard lock(m_drapeEngineMutex); - if (m_drapeEngine != nullptr) - { - m_drapeEngine->AddCustomSymbols(std::move(symbols)); - return; - } - } - - std::lock_guard lock(m_symbolsCacheMutex); - m_symbolsCache.insert(symbols.begin(), symbols.end()); -} - -void LocalAdsManager::DeleteSymbolsFromRendering(MwmSet::MwmId const & mwmId) -{ - std::lock_guard lock(m_drapeEngineMutex); - if (m_drapeEngine != nullptr) - m_drapeEngine->RemoveCustomSymbols(mwmId); -} - void LocalAdsManager::Invalidate() { + DeleteAllLocalAdsMarks(m_bmManager); { std::lock_guard lock(m_drapeEngineMutex); if (m_drapeEngine != nullptr) - m_drapeEngine->RemoveAllCustomSymbols(); + m_drapeEngine->RemoveAllCustomFeatures(); } - df::CustomSymbols symbols; + CampaignData campaignData; { std::lock_guard lock(m_mutex); for (auto const & info : m_info) { - auto campaignSymbols = ParseCampaign(info.second.m_data, m_getMwmIdByNameFn(info.first), - info.second.m_created); - symbols.insert(campaignSymbols.begin(), campaignSymbols.end()); + auto data = ParseCampaign(info.second.m_data, m_getMwmIdByNameFn(info.first), + info.second.m_created); + campaignData.insert(data.begin(), data.end()); } } - UpdateFeaturesCache(symbols); - SendSymbolsToRendering(std::move(symbols)); + UpdateFeaturesCache(ReadCampaignFeatures(m_readFeaturesFn, campaignData)); + CreateLocalAdsMarks(m_bmManager, campaignData); } -void LocalAdsManager::UpdateFeaturesCache(df::CustomSymbols const & symbols) +void LocalAdsManager::UpdateFeaturesCache(std::set && ids) { - if (symbols.empty()) - return; + std::set featuresCache; + { + std::lock_guard lock(m_featuresCacheMutex); + if (!ids.empty()) + m_featuresCache.insert(ids.begin(), ids.end()); + featuresCache = m_featuresCache; + } + { + std::lock_guard lock(m_drapeEngineMutex); + if (m_drapeEngine != nullptr) + m_drapeEngine->SetCustomFeatures(std::move(featuresCache)); + } +} - std::lock_guard lock(m_featuresCacheMutex); - for (auto const & symbolPair : symbols) - m_featuresCache.insert(symbolPair.first); +void LocalAdsManager::ClearLocalAdsForMwm(MwmSet::MwmId const &mwmId) +{ + // Clear feature cache. + { + std::lock_guard lock(m_featuresCacheMutex); + for (auto it = m_featuresCache.begin(); it != m_featuresCache.end();) + { + if (it->m_mwmId == mwmId) + it = m_featuresCache.erase(it); + else + ++it; + } + } + + // Remove custom features in graphics engine. + { + std::lock_guard lock(m_drapeEngineMutex); + if (m_drapeEngine != nullptr) + m_drapeEngine->RemoveCustomFeatures(mwmId); + } + + // Delete marks. + DeleteLocalAdsMarks(m_bmManager, mwmId); } bool LocalAdsManager::Contains(FeatureID const & featureId) const diff --git a/map/local_ads_manager.hpp b/map/local_ads_manager.hpp index 3bc0943bc8..147e81c43e 100644 --- a/map/local_ads_manager.hpp +++ b/map/local_ads_manager.hpp @@ -2,8 +2,6 @@ #include "local_ads/statistics.hpp" -#include "drape_frontend/custom_symbol.hpp" - #include "drape/pointers.hpp" #include "geometry/rect2d.hpp" @@ -15,7 +13,9 @@ #include "base/thread.hpp" +#include #include +#include #include #include #include @@ -32,17 +32,25 @@ namespace feature class TypesHolder; } +class BookmarkManager; + class LocalAdsManager final { public: - using GetMwmsByRectFn = function(m2::RectD const &)>; - using GetMwmIdByName = function; + using GetMwmsByRectFn = std::function(m2::RectD const &)>; + using GetMwmIdByNameFn = std::function; + using ReadFeatureTypeFn = std::function; + using ReadFeaturesFn = std::function const & features)>; using Timestamp = local_ads::Timestamp; - LocalAdsManager(GetMwmsByRectFn const & getMwmsByRectFn, GetMwmIdByName const & getMwmIdByName); + LocalAdsManager(GetMwmsByRectFn && getMwmsByRectFn, GetMwmIdByNameFn && getMwmIdByName, + ReadFeaturesFn && readFeaturesFn); LocalAdsManager(LocalAdsManager && /* localAdsManager */) = default; ~LocalAdsManager(); + void SetBookmarkManager(BookmarkManager * bmManager); + void Startup(); void Teardown(); void SetDrapeEngine(ref_ptr engine); @@ -72,13 +80,11 @@ private: void ThreadRoutine(); bool WaitForRequest(std::set & campaignMwms); - void SendSymbolsToRendering(df::CustomSymbols && symbols); - void DeleteSymbolsFromRendering(MwmSet::MwmId const & mwmId); - void ReadCampaignFile(std::string const & campaignFile); void WriteCampaignFile(std::string const & campaignFile); - void UpdateFeaturesCache(df::CustomSymbols const & symbols); + void UpdateFeaturesCache(std::set && ids); + void ClearLocalAdsForMwm(MwmSet::MwmId const &mwmId); void FillSupportedTypes(); @@ -87,7 +93,10 @@ private: bool DownloadCampaign(MwmSet::MwmId const & mwmId, std::vector & bytes); GetMwmsByRectFn m_getMwmsByRectFn; - GetMwmIdByName m_getMwmIdByNameFn; + GetMwmIdByNameFn m_getMwmIdByNameFn; + ReadFeaturesFn m_readFeaturesFn; + + std::atomic m_bmManager; ref_ptr m_drapeEngine; std::mutex m_drapeEngineMutex; @@ -100,9 +109,6 @@ private: }; std::map m_info; - df::CustomSymbols m_symbolsCache; - std::mutex m_symbolsCacheMutex; - std::set m_featuresCache; mutable std::mutex m_featuresCacheMutex; diff --git a/map/local_ads_mark.cpp b/map/local_ads_mark.cpp new file mode 100644 index 0000000000..e2282ca84b --- /dev/null +++ b/map/local_ads_mark.cpp @@ -0,0 +1,71 @@ +#include "map/local_ads_mark.hpp" + +#include "drape_frontend/color_constants.hpp" +#include "drape_frontend/visual_params.hpp" + +#include + +namespace +{ +static std::string const kLocalAdsPrimaryText = "LocalAdsPrimaryText"; +static std::string const kLocalAdsPrimaryTextOutline = "LocalAdsPrimaryTextOutline"; +static std::string const kLocalAdsSecondaryText = "LocalAdsSecondaryText"; +static std::string const kLocalAdsSecondaryTextOutline = "LocalAdsSecondaryTextOutline"; + +float const kLocalAdsPrimaryTextSize = 11.0f; +float const kLocalAdsSecondaryTextSize = 10.0f; +float const kSecondaryOffsetY = 2.0; +} // namespace + +LocalAdsMark::LocalAdsMark(m2::PointD const & ptOrg, + UserMarkContainer * container) + : UserMark(ptOrg, container) +{ + float const vs = static_cast(df::VisualParams::Instance().GetVisualScale()); + m_titleDecl.m_anchor = dp::Top; + m_titleDecl.m_primaryTextFont.m_color = df::GetColorConstant(kLocalAdsPrimaryText); + m_titleDecl.m_primaryTextFont.m_outlineColor = df::GetColorConstant(kLocalAdsPrimaryTextOutline); + m_titleDecl.m_primaryTextFont.m_size = kLocalAdsPrimaryTextSize * vs; + m_titleDecl.m_secondaryTextFont.m_color = df::GetColorConstant(kLocalAdsSecondaryText); + m_titleDecl.m_secondaryTextFont.m_outlineColor = df::GetColorConstant(kLocalAdsSecondaryTextOutline); + m_titleDecl.m_secondaryTextFont.m_size = kLocalAdsSecondaryTextSize * vs; + m_titleDecl.m_secondaryOffset = m2::PointF(0, kSecondaryOffsetY * vs); +} + +dp::GLState::DepthLayer LocalAdsMark::GetDepthLayer() const +{ + return dp::GLState::LocalAdsMarkLayer; +} + +drape_ptr LocalAdsMark::GetTitleDecl() const +{ + drape_ptr titleDecl = make_unique_dp(m_titleDecl); + return titleDecl; +} + +void LocalAdsMark::SetData(LocalAdsMarkData && data) +{ + SetDirty(); + m_data = std::move(data); + + m_titleDecl.m_primaryText = m_data.m_mainText; + if (!m_titleDecl.m_primaryText.empty()) + m_titleDecl.m_secondaryText = m_data.m_auxText; + else + m_titleDecl.m_secondaryText.clear(); +} + +void LocalAdsMark::SetFeatureId(FeatureID const & id) +{ + SetDirty(); + m_featureId = id; +} + +LocalAdsMarkContainer::LocalAdsMarkContainer(double layerDepth, Framework & fm) + : UserMarkContainer(layerDepth, UserMarkType::LOCAL_ADS_MARK, fm) +{} + +UserMark * LocalAdsMarkContainer::AllocateUserMark(m2::PointD const & ptOrg) +{ + return new LocalAdsMark(ptOrg, this); +} diff --git a/map/local_ads_mark.hpp b/map/local_ads_mark.hpp new file mode 100644 index 0000000000..64f62870d2 --- /dev/null +++ b/map/local_ads_mark.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include "map/user_mark_container.hpp" + +#include +#include +#include + +struct LocalAdsMarkData +{ + m2::PointD m_position = m2::PointD::Zero(); + std::string m_symbolName; + uint8_t m_minZoomLevel = 1; + std::string m_mainText; + std::string m_auxText; + uint16_t m_priority = std::numeric_limits::max(); +}; + +class LocalAdsMark : public UserMark +{ +public: + LocalAdsMark(m2::PointD const & ptOrg, UserMarkContainer * container); + virtual ~LocalAdsMark() {} + + dp::GLState::DepthLayer GetDepthLayer() const override; + + std::string GetSymbolName() const override { return m_data.m_symbolName; } + UserMark::Type GetMarkType() const override { return Type::LOCAL_ADS; } + + drape_ptr GetTitleDecl() const override; + uint16_t GetPriority() const override { return m_data.m_priority; } + bool HasSymbolPriority() const override { return true; } + bool HasTitlePriority() const override { return true; } + int GetMinZoom() const override { return static_cast(m_data.m_minZoomLevel); } + FeatureID GetFeatureID() const override { return m_featureId; } + + void SetData(LocalAdsMarkData && data); + void SetFeatureId(FeatureID const & id); + +private: + LocalAdsMarkData m_data; + FeatureID m_featureId; + dp::TitleDecl m_titleDecl; +}; + +class LocalAdsMarkContainer : public UserMarkContainer +{ +public: + LocalAdsMarkContainer(double layerDepth, Framework & fm); +protected: + UserMark * AllocateUserMark(m2::PointD const & ptOrg) override; +}; diff --git a/map/map.pro b/map/map.pro index d885d93aa7..58d2a73d19 100644 --- a/map/map.pro +++ b/map/map.pro @@ -28,6 +28,7 @@ HEADERS += \ gps_track_storage.hpp \ gps_tracker.hpp \ local_ads_manager.hpp \ + local_ads_mark.hpp \ mwm_tree.hpp \ mwm_url.hpp \ place_page_info.hpp \ @@ -60,6 +61,7 @@ SOURCES += \ gps_track_storage.cpp \ gps_tracker.cpp \ local_ads_manager.cpp \ + local_ads_mark.cpp \ local_ads_supported_types.cpp \ mwm_tree.cpp \ mwm_url.cpp \ diff --git a/map/routing_mark.hpp b/map/routing_mark.hpp index d96f097a5c..0f517dea85 100644 --- a/map/routing_mark.hpp +++ b/map/routing_mark.hpp @@ -55,8 +55,8 @@ public: drape_ptr GetTitleDecl() const override; - bool SymbolHasPriority() const override { return false; } - bool TitleHasPriority() const override { return true; } + bool HasSymbolPriority() const override { return false; } + bool HasTitlePriority() const override { return true; } private: RouteMarkData m_markData; diff --git a/map/user_mark.cpp b/map/user_mark.cpp index 5693d23373..ad5b75c121 100644 --- a/map/user_mark.cpp +++ b/map/user_mark.cpp @@ -131,5 +131,6 @@ string DebugPrint(UserMark::Type type) case UserMark::Type::MY_POSITION: return "MY_POSITION"; case UserMark::Type::DEBUG_MARK: return "DEBUG_MARK"; case UserMark::Type::ROUTING: return "ROUTING"; + case UserMark::Type::LOCAL_ADS: return "LOCAL_ADS"; } } diff --git a/map/user_mark.hpp b/map/user_mark.hpp index 1c0b33d671..ca5a8549e9 100644 --- a/map/user_mark.hpp +++ b/map/user_mark.hpp @@ -13,7 +13,6 @@ #include "std/unique_ptr.hpp" #include "std/utility.hpp" - class UserMarkContainer; class UserMarkCopy; @@ -31,6 +30,7 @@ public: BOOKMARK, MY_POSITION, ROUTING, + LOCAL_ADS, DEBUG_MARK }; @@ -48,10 +48,11 @@ public: dp::GLState::DepthLayer GetDepthLayer() const override; bool HasCreationAnimation() const override; drape_ptr GetTitleDecl() const override { return nullptr; } - uint16_t GetProirity() const override { return kDefaultUserMarkProirity; } - bool SymbolHasPriority() const override { return false; } - bool TitleHasPriority() const override { return false; } + uint16_t GetPriority() const override { return kDefaultUserMarkProirity; } + bool HasSymbolPriority() const override { return false; } + bool HasTitlePriority() const override { return false; } int GetMinZoom() const override { return 1; } + FeatureID GetFeatureID() const override { return FeatureID(); } UserMarkContainer const * GetContainer() const; ms::LatLon GetLatLon() const; diff --git a/map/user_mark_container.hpp b/map/user_mark_container.hpp index aae53d174a..21de4f0dc9 100644 --- a/map/user_mark_container.hpp +++ b/map/user_mark_container.hpp @@ -22,7 +22,8 @@ enum class UserMarkType API_MARK, DEBUG_MARK, BOOKMARK_MARK, - ROUTING_MARK + ROUTING_MARK, + LOCAL_ADS_MARK }; class UserMarksController diff --git a/xcode/map/map.xcodeproj/project.pbxproj b/xcode/map/map.xcodeproj/project.pbxproj index 7d98cff128..fe45240e13 100644 --- a/xcode/map/map.xcodeproj/project.pbxproj +++ b/xcode/map/map.xcodeproj/project.pbxproj @@ -26,6 +26,8 @@ 3D47B2C81F20EF06000828D2 /* displayed_categories_modifiers.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3D47B2C61F20EF06000828D2 /* displayed_categories_modifiers.hpp */; }; 3D74ABBE1EA76F1D0063A898 /* local_ads_supported_types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D74ABBD1EA76F1D0063A898 /* local_ads_supported_types.cpp */; }; 45201E931CE4AC90008A4842 /* api_mark_point.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45201E921CE4AC90008A4842 /* api_mark_point.cpp */; }; + 454649F11F2728CE00EF4064 /* local_ads_mark.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 454649EF1F2728CE00EF4064 /* local_ads_mark.cpp */; }; + 454649F21F2728CE00EF4064 /* local_ads_mark.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 454649F01F2728CE00EF4064 /* local_ads_mark.hpp */; }; 45580ABE1E2CBD5E00CD535D /* benchmark_tools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45580ABC1E2CBD5E00CD535D /* benchmark_tools.cpp */; }; 45580ABF1E2CBD5E00CD535D /* benchmark_tools.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45580ABD1E2CBD5E00CD535D /* benchmark_tools.hpp */; }; 45D287671E966E3400587F05 /* liblocal_ads.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45D287661E966E3400587F05 /* liblocal_ads.a */; }; @@ -154,6 +156,8 @@ 3D47B2C61F20EF06000828D2 /* displayed_categories_modifiers.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = displayed_categories_modifiers.hpp; sourceTree = ""; }; 3D74ABBD1EA76F1D0063A898 /* local_ads_supported_types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = local_ads_supported_types.cpp; sourceTree = ""; }; 45201E921CE4AC90008A4842 /* api_mark_point.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = api_mark_point.cpp; sourceTree = ""; }; + 454649EF1F2728CE00EF4064 /* local_ads_mark.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = local_ads_mark.cpp; sourceTree = ""; }; + 454649F01F2728CE00EF4064 /* local_ads_mark.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = local_ads_mark.hpp; sourceTree = ""; }; 45580ABC1E2CBD5E00CD535D /* benchmark_tools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = benchmark_tools.cpp; sourceTree = ""; }; 45580ABD1E2CBD5E00CD535D /* benchmark_tools.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = benchmark_tools.hpp; sourceTree = ""; }; 45D287661E966E3400587F05 /* liblocal_ads.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblocal_ads.a; path = "../../../omim-build/xcode/Debug-iphonesimulator/liblocal_ads.a"; sourceTree = ""; }; @@ -431,6 +435,8 @@ 675345BD1A4054AD00A0A8C3 /* map */ = { isa = PBXGroup; children = ( + 454649EF1F2728CE00EF4064 /* local_ads_mark.cpp */, + 454649F01F2728CE00EF4064 /* local_ads_mark.hpp */, 3D47B2C51F20EF06000828D2 /* displayed_categories_modifiers.cpp */, 3D47B2C61F20EF06000828D2 /* displayed_categories_modifiers.hpp */, 3D47B2901F054BC5000828D2 /* taxi_delegate.cpp */, @@ -508,6 +514,7 @@ F6B283081C1B03320081957A /* gps_track_storage.hpp in Headers */, 675346671A4054E800A0A8C3 /* ge0_parser.hpp in Headers */, 675346A21A4054E800A0A8C3 /* user_mark.hpp in Headers */, + 454649F21F2728CE00EF4064 /* local_ads_mark.hpp in Headers */, F6B283061C1B03320081957A /* gps_track_filter.hpp in Headers */, 34583BD01C88556800F94664 /* place_page_info.hpp in Headers */, 34921F661BFA0A6900737D6E /* api_mark_point.hpp in Headers */, @@ -646,6 +653,7 @@ 56B6EAF81EA4BAF00037D963 /* mwm_tree.cpp in Sources */, 674C38621BFF3095000D603B /* user_mark.cpp in Sources */, 675346641A4054E800A0A8C3 /* framework.cpp in Sources */, + 454649F11F2728CE00EF4064 /* local_ads_mark.cpp in Sources */, F63421F81DF9BF9100A96868 /* reachable_by_taxi_checker.cpp in Sources */, 6753466A1A4054E800A0A8C3 /* geourl_process.cpp in Sources */, 348AB57C1D7EE0C6009F8301 /* chart_generator.cpp in Sources */,