diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index d7a3f0313b..355e1e34f6 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -264,8 +264,10 @@ void BackendRenderer::AcceptMessage(ref_ptr message) { ref_ptr msg = message; size_t const layerId = msg->GetLayerId(); - m_userMarkGenerator->SetUserMarks(static_cast(layerId), msg->AcceptMarkRenderParams()); - m_userMarkGenerator->SetUserLines(static_cast(layerId), msg->AcceptLineRenderParams()); + m_userMarkGenerator->RemoveUserMarks(msg->AcceptRemovedIds()); + m_userMarkGenerator->SetUserMarks(msg->AcceptMarkRenderParams()); + m_userMarkGenerator->SetUserLines(msg->AcceptLineRenderParams()); + m_userMarkGenerator->SetGroup(msg->GetLayerId(), msg->AcceptIds()); m_commutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(layerId), MessagePriority::Normal); @@ -276,7 +278,7 @@ void BackendRenderer::AcceptMessage(ref_ptr message) { ref_ptr msg = message; size_t const layerId = msg->GetLayerId(); - m_userMarkGenerator->ClearUserMarks(static_cast(layerId)); + m_userMarkGenerator->RemoveGroup(static_cast(layerId)); m_commutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(layerId), MessagePriority::Normal); diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 36c2968a24..8b7ed85434 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -210,19 +210,26 @@ void DrapeEngine::ChangeVisibilityUserMarksLayer(size_t layerId, bool isVisible) void DrapeEngine::UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provider) { auto marksRenderCollection = make_unique_dp(); + auto idCollection = make_unique_dp(); + IDCollection removedIdCollection; marksRenderCollection->reserve(provider->GetUserPointCount()); for (size_t pointIndex = 0, sz = provider->GetUserPointCount(); pointIndex < sz; ++pointIndex) { UserPointMark const * mark = provider->GetUserPointMark(pointIndex); - UserMarkRenderParams renderInfo; - renderInfo.m_anchor = mark->GetAnchor(); - renderInfo.m_depth = mark->GetDepth(); - renderInfo.m_isVisible = mark->IsVisible(); - renderInfo.m_pivot = mark->GetPivot(); - renderInfo.m_pixelOffset = mark->GetPixelOffset(); - renderInfo.m_runCreationAnim = mark->HasCreationAnimation(); - renderInfo.m_symbolName = mark->GetSymbolName(); - marksRenderCollection->emplace_back(std::move(renderInfo)); + idCollection->m_marksID.push_back(mark->GetId()); + if (mark->IsDirty()) + { + auto renderInfo = make_unique_dp(); + renderInfo->m_anchor = mark->GetAnchor(); + renderInfo->m_depth = mark->GetDepth(); + renderInfo->m_isVisible = mark->IsVisible(); + renderInfo->m_pivot = mark->GetPivot(); + renderInfo->m_pixelOffset = mark->GetPixelOffset(); + renderInfo->m_runCreationAnim = mark->HasCreationAnimation(); + renderInfo->m_symbolName = mark->GetSymbolName(); + marksRenderCollection->emplace(mark->GetId(), std::move(renderInfo)); + mark->AcceptChanges(); + } } auto linesRenderCollection = make_unique_dp(); @@ -230,19 +237,27 @@ void DrapeEngine::UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provi for (size_t lineIndex = 0, sz = provider->GetUserLineCount(); lineIndex < sz; ++lineIndex) { UserLineMark const * mark = provider->GetUserLineMark(lineIndex); - UserLineRenderParams renderInfo; - renderInfo.m_spline = m2::SharedSpline(mark->GetPoints()); - renderInfo.m_layers.reserve(mark->GetLayerCount()); - for (size_t layerIndex = 0, layersCount = mark->GetLayerCount(); layerIndex < layersCount; ++layerIndex) + idCollection->m_linesID.push_back(mark->GetId()); + if (mark->IsDirty()) { - renderInfo.m_layers.emplace_back(mark->GetColor(layerIndex), - mark->GetWidth(layerIndex), - mark->GetLayerDepth(layerIndex)); + auto renderInfo = make_unique_dp(); + renderInfo->m_spline = m2::SharedSpline(mark->GetPoints()); + renderInfo->m_layers.reserve(mark->GetLayerCount()); + for (size_t layerIndex = 0, layersCount = mark->GetLayerCount(); layerIndex < layersCount; ++layerIndex) + { + renderInfo->m_layers.emplace_back(mark->GetColor(layerIndex), + mark->GetWidth(layerIndex), + mark->GetLayerDepth(layerIndex)); + } + linesRenderCollection->emplace(mark->GetId(), std::move(renderInfo)); + mark->AcceptChanges(); } - linesRenderCollection->emplace_back(std::move(renderInfo)); } + provider->AcceptChanges(removedIdCollection.m_marksID); m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(layerId, + std::move(idCollection), + std::move(removedIdCollection), std::move(marksRenderCollection), std::move(linesRenderCollection)), MessagePriority::Normal); diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 6e0d3a1252..8c3722baec 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -237,21 +237,30 @@ private: class UpdateUserMarkLayerMessage : public BaseUserMarkLayerMessage { public: - UpdateUserMarkLayerMessage(size_t layerId, drape_ptr && marksRenderParams, + UpdateUserMarkLayerMessage(size_t layerId, + drape_ptr && ids, + IDCollection && removedIds, + drape_ptr && marksRenderParams, drape_ptr && linesRenderParams) : BaseUserMarkLayerMessage(layerId) , m_marksRenderParams(std::move(marksRenderParams)) , m_linesRenderParams(std::move(linesRenderParams)) + , m_ids(std::move(ids)) + , m_removedIds(std::move(removedIds)) {} Type GetType() const override { return Message::UpdateUserMarkLayer; } drape_ptr && AcceptMarkRenderParams() { return std::move(m_marksRenderParams); } drape_ptr && AcceptLineRenderParams() { return std::move(m_linesRenderParams); } + drape_ptr && AcceptIds() { return std::move(m_ids); } + IDCollection && AcceptRemovedIds() { return std::move(m_removedIds); } private: drape_ptr m_marksRenderParams; drape_ptr m_linesRenderParams; + drape_ptr m_ids; + IDCollection m_removedIds; }; class FlushUserMarksMessage : public Message diff --git a/drape_frontend/user_mark_generator.cpp b/drape_frontend/user_mark_generator.cpp index 2b17c456d8..b1d8a3d233 100644 --- a/drape_frontend/user_mark_generator.cpp +++ b/drape_frontend/user_mark_generator.cpp @@ -17,70 +17,84 @@ UserMarkGenerator::UserMarkGenerator(TFlushFn const & flushFn) ASSERT(m_flushFn != nullptr, ()); } -void UserMarkGenerator::ClearUserMarks(GroupID groupId) +void UserMarkGenerator::RemoveGroup(GroupID groupId) { m_groupsVisibility.erase(groupId); - m_marks.erase(groupId); - m_lines.erase(groupId); - UpdateMarksIndex(groupId); - UpdateLinesIndex(groupId); + m_groups.erase(groupId); + UpdateIndex(groupId); } -void UserMarkGenerator::SetUserMarks(GroupID groupId, drape_ptr && marks) +void UserMarkGenerator::SetGroup(GroupID groupId, drape_ptr && ids) { - m_marks[groupId] = std::move(marks); - UpdateMarksIndex(groupId); + m_groups[groupId] = std::move(ids); + UpdateIndex(groupId); } -void UserMarkGenerator::SetUserLines(GroupID groupId, drape_ptr && lines) +void UserMarkGenerator::RemoveUserMarks(IDCollection && ids) { - m_lines[groupId] = std::move(lines); - UpdateLinesIndex(groupId); + for (auto const & id : ids.m_marksID) + m_marks.erase(id); + for (auto const & id : ids.m_linesID) + m_lines.erase(id); } -void UserMarkGenerator::UpdateMarksIndex(GroupID groupId) +void UserMarkGenerator::SetUserMarks(drape_ptr && marks) { - for (auto & tileGroups : m_marksIndex) + for (auto & pair : *marks.get()) + { + auto it = m_marks.find(pair.first); + if (it != m_marks.end()) + it->second = std::move(pair.second); + else + m_marks.emplace(pair.first, std::move(pair.second)); + } +} + +void UserMarkGenerator::SetUserLines(drape_ptr && lines) +{ + for (auto & pair : *lines.get()) + { + auto it = m_lines.find(pair.first); + if (it != m_lines.end()) + it->second = std::move(pair.second); + else + m_lines.emplace(pair.first, std::move(pair.second)); + } +} + + +void UserMarkGenerator::UpdateIndex(GroupID groupId) +{ + for (auto & tileGroups : m_index) { auto itGroupIndexes = tileGroups.second->find(groupId); if (itGroupIndexes != tileGroups.second->end()) - itGroupIndexes->second->m_markIndexes.clear(); - } - - if (m_marks.find(groupId) == m_marks.end()) - return; - - UserMarksRenderCollection & marks = *m_marks[groupId]; - for (size_t markIndex = 0; markIndex < marks.size(); ++markIndex) - { - UserMarkRenderParams const & params = marks[markIndex]; - for (int zoomLevel = params.m_minZoom; zoomLevel <= scales::GetUpperScale(); ++zoomLevel) { - TileKey const tileKey = GetTileKeyByPoint(params.m_pivot, zoomLevel); - ref_ptr groupIndexes = GetIndexesCollection(tileKey, groupId); - groupIndexes->m_markIndexes.push_back(static_cast(markIndex)); + itGroupIndexes->second->m_marksID.clear(); + itGroupIndexes->second->m_linesID.clear(); } } - CleanIndex(); -} - -void UserMarkGenerator::UpdateLinesIndex(GroupID groupId) -{ - for (auto & tileGroups : m_marksIndex) - { - auto itGroupIndexes = tileGroups.second->find(groupId); - if (itGroupIndexes != tileGroups.second->end()) - itGroupIndexes->second->m_lineIndexes.clear(); - } - - if (m_lines.find(groupId) == m_lines.end()) + auto const groupIt = m_groups.find(groupId); + if (groupIt == m_groups.end()) return; - UserLinesRenderCollection & lines = *m_lines[groupId]; - for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) + IDCollection & idCollection = *groupIt->second.get(); + + for (auto markId : idCollection.m_marksID) { - UserLineRenderParams const & params = lines[lineIndex]; + UserMarkRenderParams const & params = *m_marks[markId].get(); + for (int zoomLevel = params.m_minZoom; zoomLevel <= scales::GetUpperScale(); ++zoomLevel) + { + TileKey const tileKey = GetTileKeyByPoint(params.m_pivot, zoomLevel); + ref_ptr groupIDs = GetIdCollection(tileKey, groupId); + groupIDs->m_marksID.push_back(static_cast(markId)); + } + } + + for (auto lineId : idCollection.m_linesID) + { + UserLineRenderParams const & params = *m_lines[lineId].get(); m2::RectD rect; for (m2::PointD const & point : params.m_spline->GetPath()) rect.Add(point); @@ -90,8 +104,8 @@ void UserMarkGenerator::UpdateLinesIndex(GroupID groupId) CalcTilesCoverage(rect, zoomLevel, [&](int tileX, int tileY) { TileKey const tileKey(tileX, tileY, zoomLevel); - ref_ptr groupIndexes = GetIndexesCollection(tileKey, groupId); - groupIndexes->m_lineIndexes.push_back(static_cast(lineIndex)); + ref_ptr groupIDs = GetIdCollection(tileKey, groupId); + groupIDs->m_linesID.push_back(static_cast(lineId)); }); } } @@ -99,52 +113,52 @@ void UserMarkGenerator::UpdateLinesIndex(GroupID groupId) CleanIndex(); } -ref_ptr UserMarkGenerator::GetIndexesCollection(TileKey const & tileKey, GroupID groupId) +ref_ptr UserMarkGenerator::GetIdCollection(TileKey const & tileKey, GroupID groupId) { - ref_ptr tileGroups; - auto itTileGroups = m_marksIndex.find(tileKey); - if (itTileGroups == m_marksIndex.end()) + ref_ptr tileGroups; + auto itTileGroups = m_index.find(tileKey); + if (itTileGroups == m_index.end()) { - auto tileIndexesGroups = make_unique_dp(); - tileGroups = make_ref(tileIndexesGroups); - m_marksIndex.insert(make_pair(tileKey, std::move(tileIndexesGroups))); + auto tileIDGroups = make_unique_dp(); + tileGroups = make_ref(tileIDGroups); + m_index.insert(make_pair(tileKey, std::move(tileIDGroups))); } else { tileGroups = make_ref(itTileGroups->second); } - ref_ptr groupIndexes; - auto itGroupIndexes = tileGroups->find(groupId); - if (itGroupIndexes == tileGroups->end()) + ref_ptr groupIDs; + auto itGroupIDs = tileGroups->find(groupId); + if (itGroupIDs == tileGroups->end()) { - auto groupMarkIndexes = make_unique_dp(); - groupIndexes = make_ref(groupMarkIndexes); + auto groupMarkIndexes = make_unique_dp(); + groupIDs = make_ref(groupMarkIndexes); tileGroups->insert(make_pair(groupId, std::move(groupMarkIndexes))); } else { - groupIndexes = make_ref(itGroupIndexes->second); + groupIDs = make_ref(itGroupIDs->second); } - return groupIndexes; + return groupIDs; } void UserMarkGenerator::CleanIndex() { - for (auto tileIt = m_marksIndex.begin(); tileIt != m_marksIndex.end();) + for (auto tileIt = m_index.begin(); tileIt != m_index.end();) { if (tileIt->second->empty()) - tileIt = m_marksIndex.erase(tileIt); + tileIt = m_index.erase(tileIt); else ++tileIt; } - for (auto & tileGroups : m_marksIndex) + for (auto & tileGroups : m_index) { for (auto groupIt = tileGroups.second->begin(); groupIt != tileGroups.second->end();) { - if (groupIt->second->m_markIndexes.empty() && groupIt->second->m_lineIndexes.empty()) + if (groupIt->second->m_marksID.empty() && groupIt->second->m_linesID.empty()) groupIt = tileGroups.second->erase(groupIt); else ++groupIt; @@ -162,9 +176,9 @@ void UserMarkGenerator::SetGroupVisibility(GroupID groupId, bool isVisible) void UserMarkGenerator::GenerateUserMarksGeometry(TileKey const & tileKey, ref_ptr textures) { - auto const itTile = m_marksIndex.find(TileKey(tileKey.m_x, tileKey.m_y, std::min(tileKey.m_zoomLevel, - scales::GetUpperScale()))); - if (itTile == m_marksIndex.end()) + auto const itTile = m_index.find(TileKey(tileKey.m_x, tileKey.m_y, + std::min(tileKey.m_zoomLevel, scales::GetUpperScale()))); + if (itTile == m_index.end()) return; TUserMarksRenderData renderData; @@ -177,7 +191,7 @@ void UserMarkGenerator::GenerateUserMarksGeometry(TileKey const & tileKey, ref_p renderData.emplace_back(state, std::move(b), tileKey); }); - MarkIndexesGroups & indexesGroups = *itTile->second; + MarksIDGroups & indexesGroups = *itTile->second; for (auto & groupPair : indexesGroups) { GroupID groupId = groupPair.first; @@ -185,8 +199,8 @@ void UserMarkGenerator::GenerateUserMarksGeometry(TileKey const & tileKey, ref_p if (m_groupsVisibility.find(groupId) == m_groupsVisibility.end()) continue; - CacheUserMarks(tileKey, textures, groupPair.second->m_markIndexes, *m_marks[groupId], batcher); - CacheUserLines(tileKey, textures, groupPair.second->m_lineIndexes, *m_lines[groupId], batcher); + CacheUserMarks(tileKey, textures, groupPair.second->m_marksID, m_marks, batcher); + CacheUserLines(tileKey, textures, groupPair.second->m_linesID, m_lines, batcher); } } m_flushFn(std::move(renderData)); diff --git a/drape_frontend/user_mark_generator.hpp b/drape_frontend/user_mark_generator.hpp index 972c90019d..eb1c10674d 100644 --- a/drape_frontend/user_mark_generator.hpp +++ b/drape_frontend/user_mark_generator.hpp @@ -13,17 +13,9 @@ namespace df { using GroupID = size_t; -using MarkGroups = std::map>; -using LineGroups = std::map>; -struct IndexesCollection -{ - MarkIndexesCollection m_markIndexes; - LineIndexesCollection m_lineIndexes; -}; - -using MarkIndexesGroups = std::map>; -using MarksIndex = std::map>; +using MarksIDGroups = std::map>; +using MarksIndex = std::map>; class UserMarkGenerator { @@ -32,28 +24,30 @@ public: UserMarkGenerator(TFlushFn const & flushFn); - void SetUserMarks(GroupID groupId, drape_ptr && marks); - void SetUserLines(GroupID groupId, drape_ptr && lines); + void SetUserMarks(drape_ptr && marks); + void SetUserLines(drape_ptr && lines); - void ClearUserMarks(GroupID groupId); + void SetGroup(GroupID groupId, drape_ptr && ids); + void RemoveGroup(GroupID groupId); + void RemoveUserMarks(IDCollection && ids); void SetGroupVisibility(GroupID groupId, bool isVisible); void GenerateUserMarksGeometry(TileKey const & tileKey, ref_ptr textures); private: - void UpdateMarksIndex(GroupID groupId); - void UpdateLinesIndex(GroupID groupId); + void UpdateIndex(GroupID groupId); - ref_ptr GetIndexesCollection(TileKey const & tileKey, GroupID groupId); + ref_ptr GetIdCollection(TileKey const & tileKey, GroupID groupId); void CleanIndex(); std::unordered_set m_groupsVisibility; + MarksIDGroups m_groups; - MarkGroups m_marks; - LineGroups m_lines; + UserMarksRenderCollection m_marks; + UserLinesRenderCollection m_lines; - MarksIndex m_marksIndex; + MarksIndex m_index; TFlushFn m_flushFn; }; diff --git a/drape_frontend/user_mark_shapes.cpp b/drape_frontend/user_mark_shapes.cpp index 8980446030..c3df07d4c9 100644 --- a/drape_frontend/user_mark_shapes.cpp +++ b/drape_frontend/user_mark_shapes.cpp @@ -81,20 +81,24 @@ struct UserPointVertex : gpu::BaseVertex } // namespace void CacheUserMarks(TileKey const & tileKey, ref_ptr textures, - MarkIndexesCollection const & indexes, UserMarksRenderCollection & renderParams, + MarkIdCollection const & marksId, UserMarksRenderCollection & renderParams, dp::Batcher & batcher) { using UPV = UserPointVertex; - uint32_t const vertexCount = static_cast(indexes.size()) * dp::Batcher::VertexPerQuad; + uint32_t const vertexCount = static_cast(marksId.size()) * dp::Batcher::VertexPerQuad; buffer_vector buffer; buffer.reserve(vertexCount); dp::TextureManager::SymbolRegion region; - for (auto const markIndex : indexes) + for (auto const id : marksId) { - UserMarkRenderParams & renderInfo = renderParams[markIndex]; + auto const it = renderParams.find(id); + ASSERT(it != renderParams.end(), ()); + + UserMarkRenderParams & renderInfo = *it->second.get(); if (!renderInfo.m_isVisible) continue; + textures->GetSymbolRegion(renderInfo.m_symbolName, region); m2::RectF const & texRect = region.GetTexRect(); m2::PointF const pxSize = region.GetPixelSize(); @@ -130,7 +134,7 @@ void CacheUserMarks(TileKey const & tileKey, ref_ptr texture } void CacheUserLines(TileKey const & tileKey, ref_ptr textures, - LineIndexesCollection const & indexes, UserLinesRenderCollection & renderParams, + LineIdCollection const & linesId, UserLinesRenderCollection & renderParams, dp::Batcher & batcher) { float const vs = static_cast(df::VisualParams::Instance().GetVisualScale()); @@ -144,9 +148,11 @@ void CacheUserLines(TileKey const & tileKey, ref_ptr texture sqrScale = math::sqr(currentScaleGtoP); } - for (auto lineIndex : indexes) + for (auto id : linesId) { - UserLineRenderParams & renderInfo = renderParams[lineIndex]; + auto const it = renderParams.find(id); + ASSERT(it != renderParams.end(), ()); + UserLineRenderParams const & renderInfo = *it->second.get(); m2::SharedSpline spline = renderInfo.m_spline; if (simplify) diff --git a/drape_frontend/user_mark_shapes.hpp b/drape_frontend/user_mark_shapes.hpp index b9f22597cc..763e806de1 100644 --- a/drape_frontend/user_mark_shapes.hpp +++ b/drape_frontend/user_mark_shapes.hpp @@ -8,6 +8,7 @@ #include "geometry/spline.hpp" #include +#include namespace df { @@ -44,11 +45,17 @@ struct UserLineRenderParams m2::SharedSpline m_spline; }; -using UserMarksRenderCollection = std::vector; -using UserLinesRenderCollection = std::vector; +using UserMarksRenderCollection = std::unordered_map>; +using UserLinesRenderCollection = std::unordered_map>; -using MarkIndexesCollection = std::vector; -using LineIndexesCollection = std::vector; +using MarkIdCollection = std::vector; +using LineIdCollection = std::vector; + +struct IDCollection +{ + MarkIdCollection m_marksID; + LineIdCollection m_linesID; +}; struct UserMarkRenderData { @@ -66,10 +73,10 @@ struct UserMarkRenderData using TUserMarksRenderData = std::vector; void CacheUserMarks(TileKey const & tileKey, ref_ptr textures, - MarkIndexesCollection const & indexes, UserMarksRenderCollection & renderParams, + MarkIdCollection const & marksId, UserMarksRenderCollection & renderParams, dp::Batcher & batcher); void CacheUserLines(TileKey const & tileKey, ref_ptr textures, - LineIndexesCollection const & indexes, UserLinesRenderCollection & renderParams, + LineIdCollection const & linesId, UserLinesRenderCollection & renderParams, dp::Batcher & batcher); } // namespace df diff --git a/drape_frontend/user_marks_provider.cpp b/drape_frontend/user_marks_provider.cpp index 00b715ac17..f834358317 100644 --- a/drape_frontend/user_marks_provider.cpp +++ b/drape_frontend/user_marks_provider.cpp @@ -1,32 +1,40 @@ #include "user_marks_provider.hpp" -df::UserMarksProvider::UserMarksProvider() +namespace +{ +uint32_t GetNextUserMarkId() +{ + static uint32_t nextMarkId = 0; + return ++nextMarkId; +} +} // namespace + +namespace df +{ +UserPointMark::UserPointMark() + : m_id(GetNextUserMarkId()) +{ +} + + +UserLineMark::UserLineMark() + : m_id(GetNextUserMarkId()) +{ +} + +UserMarksProvider::UserMarksProvider() : m_pendingOnDelete(false) { } -bool df::UserMarksProvider::IsDirty() const -{ - return m_isDirty; -} - -void df::UserMarksProvider::ResetDirty() -{ - m_isDirty = false; -} - -bool df::UserMarksProvider::IsPendingOnDelete() +bool UserMarksProvider::IsPendingOnDelete() { return m_pendingOnDelete; } -void df::UserMarksProvider::DeleteLater() +void UserMarksProvider::DeleteLater() { ASSERT(m_pendingOnDelete == false, ()); m_pendingOnDelete = true; } - -void df::UserMarksProvider::SetDirty() -{ - m_isDirty = true; -} +} // namespace df diff --git a/drape_frontend/user_marks_provider.hpp b/drape_frontend/user_marks_provider.hpp index 711a832072..b5dbd72987 100644 --- a/drape_frontend/user_marks_provider.hpp +++ b/drape_frontend/user_marks_provider.hpp @@ -15,7 +15,14 @@ namespace df class UserPointMark { public: + UserPointMark(); virtual ~UserPointMark() {} + + virtual bool IsDirty() const = 0; + virtual void AcceptChanges() const = 0; + + uint32_t GetId() const { return m_id; } + virtual m2::PointD const & GetPivot() const = 0; virtual m2::PointD GetPixelOffset() const = 0; virtual std::string GetSymbolName() const = 0; @@ -23,18 +30,30 @@ public: virtual float GetDepth() const = 0; virtual bool HasCreationAnimation() const = 0; virtual bool IsVisible() const { return true; } + +private: + uint32_t m_id; }; class UserLineMark { public: + UserLineMark(); virtual ~UserLineMark() {} + virtual bool IsDirty() const = 0; + virtual void AcceptChanges() const = 0; + + virtual uint32_t GetId() const { return m_id; } + virtual size_t GetLayerCount() const = 0; virtual dp::Color const & GetColor(size_t layerIndex) const = 0; virtual float GetWidth(size_t layerIndex) const = 0; virtual float GetLayerDepth(size_t layerIndex) const = 0; virtual std::vector const & GetPoints() const = 0; + +private: + uint32_t m_id; }; class UserMarksProvider @@ -43,7 +62,9 @@ public: UserMarksProvider(); virtual ~UserMarksProvider() {} - bool IsDirty() const; + virtual bool IsDirty() const = 0; + virtual void AcceptChanges(std::vector & removedMarks) = 0; + virtual bool IsDrawable() const = 0; virtual size_t GetUserPointCount() const = 0; @@ -57,12 +78,7 @@ public: bool IsPendingOnDelete(); void DeleteLater(); -protected: - void SetDirty(); - void ResetDirty(); - private: - bool m_isDirty = false; bool m_pendingOnDelete; }; diff --git a/map/track.hpp b/map/track.hpp index 2a9d21fed8..d232004e1b 100644 --- a/map/track.hpp +++ b/map/track.hpp @@ -34,6 +34,9 @@ public: explicit Track(PolylineD const & polyline, Params const & p); + bool IsDirty() const override { return m_isDirty; } + void AcceptChanges() const override { m_isDirty = false; } + string const & GetName() const; PolylineD const & GetPolyline() const { return m_polyline; } m2::RectD GetLimitRect() const; @@ -48,4 +51,5 @@ public: private: PolylineD m_polyline; Params m_params; + mutable bool m_isDirty = true; }; diff --git a/map/user_mark.cpp b/map/user_mark.cpp index fce1e5b56e..9dd194e775 100644 --- a/map/user_mark.cpp +++ b/map/user_mark.cpp @@ -43,6 +43,11 @@ UserMarkContainer const * UserMark::GetContainer() const return m_container; } +void UserMark::SetDirty() +{ + m_isDirty = true; +} + ms::LatLon UserMark::GetLatLon() const { return MercatorBounds::ToLatLon(m_ptOrg); @@ -63,6 +68,24 @@ UserMark::Type SearchMarkPoint::GetMarkType() const return UserMark::Type::SEARCH; } +void SearchMarkPoint::SetFoundFeature(FeatureID const & feature) +{ + SetDirty(); + m_foundFeatureID = feature; +} + +void SearchMarkPoint::SetMatchedName(string const & name) +{ + SetDirty(); + m_matchedName = name; +} + +void SearchMarkPoint::SetCustomSymbol(string const & symbol) +{ + SetDirty(); + m_customSymbol = symbol; +} + PoiMarkPoint::PoiMarkPoint(UserMarkContainer * container) : SearchMarkPoint(m2::PointD::Zero(), container) {} @@ -73,6 +96,7 @@ UserMark::Type PoiMarkPoint::GetMarkType() const void PoiMarkPoint::SetPtOrg(m2::PointD const & ptOrg) { + SetDirty(); m_ptOrg = ptOrg; } diff --git a/map/user_mark.hpp b/map/user_mark.hpp index 809de476f2..92a605d91e 100644 --- a/map/user_mark.hpp +++ b/map/user_mark.hpp @@ -35,6 +35,9 @@ public: UserMark(m2::PointD const & ptOrg, UserMarkContainer * container); virtual ~UserMark() {} + bool IsDirty() const override { return m_isDirty; } + void AcceptChanges() const override { m_isDirty = false; } + // df::UserPointMark overrides. m2::PointD const & GetPivot() const override; m2::PointD GetPixelOffset() const override; @@ -47,8 +50,13 @@ public: virtual Type GetMarkType() const = 0; protected: + void SetDirty(); + m2::PointD m_ptOrg; mutable UserMarkContainer * m_container; + +private: + mutable bool m_isDirty = true; }; enum SearchMarkType @@ -70,13 +78,13 @@ public: UserMark::Type GetMarkType() const override; FeatureID const & GetFoundFeature() const { return m_foundFeatureID; } - void SetFoundFeature(FeatureID const & feature) { m_foundFeatureID = feature; } + void SetFoundFeature(FeatureID const & feature); string const & GetMatchedName() const { return m_matchedName; } - void SetMatchedName(string const & name) { m_matchedName = name; } + void SetMatchedName(string const & name); string const & GetCustomSymbol() const { return m_customSymbol; } - void SetCustomSymbol(string const & symbol) { m_customSymbol = symbol; } + void SetCustomSymbol(string const & symbol); protected: FeatureID m_foundFeatureID; diff --git a/map/user_mark_container.cpp b/map/user_mark_container.cpp index b0be988eb2..8ba1b813a1 100644 --- a/map/user_mark_container.cpp +++ b/map/user_mark_container.cpp @@ -131,13 +131,12 @@ void UserMarkContainer::ReleaseController() if (GetUserPointCount() == 0 && GetUserLineCount() == 0) { + engine->UpdateUserMarksLayer(layerId, this); engine->ClearUserMarksLayer(layerId); - ResetDirty(); } else if (IsVisible() && IsDrawable()) { engine->UpdateUserMarksLayer(layerId, this); - ResetDirty(); } } @@ -233,22 +232,14 @@ void UserMarkContainer::Update() SetDirty(); } -namespace +void UserMarkContainer::SetDirty() { - -template void DeleteItem(vector & v, size_t i) -{ - if (i < v.size()) - { - delete v[i]; - v.erase(v.begin() + i); - } - else - { - LOG(LWARNING, ("Trying to delete non-existing item at index", i)); - } + m_isDirty = true; } +bool UserMarkContainer::IsDirty() const +{ + return m_isDirty; } void UserMarkContainer::DeleteUserMark(size_t index) @@ -256,11 +247,21 @@ void UserMarkContainer::DeleteUserMark(size_t index) SetDirty(); ASSERT_LESS(index, m_userMarks.size(), ()); if (index < m_userMarks.size()) + { + m_removedMarks.push_back(m_userMarks[index]->GetId()); m_userMarks.erase(m_userMarks.begin() + index); + } else LOG(LWARNING, ("Trying to delete non-existing item at index", index)); } +void UserMarkContainer::AcceptChanges(std::vector & removedMarks) +{ + removedMarks.swap(m_removedMarks); + m_removedMarks.clear(); + m_isDirty = false; +} + SearchUserMarkContainer::SearchUserMarkContainer(double layerDepth, Framework & framework) : UserMarkContainer(layerDepth, UserMarkType::SEARCH_MARK, framework) { diff --git a/map/user_mark_container.hpp b/map/user_mark_container.hpp index 860fea50a2..b77193da6b 100644 --- a/map/user_mark_container.hpp +++ b/map/user_mark_container.hpp @@ -71,6 +71,9 @@ public: size_t GetUserLineCount() const override; df::UserLineMark const * GetUserLineMark(size_t index) const override; + bool IsDirty() const override; + void AcceptChanges(std::vector & removedMarks) override; + float GetPointDepth() const; bool IsVisible() const; @@ -89,6 +92,8 @@ protected: void SetIsVisible(bool isVisible) override; void Update() override; + void SetDirty(); + virtual UserMark * AllocateUserMark(m2::PointD const & ptOrg) = 0; Framework & m_framework; @@ -98,6 +103,8 @@ private: double m_layerDepth; TUserMarksList m_userMarks; UserMarkType m_type; + std::vector m_removedMarks; + bool m_isDirty = false; }; class SearchUserMarkContainer : public UserMarkContainer