Notification via BookmarkManager.

This commit is contained in:
Daria Volvenkova 2018-02-07 13:01:07 +03:00 committed by Roman Kuznetsov
parent 56f9dec716
commit f403f41296
17 changed files with 340 additions and 247 deletions

View file

@ -221,83 +221,99 @@ void DrapeEngine::InvalidateUserMarks()
MessagePriority::Normal);
}
void DrapeEngine::UpdateUserMarksGroup(MarkGroupID groupId, UserMarksProvider * provider)
void DrapeEngine::UpdateUserMarks(UserMarksProvider * provider)
{
auto const & groupMarkIds = provider->GetPointMarkIds(groupId);
auto groupIdCollection = make_unique_dp<MarkIDCollection>();
groupIdCollection->m_marksID.reserve(groupMarkIds.size());
auto const & dirtyGroupIds = provider->GetDirtyGroupIds();
if (dirtyGroupIds.empty())
return;
auto marksRenderCollection = make_unique_dp<UserMarksRenderCollection>();
marksRenderCollection->reserve(groupMarkIds.size());
for (auto markId : groupMarkIds)
{
groupIdCollection->m_marksID.push_back(markId);
UserPointMark const * mark = provider->GetUserPointMark(markId);
if (mark->IsDirty())
{
auto renderInfo = make_unique_dp<UserMarkRenderParams>();
renderInfo->m_anchor = mark->GetAnchor();
renderInfo->m_depth = mark->GetDepth();
renderInfo->m_depthLayer = mark->GetDepthLayer();
renderInfo->m_minZoom = mark->GetMinZoom();
renderInfo->m_minTitleZoom = mark->GetMinTitleZoom();
renderInfo->m_isVisible = mark->IsVisible();
renderInfo->m_pivot = mark->GetPivot();
renderInfo->m_pixelOffset = mark->GetPixelOffset();
renderInfo->m_titleDecl = mark->GetTitleDecl();
renderInfo->m_symbolNames = mark->GetSymbolNames();
renderInfo->m_coloredSymbols = mark->GetColoredSymbols();
renderInfo->m_symbolSizes = mark->GetSymbolSizes();
renderInfo->m_symbolOffsets = mark->GetSymbolOffsets();
renderInfo->m_hasSymbolPriority = mark->HasSymbolPriority();
renderInfo->m_hasTitlePriority = mark->HasTitlePriority();
renderInfo->m_priority = mark->GetPriority();
renderInfo->m_index = mark->GetIndex();
renderInfo->m_featureId = mark->GetFeatureID();
renderInfo->m_hasCreationAnimation = mark->HasCreationAnimation();
marksRenderCollection->emplace(mark->GetId(), std::move(renderInfo));
mark->ResetChanges();
}
}
auto const & lineIds = provider->GetLineMarkIds(groupId);
auto linesRenderCollection = make_unique_dp<UserLinesRenderCollection>();
linesRenderCollection->reserve(lineIds.size());
for (auto lineId : lineIds)
{
UserLineMark const * mark = provider->GetUserLineMark(lineId);
if (mark->IsDirty())
{
auto renderInfo = make_unique_dp<UserLineRenderParams>();
renderInfo->m_minZoom = mark->GetMinZoom();
renderInfo->m_depthLayer = mark->GetDepthLayer();
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->GetDepth(layerIndex));
}
auto createdIdCollection = make_unique_dp<MarkIDCollection>();
auto removedIdCollection = make_unique_dp<MarkIDCollection>();
linesRenderCollection->emplace(mark->GetId(), std::move(renderInfo));
mark->ResetChanges();
df::MarkGroupID lastGroupId = *dirtyGroupIds.begin();
bool visibilityChanged = provider->IsGroupVisiblityChanged(lastGroupId);
bool groupIsVisible = provider->IsGroupVisible(lastGroupId);
auto const HandleMark = [&](
df::MarkID markId,
UserMarksRenderCollection & renderCollection,
IDCollection * idCollection)
{
auto const * mark = provider->GetUserPointMark(markId);
if (!mark->IsDirty())
return;
auto const groupId = mark->GetGroupId();
if (groupId != lastGroupId)
{
lastGroupId = groupId;
visibilityChanged = provider->IsGroupVisiblityChanged(groupId);
groupIsVisible = provider->IsGroupVisible(groupId);
}
if (!visibilityChanged && groupIsVisible)
{
if (idCollection)
idCollection->push_back(markId);
renderCollection.emplace(markId, GenerateMarkRenderInfo(mark));
}
};
for (auto markId : provider->GetCreatedMarkIds())
HandleMark(markId, *marksRenderCollection, &createdIdCollection->m_marksID);
for (auto markId : provider->GetUpdatedMarkIds())
HandleMark(markId, *marksRenderCollection, nullptr);
auto const & removedMarkIds = provider->GetRemovedMarkIds();
removedIdCollection->m_marksID.reserve(removedMarkIds.size());
removedIdCollection->m_marksID.assign(removedMarkIds.begin(), removedMarkIds.end());
std::map<df::MarkGroupID, drape_ptr<MarkIDCollection>> dirtyMarkIds;
for (auto groupId : dirtyGroupIds)
{
auto & idCollection = *(dirtyMarkIds.emplace(groupId, make_unique_dp<MarkIDCollection>()).first->second);
visibilityChanged = provider->IsGroupVisiblityChanged(groupId);
groupIsVisible = provider->IsGroupVisible(groupId);
if (!groupIsVisible && !visibilityChanged)
continue;
auto const & markIds = provider->GetGroupPointIds(groupId);
auto const & lineIds = provider->GetGroupLineIds(groupId);
if (groupIsVisible)
{
idCollection.m_marksID.reserve(markIds.size());
idCollection.m_marksID.assign(markIds.begin(), markIds.end());
idCollection.m_linesID.reserve(lineIds.size());
idCollection.m_linesID.assign(lineIds.begin(), lineIds.end());
for (auto lineId : lineIds)
{
auto const * line = provider->GetUserLineMark(lineId);
if (visibilityChanged || line->IsDirty())
linesRenderCollection->emplace(lineId, GenerateLineRenderInfo(line));
}
if (visibilityChanged)
{
for (auto markId : markIds)
marksRenderCollection->emplace(
markId, GenerateMarkRenderInfo(provider->GetUserPointMark(markId)));
}
}
else
{
auto & points = removedIdCollection->m_marksID;
points.reserve(points.size() + markIds.size());
points.insert(points.end(), markIds.begin(), markIds.end());
auto & lines = removedIdCollection->m_linesID;
lines.reserve(lines.size() + lineIds.size());
lines.insert(lines.end(), lineIds.begin(), lineIds.end());
}
}
auto const & createdIds = provider->GetCreatedMarkIds(groupId);
auto const & removedIds = provider->GetRemovedMarkIds(groupId);
if (!createdIds.empty() || !removedIds.empty() ||
!marksRenderCollection->empty() || !linesRenderCollection->empty())
if (!marksRenderCollection->empty() || !linesRenderCollection->empty()
|| !removedIdCollection->IsEmpty() || !createdIdCollection->IsEmpty())
{
auto createdIdCollection = make_unique_dp<MarkIDCollection>();
createdIdCollection->m_marksID.reserve(createdIds.size());
createdIdCollection->m_marksID.assign(createdIds.begin(), createdIds.end());
auto removedIdCollection = make_unique_dp<MarkIDCollection>();
removedIdCollection->m_marksID.reserve(removedIds.size());
removedIdCollection->m_marksID.assign(removedIds.begin(), removedIds.end());
m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<UpdateUserMarksMessage>(
std::move(createdIdCollection),
@ -307,11 +323,14 @@ void DrapeEngine::UpdateUserMarksGroup(MarkGroupID groupId, UserMarksProvider *
MessagePriority::Normal);
}
m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<UpdateUserMarkGroupMessage>(
groupId,
std::move(groupIdCollection)),
MessagePriority::Normal);
for (auto & v : dirtyMarkIds)
{
m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<UpdateUserMarkGroupMessage>(
v.first,
std::move(v.second)),
MessagePriority::Normal);
}
}
void DrapeEngine::SetRenderingEnabled(ref_ptr<dp::OGLContextFactory> contextFactory)
@ -764,4 +783,46 @@ void DrapeEngine::RunFirstLaunchAnimation()
make_unique_dp<RunFirstLaunchAnimationMessage>(),
MessagePriority::Normal);
}
drape_ptr<UserMarkRenderParams> DrapeEngine::GenerateMarkRenderInfo(UserPointMark const * mark)
{
auto renderInfo = make_unique_dp<UserMarkRenderParams>();
renderInfo->m_anchor = mark->GetAnchor();
renderInfo->m_depth = mark->GetDepth();
renderInfo->m_depthLayer = mark->GetDepthLayer();
renderInfo->m_minZoom = mark->GetMinZoom();
renderInfo->m_minTitleZoom = mark->GetMinTitleZoom();
renderInfo->m_isVisible = mark->IsVisible();
renderInfo->m_pivot = mark->GetPivot();
renderInfo->m_pixelOffset = mark->GetPixelOffset();
renderInfo->m_titleDecl = mark->GetTitleDecl();
renderInfo->m_symbolNames = mark->GetSymbolNames();
renderInfo->m_coloredSymbols = mark->GetColoredSymbols();
renderInfo->m_symbolSizes = mark->GetSymbolSizes();
renderInfo->m_symbolOffsets = mark->GetSymbolOffsets();
renderInfo->m_hasSymbolPriority = mark->HasSymbolPriority();
renderInfo->m_hasTitlePriority = mark->HasTitlePriority();
renderInfo->m_priority = mark->GetPriority();
renderInfo->m_index = mark->GetIndex();
renderInfo->m_featureId = mark->GetFeatureID();
renderInfo->m_hasCreationAnimation = mark->HasCreationAnimation();
return renderInfo;
}
drape_ptr<UserLineRenderParams> DrapeEngine::GenerateLineRenderInfo(UserLineMark const * mark)
{
auto renderInfo = make_unique_dp<UserLineRenderParams>();
renderInfo->m_minZoom = mark->GetMinZoom();
renderInfo->m_depthLayer = mark->GetDepthLayer();
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->GetDepth(layerIndex));
}
return renderInfo;
}
} // namespace df

View file

@ -133,7 +133,7 @@ public:
void ClearUserMarksGroup(size_t layerId);
void ChangeVisibilityUserMarksGroup(MarkGroupID groupId, bool isVisible);
void UpdateUserMarksGroup(MarkGroupID groupId, UserMarksProvider * provider);
void UpdateUserMarks(UserMarksProvider * provider);
void InvalidateUserMarks();
void SetRenderingEnabled(ref_ptr<dp::OGLContextFactory> contextFactory = nullptr);
@ -228,6 +228,9 @@ private:
dp::DrapeID GenerateDrapeID();
static drape_ptr<UserMarkRenderParams> GenerateMarkRenderInfo(UserPointMark const * mark);
static drape_ptr<UserLineRenderParams> GenerateLineRenderInfo(UserLineMark const * mark);
drape_ptr<FrontendRenderer> m_frontend;
drape_ptr<BackendRenderer> m_backend;
drape_ptr<ThreadsCommutator> m_threadCommutator;

View file

@ -8,5 +8,7 @@ namespace df
using MarkID = uint32_t;
using MarkGroupID = size_t;
using IDCollection = std::vector<MarkID>;
using MarkIDSet = std::set<df::MarkID>;
using MarkIDSet = std::set<MarkID>;
using GroupIDList = std::vector<MarkGroupID>;
using GroupIDSet = std::set<MarkGroupID>;
} // namespace df

View file

@ -48,6 +48,7 @@ public:
virtual void ResetChanges() const = 0;
MarkID GetId() const { return m_id; }
virtual df::MarkGroupID GetGroupId() const = 0;
virtual m2::PointD const & GetPivot() const = 0;
virtual m2::PointD GetPixelOffset() const = 0;
@ -100,13 +101,17 @@ class UserMarksProvider
{
public:
virtual ~UserMarksProvider() {}
virtual MarkIDSet const & GetPointMarkIds(MarkGroupID groupID) const = 0;
virtual MarkIDSet const & GetLineMarkIds(MarkGroupID groupID) const = 0;
virtual MarkIDSet const & GetCreatedMarkIds(MarkGroupID groupID) const = 0;
virtual MarkIDSet const & GetRemovedMarkIds(MarkGroupID groupID) const = 0;
/// never store UserPointMark reference
virtual GroupIDSet const & GetDirtyGroupIds() const = 0;
virtual bool IsGroupVisible(MarkGroupID groupID) const = 0;
virtual bool IsGroupVisiblityChanged(MarkGroupID groupID) const = 0;
virtual MarkIDSet const & GetGroupPointIds(MarkGroupID groupID) const = 0;
virtual MarkIDSet const & GetGroupLineIds(MarkGroupID groupID) const = 0;
virtual MarkIDSet const & GetCreatedMarkIds() const = 0;
virtual MarkIDSet const & GetRemovedMarkIds() const = 0;
virtual MarkIDSet const & GetUpdatedMarkIds() const = 0;
/// Never store UserPointMark reference.
virtual UserPointMark const * GetUserPointMark(MarkID markID) const = 0;
/// never store UserLineMark reference
/// Never store UserLineMark reference.
virtual UserLineMark const * GetUserLineMark(MarkID markID) const = 0;
};

View file

@ -307,7 +307,7 @@ extern NSString * const kBookmarkDeletedNotification = @"BookmarkDeletedNotifica
NSValue * value = [NSValue valueWithBytes:&bmId objCType:@encode(df::MarkID*)];
[NSNotificationCenter.defaultCenter postNotificationName:kBookmarkDeletedNotification
object:value];
bmManager.DeleteUserMark(bmId);
bmManager.DeleteBookmark(bmId);
[m_bookmarkIds removeObjectAtIndex:indexPath.row];
[NSNotificationCenter.defaultCenter postNotificationName:kBookmarksChangedNotification
object:nil

View file

@ -51,7 +51,7 @@ static NSString * const kKeyPath = @"subviews";
Framework & f = GetFramework();
f.DeactivateMapSelection(true);
auto & bmManager = f.GetBookmarkManager();
bmManager.ClearUserMarks(UserMark::Type::API);
bmManager.ClearGroup(UserMark::Type::API);
bmManager.NotifyChanges(UserMark::Type::API);
NSURL * url = [NSURL URLWithString:@(f.GetApiDataHolder().GetGlobalBackUrl().c_str())];
[UIApplication.sharedApplication openURL:url];

View file

@ -150,24 +150,15 @@ BookmarkCategory::BookmarkCategory(std::string const & name,
BookmarkCategory::~BookmarkCategory()
{
ClearTracks();
}
void BookmarkCategory::ClearTracks()
{
SetDirty();
m_tracks.clear();
}
void BookmarkCategory::AttachTrack(df::MarkID trackId)
{
SetDirty();
m_tracks.insert(trackId);
}
void BookmarkCategory::DetachTrack(df::MarkID trackId)
{
SetDirty();
m_tracks.erase(trackId);
}

View file

@ -133,8 +133,6 @@ public:
std::string const & GetFileName() const { return m_file; }
private:
void ClearTracks();
const df::MarkGroupID m_groupID;
std::string m_name;
// Stores file name from which bookmarks were loaded.

View file

@ -154,6 +154,14 @@ BookmarkManager::~BookmarkManager()
////////////////////////////
UserMark const * BookmarkManager::GetMark(df::MarkID markID) const
{
auto const * userMark = GetUserMark(markID);
if (userMark != nullptr)
return userMark;
return static_cast<UserMark const *>(GetBookmark(markID));
}
UserMark const * BookmarkManager::GetUserMark(df::MarkID markID) const
{
auto it = m_userMarks.find(markID);
@ -165,8 +173,7 @@ UserMark * BookmarkManager::GetUserMarkForEdit(df::MarkID markID)
auto it = m_userMarks.find(markID);
if (it == m_userMarks.end())
return nullptr;
auto const groupId = static_cast<df::MarkGroupID>(it->second->GetMarkType());
m_userMarkLayers[groupId]->EditUserMark(markID);
m_updatedMarks.insert(markID);
return it->second.get();
}
@ -175,6 +182,11 @@ void BookmarkManager::DeleteUserMark(df::MarkID markId)
auto it = m_userMarks.find(markId);
auto const groupId = it->second->GetGroupId();
FindContainer(groupId)->DetachUserMark(markId);
auto const mit = m_createdMarks.find(markId);
if (mit != m_createdMarks.end())
m_createdMarks.erase(mit);
else
m_removedMarks.insert(markId);
m_userMarks.erase(it);
}
@ -216,7 +228,9 @@ Bookmark * BookmarkManager::GetBookmarkForEdit(df::MarkID markID)
return nullptr;
auto const groupId = it->second->GetGroupId();
if (groupId)
GetBmCategory(groupId)->EditUserMark(markID);
{
m_updatedMarks.insert(markID);
}
return it->second.get();
}
@ -234,11 +248,18 @@ void BookmarkManager::DetachBookmark(df::MarkID bmId, df::MarkGroupID catID)
void BookmarkManager::DeleteBookmark(df::MarkID bmId)
{
auto it = m_bookmarks.find(bmId);
auto const groupID = it->second->GetGroupId();
auto groupIt = m_bookmarks.find(bmId);
auto const groupID = groupIt->second->GetGroupId();
if (groupID)
{
auto const it = m_createdMarks.find(bmId);
if (it != m_createdMarks.end())
m_createdMarks.erase(it);
else
m_removedMarks.insert(bmId);
FindContainer(groupID)->DetachUserMark(bmId);
m_bookmarks.erase(it);
}
m_bookmarks.erase(groupIt);
}
Track * BookmarkManager::CreateTrack(m2::PolylineD const & polyline, Track::Params const & p)
@ -273,39 +294,71 @@ void BookmarkManager::DeleteTrack(df::MarkID trackID)
m_tracks.erase(it);
}
void BookmarkManager::NotifyChanges(df::MarkGroupID groupId)
void BookmarkManager::FindDirtyGroups()
{
auto * group = FindContainer(groupId);
if (!group->IsDirty())
return;
if (IsBookmark(groupId))
m_dirtyGroups.clear();
for (auto const & group : m_userMarkLayers)
{
OnCreateUserMarks(*group);
OnUpdateUserMarks(*group);
OnDeleteUserMarks(*group);
if (!group->IsDirty())
continue;
auto const groupId = static_cast<df::MarkGroupID>(group->GetType());
m_dirtyGroups.insert(groupId);
}
for (auto const & group : m_categories)
{
if (!group.second->IsDirty())
continue;
m_dirtyGroups.insert(group.first);
}
for (auto const markId : m_updatedMarks)
{
auto const * mark = GetMark(markId);
if (mark->IsDirty())
m_dirtyGroups.insert(mark->GetGroupId());
}
}
void BookmarkManager::NotifyChanges(df::MarkGroupID)
{
FindDirtyGroups();
if (m_dirtyGroups.empty())
return;
df::DrapeEngineLockGuard lock(m_drapeEngine);
if (!lock)
return;
bool isBookmarks = false;
auto engine = lock.Get();
engine->ChangeVisibilityUserMarksGroup(groupId, group->IsVisible());
if (group->GetUserMarks().empty() && group->GetUserLines().empty())
for (auto groupId : m_dirtyGroups)
{
engine->UpdateUserMarksGroup(groupId, this);
engine->ClearUserMarksGroup(groupId);
isBookmarks |= IsBookmark(groupId);
auto * group = FindContainer(groupId);
engine->ChangeVisibilityUserMarksGroup(groupId, group->IsVisible());
}
else if (group->IsVisible())
engine->UpdateUserMarks(this);
for (auto groupId : m_dirtyGroups)
{
engine->UpdateUserMarksGroup(groupId, this);
auto * group = FindContainer(groupId);
if (group->GetUserMarks().empty() && group->GetUserLines().empty())
engine->ClearUserMarksGroup(groupId);
group->ResetChanges();
}
engine->InvalidateUserMarks();
group->ResetChanges();
if (isBookmarks)
SendBookmarksChanges();
for (auto const markId : m_updatedMarks)
GetMark(markId)->ResetChanges();
m_dirtyGroups.clear();
m_createdMarks.clear();
m_removedMarks.clear();
m_updatedMarks.clear();
}
df::MarkIDSet const & BookmarkManager::GetUserMarkIds(df::MarkGroupID groupID) const
@ -318,16 +371,23 @@ df::MarkIDSet const & BookmarkManager::GetTrackIds(df::MarkGroupID groupID) cons
return FindContainer(groupID)->GetUserLines();
}
void BookmarkManager::ClearUserMarks(df::MarkGroupID groupId)
void BookmarkManager::ClearGroup(df::MarkGroupID groupId)
{
auto * group = FindContainer(groupId);
for (auto markId : group->GetUserMarks())
{
auto const it = m_createdMarks.find(markId);
if (it == m_createdMarks.end())
m_removedMarks.insert(markId);
else
m_createdMarks.erase(it);
if (IsBookmark(groupId))
m_bookmarks.erase(markId);
else
m_userMarks.erase(markId);
}
for (auto trackId : group->GetUserLines())
m_tracks.erase(trackId);
group->Clear();
}
@ -366,14 +426,14 @@ UserMark const * BookmarkManager::FindMarkInRect(df::MarkGroupID groupID, m2::An
return mark;
}
void BookmarkManager::SetIsVisible(df::MarkGroupID categoryId, bool visible)
void BookmarkManager::SetIsVisible(df::MarkGroupID groupId, bool visible)
{
return FindContainer(categoryId)->SetIsVisible(visible);
return FindContainer(groupId)->SetIsVisible(visible);
}
bool BookmarkManager::IsVisible(df::MarkGroupID categoryId) const
bool BookmarkManager::IsVisible(df::MarkGroupID groupId) const
{
return FindContainer(categoryId)->IsVisible();
return FindContainer(groupId)->IsVisible();
}
////////////////////////////
@ -404,6 +464,7 @@ Bookmark * BookmarkManager::AddBookmark(std::unique_ptr<Bookmark> && bookmark)
auto const markId = bm->GetId();
ASSERT(m_bookmarks.count(markId) == 0, ());
m_bookmarks.emplace(markId, std::move(bookmark));
m_createdMarks.insert(markId);
return bm;
}
@ -617,7 +678,6 @@ void BookmarkManager::MoveBookmark(df::MarkID bmID, df::MarkGroupID curGroupID,
{
DetachBookmark(bmID, curGroupID);
SaveToKMLFile(curGroupID);
NotifyChanges(curGroupID);
AttachBookmark(bmID, newGroupID);
}
@ -659,36 +719,25 @@ BookmarkCategory * BookmarkManager::GetBmCategory(df::MarkGroupID categoryId) co
return (it != m_categories.end() ? it->second.get() : 0);
}
void BookmarkManager::OnCreateUserMarks(UserMarkContainer const & container)
void BookmarkManager::SendBookmarksChanges()
{
if (m_callbacks.m_createdBookmarksCallback == nullptr)
return;
std::vector<std::pair<df::MarkID, BookmarkData>> marksInfo;
GetBookmarksData(container.GetCreatedMarks(), marksInfo);
m_callbacks.m_createdBookmarksCallback(marksInfo);
}
void BookmarkManager::OnUpdateUserMarks(UserMarkContainer const & container)
{
if (m_callbacks.m_updatedBookmarksCallback == nullptr)
return;
std::vector<std::pair<df::MarkID, BookmarkData>> marksInfo;
GetBookmarksData(container.GetUpdatedMarks(), marksInfo);
m_callbacks.m_updatedBookmarksCallback(marksInfo);
}
void BookmarkManager::OnDeleteUserMarks(UserMarkContainer const & container)
{
if (m_callbacks.m_deletedBookmarksCallback == nullptr)
return;
auto const & removedIds = container.GetRemovedMarks();
df::IDCollection idCollection(removedIds.begin(), removedIds.end());
m_callbacks.m_deletedBookmarksCallback(idCollection);
if (m_callbacks.m_createdBookmarksCallback != nullptr)
{
std::vector<std::pair<df::MarkID, BookmarkData>> marksInfo;
GetBookmarksData(m_createdMarks, marksInfo);
m_callbacks.m_createdBookmarksCallback(marksInfo);
}
if (m_callbacks.m_updatedBookmarksCallback != nullptr)
{
std::vector<std::pair<df::MarkID, BookmarkData>> marksInfo;
GetBookmarksData(m_updatedMarks, marksInfo);
m_callbacks.m_updatedBookmarksCallback(marksInfo);
}
if (m_callbacks.m_deletedBookmarksCallback != nullptr)
{
df::IDCollection idCollection(m_removedMarks.begin(), m_removedMarks.end());
m_callbacks.m_deletedBookmarksCallback(idCollection);
}
}
void BookmarkManager::GetBookmarksData(df::MarkIDSet const & markIds,
@ -699,8 +748,8 @@ void BookmarkManager::GetBookmarksData(df::MarkIDSet const & markIds,
for (auto markId : markIds)
{
auto const * bookmark = GetBookmark(markId);
ASSERT(bookmark != nullptr, ());
data.push_back(std::make_pair(markId, bookmark->GetData()));
if (bookmark)
data.push_back(std::make_pair(markId, bookmark->GetData()));
}
}
@ -728,11 +777,7 @@ bool BookmarkManager::DeleteBmCategory(df::MarkGroupID groupID)
// TODO(darina): check the necessity of DeleteLater
// cat.DeleteLater();
FileWriter::DeleteFileX(group.GetFileName());
for (auto markId : group.GetUserMarks())
m_bookmarks.erase(markId);
for (auto trackId : group.GetUserLines())
m_tracks.erase(trackId);
it->second->Clear();
ClearGroup(groupID);
NotifyChanges(groupID);
m_categories.erase(it);
m_bmGroupsIdList.erase(std::remove(m_bmGroupsIdList.begin(), m_bmGroupsIdList.end(), groupID),
@ -812,24 +857,44 @@ UserMarkContainer * BookmarkManager::FindContainer(df::MarkGroupID containerId)
}
}
df::MarkIDSet const & BookmarkManager::GetPointMarkIds(df::MarkGroupID groupId) const
df::GroupIDSet const & BookmarkManager::GetDirtyGroupIds() const
{
return m_dirtyGroups;
}
bool BookmarkManager::IsGroupVisible(df::MarkGroupID groupID) const
{
return IsVisible(groupID);
}
bool BookmarkManager::IsGroupVisiblityChanged(df::MarkGroupID groupID) const
{
return FindContainer(groupID)->IsVisibilityChanged();
}
df::MarkIDSet const & BookmarkManager::GetGroupPointIds(df::MarkGroupID groupId) const
{
return GetUserMarkIds(groupId);
}
df::MarkIDSet const & BookmarkManager::GetLineMarkIds(df::MarkGroupID groupId) const
df::MarkIDSet const & BookmarkManager::GetGroupLineIds(df::MarkGroupID groupId) const
{
return GetTrackIds(groupId);
}
df::MarkIDSet const & BookmarkManager::GetCreatedMarkIds(df::MarkGroupID groupId) const
df::MarkIDSet const & BookmarkManager::GetCreatedMarkIds() const
{
return FindContainer(groupId)->GetCreatedMarks();
return m_createdMarks;
}
df::MarkIDSet const & BookmarkManager::GetRemovedMarkIds(df::MarkGroupID groupId) const
df::MarkIDSet const & BookmarkManager::GetRemovedMarkIds() const
{
return FindContainer(groupId)->GetRemovedMarks();
return m_removedMarks;
}
df::MarkIDSet const & BookmarkManager::GetUpdatedMarkIds() const
{
return m_updatedMarks;
}
df::UserPointMark const * BookmarkManager::GetUserPointMark(df::MarkID markID) const

View file

@ -80,6 +80,7 @@ public:
ASSERT(m_userMarks.count(markId) == 0, ());
ASSERT_LESS(groupId, m_userMarkLayers.size(), ());
m_userMarks.emplace(markId, std::move(mark));
m_createdMarks.insert(markId);
m_userMarkLayers[groupId]->AttachUserMark(markId);
return m;
}
@ -133,7 +134,7 @@ public:
void DeleteTrack(df::MarkID trackID);
//////////////////
void ClearUserMarks(df::MarkGroupID groupID);
void ClearGroup(df::MarkGroupID groupID);
void NotifyChanges(df::MarkGroupID groupID);
@ -143,10 +144,10 @@ public:
std::string const & GetCategoryName(df::MarkGroupID categoryId) const;
void SetCategoryName(df::MarkGroupID categoryId, std::string const & name);
UserMark const * FindMarkInRect(df::MarkGroupID categoryId, m2::AnyRectD const & rect, double & d) const;
UserMark const * FindMarkInRect(df::MarkGroupID groupId, m2::AnyRectD const & rect, double & d) const;
void SetIsVisible(df::MarkGroupID categoryId, bool visible);
bool IsVisible(df::MarkGroupID categoryId) const;
void SetIsVisible(df::MarkGroupID groupId, bool visible);
bool IsVisible(df::MarkGroupID groupId) const;
/// Uses the same file name from which was loaded, or
/// creates unique file name on first save and uses it every time.
@ -200,10 +201,14 @@ public:
bool IsAsyncLoadingInProgress() const { return m_asyncLoadingInProgress; }
// UserMarksProvider
df::MarkIDSet const & GetPointMarkIds(df::MarkGroupID groupId) const override;
df::MarkIDSet const & GetLineMarkIds(df::MarkGroupID groupId) const override;
df::MarkIDSet const & GetCreatedMarkIds(df::MarkGroupID groupId) const override;
df::MarkIDSet const & GetRemovedMarkIds(df::MarkGroupID groupId) const override;
df::GroupIDSet const & GetDirtyGroupIds() const override;
bool IsGroupVisible(df::MarkGroupID groupID) const override;
bool IsGroupVisiblityChanged(df::MarkGroupID groupID) const override;
df::MarkIDSet const & GetGroupPointIds(df::MarkGroupID groupId) const override;
df::MarkIDSet const & GetGroupLineIds(df::MarkGroupID groupId) const override;
df::MarkIDSet const & GetCreatedMarkIds() const override;
df::MarkIDSet const & GetRemovedMarkIds() const override;
df::MarkIDSet const & GetUpdatedMarkIds() const override;
df::UserPointMark const * GetUserPointMark(df::MarkID markID) const override;
df::UserLineMark const * GetUserLineMark(df::MarkID markID) const override;
@ -211,6 +216,8 @@ private:
using KMLDataCollection = std::vector<std::unique_ptr<KMLData>>;
bool IsBookmark(df::MarkGroupID groupId) const { return groupId >= UserMark::BOOKMARK; }
UserMark const * GetMark(df::MarkID markID) const;
void FindDirtyGroups();
UserMarkContainer const * FindContainer(df::MarkGroupID containerId) const;
UserMarkContainer * FindContainer(df::MarkGroupID containerId);
@ -228,9 +235,7 @@ private:
void NotifyAboutFile(bool success, std::string const & filePath, bool isTemporaryFile);
void LoadBookmarkRoutine(std::string const & filePath, bool isTemporaryFile);
void OnCreateUserMarks(UserMarkContainer const & container);
void OnUpdateUserMarks(UserMarkContainer const & container);
void OnDeleteUserMarks(UserMarkContainer const & container);
void SendBookmarksChanges();
void GetBookmarksData(df::MarkIDSet const & markIds,
std::vector<std::pair<df::MarkID, BookmarkData>> & data) const;
@ -245,19 +250,21 @@ private:
ScreenBase m_viewport;
CategoriesCollection m_categories;
GroupIdList m_bmGroupsIdList;
df::GroupIDList m_bmGroupsIdList;
df::GroupIDSet m_dirtyGroups;
std::string m_lastCategoryUrl;
std::string m_lastType;
UserMarkLayers m_userMarkLayers;
uint64_t m_generation;
MarksCollection m_userMarks;
BookmarksCollection m_bookmarks;
TracksCollection m_tracks;
df::MarkIDSet m_createdMarks;
df::MarkIDSet m_removedMarks;
df::MarkIDSet m_updatedMarks;
StaticMarkPoint* m_selectionMark;
MyPositionMarkPoint* m_myPositionMark;
StaticMarkPoint * m_selectionMark = nullptr;
MyPositionMarkPoint * m_myPositionMark = nullptr;
bool m_asyncLoadingInProgress = false;
struct BookmarkLoaderInfo

View file

@ -1605,7 +1605,7 @@ void Framework::FillSearchResultsMarks(bool clear, search::Results::ConstIter be
{
auto & bmManager = GetBookmarkManager();
if (clear)
bmManager.ClearUserMarks(UserMark::Type::SEARCH);
bmManager.ClearGroup(UserMark::Type::SEARCH);
bmManager.SetIsVisible(UserMark::Type::SEARCH, true);
for (auto it = begin; it != end; ++it)
@ -1637,7 +1637,7 @@ void Framework::FillSearchResultsMarks(bool clear, search::Results::ConstIter be
void Framework::ClearSearchResultsMarks()
{
GetBookmarkManager().ClearUserMarks(UserMark::Type::SEARCH);
GetBookmarkManager().ClearGroup(UserMark::Type::SEARCH);
GetBookmarkManager().NotifyChanges(UserMark::Type::SEARCH);
}
@ -2030,7 +2030,7 @@ url_scheme::ParsedMapApi::ParsingResult Framework::ParseAndSetApiURL(string cons
// Clear every current API-mark.
{
auto & bmManager = GetBookmarkManager();
bmManager.ClearUserMarks(UserMark::Type::API);
bmManager.ClearGroup(UserMark::Type::API);
bmManager.SetIsVisible(UserMark::Type::API, true);
bmManager.NotifyChanges(UserMark::Type::API);
}

View file

@ -177,7 +177,7 @@ void DeleteAllLocalAdsMarks(BookmarkManager * bmManager)
GetPlatform().RunTask(Platform::Thread::Gui, [bmManager]()
{
bmManager->ClearUserMarks(UserMark::Type::LOCAL_ADS);
bmManager->ClearGroup(UserMark::Type::LOCAL_ADS);
bmManager->NotifyChanges(UserMark::Type::LOCAL_ADS);
});
}

View file

@ -410,7 +410,7 @@ void RoutingManager::SetRouterImpl(RouterType type)
void RoutingManager::RemoveRoute(bool deactivateFollowing)
{
m_bmManager->ClearUserMarks(UserMark::Type::TRANSIT);
m_bmManager->ClearGroup(UserMark::Type::TRANSIT);
m_bmManager->NotifyChanges(UserMark::Type::TRANSIT);
if (deactivateFollowing)
@ -578,7 +578,7 @@ void RoutingManager::CloseRouting(bool removeRoutePoints)
if (removeRoutePoints)
{
m_bmManager->ClearUserMarks(UserMark::Type::ROUTING);
m_bmManager->ClearGroup(UserMark::Type::ROUTING);
m_bmManager->NotifyChanges(UserMark::Type::ROUTING);
CancelRecommendation(Recommendation::RebuildAfterPointsLoading);
@ -784,7 +784,7 @@ void RoutingManager::BuildRoute(uint32_t timeoutSec)
{
ASSERT_THREAD_CHECKER(m_threadChecker, ("BuildRoute"));
m_bmManager->ClearUserMarks(UserMark::Type::TRANSIT);
m_bmManager->ClearGroup(UserMark::Type::TRANSIT);
m_bmManager->NotifyChanges(UserMark::Type::TRANSIT);
auto routePoints = GetRoutePoints();
@ -1129,7 +1129,7 @@ void RoutingManager::CancelRoutePointsTransaction(uint32_t transactionId)
// Revert route points.
ASSERT(m_bmManager != nullptr, ());
m_bmManager->ClearUserMarks(UserMark::Type::ROUTING);
m_bmManager->ClearGroup(UserMark::Type::ROUTING);
RoutePointsLayout routePoints(*m_bmManager);
for (auto & markData : routeMarks)
routePoints.AddRoutePoint(move(markData));
@ -1169,7 +1169,7 @@ bool RoutingManager::LoadRoutePoints()
// If we have found my position, we use my position as start point.
auto const & myPosMark = m_bmManager->MyPositionMark();
ASSERT(m_bmManager != nullptr, ());
m_bmManager->ClearUserMarks(UserMark::Type::ROUTING);
m_bmManager->ClearGroup(UserMark::Type::ROUTING);
for (auto & p : points)
{
if (p.m_pointType == RouteMarkType::Start && myPosMark.HasPosition())

View file

@ -279,7 +279,7 @@ bool RoutePointsLayout::RemoveRoutePoint(RouteMarkType type, size_t intermediate
void RoutePointsLayout::RemoveRoutePoints()
{
m_manager.ClearUserMarks(UserMark::Type::ROUTING);
m_manager.ClearGroup(UserMark::Type::ROUTING);
}
void RoutePointsLayout::RemoveIntermediateRoutePoints()

View file

@ -44,6 +44,9 @@ public:
UserMark(m2::PointD const & ptOrg, UserMark::Type type);
Type GetMarkType() const { return m_type; }
df::MarkGroupID GetGroupId() const override { return m_type; }
// df::UserPointMark overrides.
bool IsDirty() const override { return m_isDirty; }
void ResetChanges() const override { m_isDirty = false; }
@ -51,7 +54,7 @@ public:
m2::PointD const & GetPivot() const override;
m2::PointD GetPixelOffset() const override;
dp::Anchor GetAnchor() const override;
virtual float GetDepth() const override { return 0.0f; }
float GetDepth() const override { return 0.0f; }
df::RenderState::DepthLayer GetDepthLayer() const override;
drape_ptr<TitlesInfo> GetTitleDecl() const override { return nullptr; }
drape_ptr<ColoredSymbolZoomInfo> GetColoredSymbols() const override { return nullptr; }
@ -67,8 +70,6 @@ public:
bool HasCreationAnimation() const override { return false; }
ms::LatLon GetLatLon() const;
virtual Type GetMarkType() const { return m_type; }
virtual df::MarkGroupID GetGroupId() const { return m_type; }
virtual bool IsAvailableForSearch() const { return true; }

View file

@ -26,6 +26,11 @@ bool UserMarkContainer::IsVisible() const
return m_isVisible;
}
bool UserMarkContainer::IsVisibilityChanged() const
{
return m_isVisible != m_wasVisible;
}
UserMark::Type UserMarkContainer::GetType() const
{
return m_type;
@ -34,12 +39,6 @@ UserMark::Type UserMarkContainer::GetType() const
void UserMarkContainer::Clear()
{
SetDirty();
for (auto const & markId : m_userMarks)
{
if (m_createdMarks.find(markId) == m_createdMarks.end())
m_removedMarks.insert(markId);
}
m_createdMarks.clear();
m_userMarks.clear();
}
@ -52,50 +51,20 @@ void UserMarkContainer::SetIsVisible(bool isVisible)
}
}
void UserMarkContainer::Update()
{
SetDirty();
}
void UserMarkContainer::SetDirty()
{
m_isDirty = true;
}
bool UserMarkContainer::IsDirty() const
{
return m_isDirty;
}
void UserMarkContainer::ResetChanges()
{
m_createdMarks.clear();
m_removedMarks.clear();
m_updatedMarks.clear();
m_isDirty = false;
m_wasVisible = m_isVisible;
}
void UserMarkContainer::AttachUserMark(df::MarkID markId)
{
SetDirty();
m_createdMarks.insert(markId);
m_userMarks.insert(markId);
}
void UserMarkContainer::EditUserMark(df::MarkID markId)
{
SetDirty();
m_updatedMarks.insert(markId);
}
void UserMarkContainer::DetachUserMark(df::MarkID markId)
{
SetDirty();
auto const it = m_createdMarks.find(markId);
if (it != m_createdMarks.end())
m_createdMarks.erase(it);
else
m_removedMarks.insert(markId);
m_userMarks.erase(markId);
}

View file

@ -17,45 +17,36 @@
class UserMarkContainer
{
public:
using NotifyChangesFn = std::function<void (UserMarkContainer const &, df::IDCollection const &)>;
UserMarkContainer(UserMark::Type type);
virtual ~UserMarkContainer();
bool IsDirty() const;
// Discard isDirty and clear the lists of created, removed and updated items.
bool IsDirty() const { return m_isDirty; }
virtual void ResetChanges();
bool IsVisible() const;
bool IsVisibilityChanged() const;
UserMark::Type GetType() const;
df::MarkIDSet const & GetUserMarks() const { return m_userMarks; }
virtual df::MarkIDSet const & GetUserLines() const { return m_userLines; }
df::MarkIDSet const & GetCreatedMarks() const { return m_createdMarks; }
df::MarkIDSet const & GetUpdatedMarks() const { return m_updatedMarks; }
df::MarkIDSet const & GetRemovedMarks() const { return m_removedMarks; }
void AttachUserMark(df::MarkID markId);
void EditUserMark(df::MarkID markId);
void DetachUserMark(df::MarkID markId);
void Clear();
void SetIsVisible(bool isVisible);
void Update();
protected:
void SetDirty();
void SetDirty() { m_isDirty = true; }
UserMark::Type m_type;
df::MarkIDSet m_userMarks;
df::MarkIDSet m_userLines;
df::MarkIDSet m_createdMarks;
df::MarkIDSet m_removedMarks;
df::MarkIDSet m_updatedMarks;
bool m_isVisible = true;
bool m_isDirty = false;
bool m_isVisible = true;
bool m_wasVisible = false;
DISALLOW_COPY_AND_MOVE(UserMarkContainer);
};