[bookmarks] Refactoring of the bookmarks changes tracker.

This commit is contained in:
Daria Volvenkova 2019-09-26 19:22:36 +03:00 committed by Roman Kuznetsov
parent 50442b529d
commit b94630c2b4
4 changed files with 154 additions and 43 deletions

View file

@ -243,8 +243,9 @@ void DrapeEngine::InvalidateUserMarks()
void DrapeEngine::UpdateUserMarks(UserMarksProvider * provider, bool firstTime)
{
auto const dirtyGroupIds = firstTime ? provider->GetAllGroupIds() : provider->GetDirtyGroupIds();
if (dirtyGroupIds.empty())
auto const updatedGroupIds = firstTime ? provider->GetAllGroupIds()
: provider->GetUpdatedGroupIds();
if (updatedGroupIds.empty())
return;
auto marksRenderCollection = make_unique_dp<UserMarksRenderCollection>();
@ -254,7 +255,7 @@ void DrapeEngine::UpdateUserMarks(UserMarksProvider * provider, bool firstTime)
if (!firstTime)
{
kml::MarkGroupId lastGroupId = *dirtyGroupIds.begin();
kml::MarkGroupId lastGroupId = *updatedGroupIds.begin();
bool visibilityChanged = provider->IsGroupVisibilityChanged(lastGroupId);
bool groupIsVisible = provider->IsGroupVisible(lastGroupId);
@ -264,8 +265,6 @@ void DrapeEngine::UpdateUserMarks(UserMarksProvider * provider, bool firstTime)
kml::MarkIdCollection *idCollection)
{
auto const *mark = provider->GetUserPointMark(markId);
if (!mark->IsDirty())
return;
auto const groupId = mark->GetGroupId();
if (groupId != lastGroupId)
{
@ -297,7 +296,7 @@ void DrapeEngine::UpdateUserMarks(UserMarksProvider * provider, bool firstTime)
}
std::map<kml::MarkGroupId, drape_ptr<IDCollections>> dirtyMarkIds;
for (auto groupId : dirtyGroupIds)
for (auto groupId : updatedGroupIds)
{
auto & idCollection = *(dirtyMarkIds.emplace(groupId, make_unique_dp<IDCollections>()).first->second);
bool const visibilityChanged = provider->IsGroupVisibilityChanged(groupId);

View file

@ -114,7 +114,7 @@ class UserMarksProvider
{
public:
virtual ~UserMarksProvider() = default;
virtual kml::GroupIdSet const & GetDirtyGroupIds() const = 0;
virtual kml::GroupIdSet const & GetUpdatedGroupIds() const = 0;
virtual kml::GroupIdSet const & GetRemovedGroupIds() const = 0;
virtual kml::GroupIdSet GetAllGroupIds() const = 0;
virtual bool IsGroupVisible(kml::MarkGroupId groupId) const = 0;

View file

@ -525,6 +525,7 @@ BookmarkManager::BookmarkManager(User & user, Callbacks && callbacks)
: m_user(user)
, m_callbacks(std::move(callbacks))
, m_changesTracker(*this)
, m_postponedChangesTracker(*this)
, m_needTeardown(false)
, m_bookmarkCloud(Cloud::CloudParams("bmc.json", "bookmarks", std::string(kBookmarkCloudSettingsParam),
GetBookmarksDirectory(), std::string(kKmbExtension),
@ -731,7 +732,7 @@ void BookmarkManager::DeleteTrack(kml::TrackId trackId)
m_tracks.erase(it);
}
void BookmarkManager::CollectDirtyGroups(kml::GroupIdSet & dirtyGroups)
void BookmarkManager::GetDirtyGroups(kml::GroupIdSet & dirtyGroups) const
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
for (auto const & group : m_userMarkLayers)
@ -765,25 +766,31 @@ void BookmarkManager::NotifyChanges()
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
m_changesTracker.AcceptDirtyItems();
if (!m_firstDrapeNotification &&
!m_changesTracker.HasChanges() && !m_postponedChangesTracker.HasChanges())
{
return;
}
if (m_changesTracker.HasBookmarksChanges())
NotifyBookmarksChanged();
m_postponedChangesTracker.AddChanges(m_changesTracker);
m_changesTracker.ResetChanges();
if (!m_notificationsEnabled)
return;
if (!m_changesTracker.CheckChanges() && !m_firstDrapeNotification)
return;
bool hasBookmarks = false;
kml::GroupIdCollection categoriesToSave;
for (auto groupId : m_changesTracker.GetDirtyGroupIds())
if (m_postponedChangesTracker.HasBookmarksChanges())
{
if (IsBookmarkCategory(groupId))
kml::GroupIdCollection categoriesToSave;
for (auto groupId : m_postponedChangesTracker.GetUpdatedGroupIds())
{
if (GetBmCategory(groupId)->IsAutoSaveEnabled())
if (IsBookmarkCategory(groupId) && GetBmCategory(groupId)->IsAutoSaveEnabled())
categoriesToSave.push_back(groupId);
hasBookmarks = true;
}
}
if (hasBookmarks)
{
SaveBookmarks(categoriesToSave);
SendBookmarksChanges();
}
@ -792,31 +799,22 @@ void BookmarkManager::NotifyChanges()
if (lock)
{
auto engine = lock.Get();
for (auto groupId : m_changesTracker.GetDirtyGroupIds())
for (auto groupId : m_postponedChangesTracker.GetUpdatedGroupIds())
{
auto * group = GetGroup(groupId);
engine->ChangeVisibilityUserMarksGroup(groupId, group->IsVisible());
}
for (auto groupId : m_changesTracker.GetRemovedGroupIds())
for (auto groupId : m_postponedChangesTracker.GetRemovedGroupIds())
engine->ClearUserMarksGroup(groupId);
engine->UpdateUserMarks(&m_changesTracker, m_firstDrapeNotification);
engine->UpdateUserMarks(&m_postponedChangesTracker, m_firstDrapeNotification);
m_firstDrapeNotification = false;
for (auto groupId : m_changesTracker.GetDirtyGroupIds())
{
auto * group = GetGroup(groupId);
group->ResetChanges();
}
engine->InvalidateUserMarks();
}
for (auto const markId : m_changesTracker.GetUpdatedMarkIds())
GetMark(markId)->ResetChanges();
m_changesTracker.ResetChanges();
m_postponedChangesTracker.ResetChanges();
}
kml::MarkIdSet const & BookmarkManager::GetUserMarkIds(kml::MarkGroupId groupId) const
@ -1612,6 +1610,11 @@ void BookmarkManager::UpdateViewport(ScreenBase const & screen)
m_viewport = screen;
}
void BookmarkManager::SetCategoriesChangedCallback(CategoriesChangedCallback && callback)
{
m_categoriesChangedCallback = std:move(callback);
}
void BookmarkManager::SetAsyncLoadingCallbacks(AsyncLoadingCallbacks && callbacks)
{
m_asyncLoadingCallbacks = std::move(callbacks);
@ -2193,6 +2196,12 @@ void BookmarkManager::SendBookmarksChanges()
}
}
void BookmarkManager::NotifyBookmarksChanged()
{
if (m_categoriesChangedCallback != nullptr)
m_categoriesChangedCallback();
}
bool BookmarkManager::HasBmCategory(kml::MarkGroupId groupId) const
{
CHECK_THREAD_CHECKER(m_threadChecker, ());
@ -2591,6 +2600,9 @@ void BookmarkManager::SaveBookmarks(kml::GroupIdCollection const & groupIdCollec
if (m_migrationInProgress)
return;
if (groupIdCollection.empty())
return;
auto kmlDataCollection = PrepareToSaveBookmarks(groupIdCollection);
if (!kmlDataCollection)
return;
@ -3429,6 +3441,7 @@ void BookmarkManager::MarksChangesTracker::OnAddGroup(kml::MarkGroupId groupId)
void BookmarkManager::MarksChangesTracker::OnDeleteGroup(kml::MarkGroupId groupId)
{
m_updatedGroups.erase(groupId);
auto const it = m_createdGroups.find(groupId);
if (it != m_createdGroups.end())
m_createdGroups.erase(it);
@ -3436,21 +3449,71 @@ void BookmarkManager::MarksChangesTracker::OnDeleteGroup(kml::MarkGroupId groupI
m_removedGroups.insert(groupId);
}
bool BookmarkManager::MarksChangesTracker::CheckChanges()
void BookmarkManager::MarksChangesTracker::OnUpdateGroup(kml::MarkGroupId groupId)
{
m_bmManager.CollectDirtyGroups(m_dirtyGroups);
m_updatedGroups.insert(groupId);
}
void BookmarkManager::MarksChangesTracker::AcceptDirtyItems()
{
m_bmManager.GetDirtyGroups(m_updatedGroups);
for (auto groupId : m_updatedGroups)
{
auto * group = m_bmManager.GetGroup(groupId);
group->ResetChanges();
}
kml::MarkIdSet dirtyMarks;
for (auto const markId : m_updatedMarks)
{
auto const * mark = m_bmManager.GetMark(markId);
if (mark->IsDirty())
m_dirtyGroups.insert(mark->GetGroupId());
{
dirtyMarks.insert(markId);
m_updatedGroups.insert(mark->GetGroupId());
mark->ResetChanges();
}
}
return !m_dirtyGroups.empty() || !m_removedGroups.empty();
m_updatedMarks.swap(dirtyMarks);
for (auto const markId : m_createdMarks)
{
auto const *mark = m_bmManager.GetMark(markId);
ASSERT(mark->IsDirty(), ());
mark->ResetChanges();
}
for (auto const lineId : m_createdLines)
{
auto const *line = m_bmManager.GetTrack(lineId);
ASSERT(line->IsDirty(), ());
line->ResetChanges();
}
}
bool BookmarkManager::MarksChangesTracker::HasChanges() const
{
return !m_updatedGroups.empty() || !m_removedGroups.empty();
}
bool BookmarkManager::MarksChangesTracker::HasBookmarksChanges() const
{
for (auto groupId : m_updatedGroups)
{
if (m_bmManager.IsBookmarkCategory(groupId))
return true;
}
for (auto groupId : m_removedGroups)
{
if (m_bmManager.IsBookmarkCategory(groupId))
return true;
}
return false;
}
void BookmarkManager::MarksChangesTracker::ResetChanges()
{
m_dirtyGroups.clear();
m_updatedGroups.clear();
m_createdGroups.clear();
m_removedGroups.clear();
@ -3465,6 +3528,45 @@ void BookmarkManager::MarksChangesTracker::ResetChanges()
m_detachedBookmarks.clear();
}
void BookmarkManager::MarksChangesTracker::AddChanges(MarksChangesTracker const & changes)
{
for (auto const groupId : changes.m_createdGroups)
OnAddGroup(groupId);
for (auto const groupId : changes.m_updatedGroups)
OnUpdateGroup(groupId);
for (auto const groupId : changes.m_removedGroups)
OnDeleteGroup(groupId);
for (auto const markId : changes.m_createdMarks)
OnAddMark(markId);
for (auto const markId : changes.m_updatedMarks)
OnUpdateMark(markId);
for (auto const markId : changes.m_removedMarks)
OnDeleteMark(markId);
for (auto const lineId : changes.m_createdLines)
OnAddLine(lineId);
for (auto const lineId : changes.m_removedLines)
OnDeleteLine(lineId);
for (auto const & attachedInfo : changes.m_attachedBookmarks)
{
for (auto const markId : attachedInfo.second)
OnAttachBookmark(markId, attachedInfo.first);
}
for (auto const & detachedInfo : changes.m_detachedBookmarks)
{
for (auto const markId : detachedInfo.second)
OnDetachBookmark(markId, detachedInfo.first);
}
}
bool BookmarkManager::SortedBlock::operator==(SortedBlock const & other) const
{
return m_blockName == other.m_blockName && m_markIds == other.m_markIds &&

View file

@ -57,6 +57,8 @@ public:
using KMLDataCollection = std::vector<std::pair<std::string, std::unique_ptr<kml::FileData>>>;
using KMLDataCollectionPtr = std::shared_ptr<KMLDataCollection>;
using CategoriesChangedCallback = std::function<void()>;
using AsyncLoadingStartedCallback = std::function<void()>;
using AsyncLoadingFinishedCallback = std::function<void()>;
using AsyncLoadingFileCallback = std::function<void(std::string const &, bool)>;
@ -173,6 +175,7 @@ public:
storage::CountryInfoGetter const & infoGetter);
void ResetRegionAddressGetter();
void SetCategoriesChangedCallback(CategoriesChangedCallback && callback);
void SetAsyncLoadingCallbacks(AsyncLoadingCallbacks && callbacks);
bool IsAsyncLoadingInProgress() const { return m_asyncLoadingInProgress; }
@ -459,12 +462,16 @@ private:
void OnAddGroup(kml::MarkGroupId groupId);
void OnDeleteGroup(kml::MarkGroupId groupId);
void OnUpdateGroup(kml::MarkGroupId groupId);
void OnAttachBookmark(kml::MarkId markId, kml::MarkGroupId catId);
void OnDetachBookmark(kml::MarkId markId, kml::MarkGroupId catId);
bool CheckChanges();
void AcceptDirtyItems();
bool HasChanges() const;
bool HasBookmarksChanges() const;
void ResetChanges();
void AddChanges(MarksChangesTracker const & changes);
using GroupMarkIdSet = std::map<kml::MarkGroupId, kml::MarkIdSet>;
GroupMarkIdSet const & GetAttachedBookmarks() const { return m_attachedBookmarks; }
@ -472,7 +479,7 @@ private:
// UserMarksProvider
kml::GroupIdSet GetAllGroupIds() const override;
kml::GroupIdSet const & GetDirtyGroupIds() const override { return m_dirtyGroups; }
kml::GroupIdSet const & GetUpdatedGroupIds() const override { return m_updatedGroups; }
kml::GroupIdSet const & GetRemovedGroupIds() const override { return m_removedGroups; }
kml::MarkIdSet const & GetCreatedMarkIds() const override { return m_createdMarks; }
kml::MarkIdSet const & GetRemovedMarkIds() const override { return m_removedMarks; }
@ -498,7 +505,7 @@ private:
kml::TrackIdSet m_createdLines;
kml::TrackIdSet m_removedLines;
kml::GroupIdSet m_dirtyGroups;
kml::GroupIdSet m_updatedGroups;
kml::GroupIdSet m_createdGroups;
kml::GroupIdSet m_removedGroups;
@ -612,10 +619,11 @@ private:
KmlFileType fileType, BookmarksChecker const & checker,
std::vector<std::string> & cloudFilePaths);
void CollectDirtyGroups(kml::GroupIdSet & dirtyGroups);
void GetDirtyGroups(kml::GroupIdSet & dirtyGroups) const;
void UpdateBmGroupIdList();
void NotifyBookmarksChanged();
void SendBookmarksChanges();
void GetBookmarksInfo(kml::MarkIdSet const & marks, std::vector<BookmarkInfo> & bookmarks);
void GetBookmarkGroupsInfo(MarksChangesTracker::GroupMarkIdSet const & groups,
@ -702,11 +710,13 @@ private:
User & m_user;
Callbacks m_callbacks;
MarksChangesTracker m_changesTracker;
MarksChangesTracker m_postponedChangesTracker;
df::DrapeEngineSafePtr m_drapeEngine;
std::unique_ptr<search::RegionAddressGetter> m_regionAddressGetter;
std::mutex m_regionAddressMutex;
CategoriesChangedCallback m_categoriesChangedCallback;
AsyncLoadingCallbacks m_asyncLoadingCallbacks;
std::atomic<bool> m_needTeardown;
size_t m_openedEditSessionsCount = 0;