From 370d6169deecf827006b90c28202570a0e05b098 Mon Sep 17 00:00:00 2001 From: ExMix Date: Tue, 8 Jul 2014 15:04:53 +0200 Subject: [PATCH] [core] crash fix. In some cases anim::Task write into deleted memory --- iphone/Maps/Classes/PlacePageView.mm | 2 +- map/bookmark.cpp | 40 +++++++++++++++++++++++++++- map/bookmark.hpp | 5 ++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/iphone/Maps/Classes/PlacePageView.mm b/iphone/Maps/Classes/PlacePageView.mm index 7332740feb..45bb06f5e8 100644 --- a/iphone/Maps/Classes/PlacePageView.mm +++ b/iphone/Maps/Classes/PlacePageView.mm @@ -864,7 +864,7 @@ typedef NS_ENUM(NSUInteger, CellRow) BookmarkAndCategory const & bookmarkAndCategory = framework.FindBookmark(mark); BookmarkCategory * category = framework.GetBmCategory(bookmarkAndCategory.first); m_mark = [self cachedMark]; - framework.ActivateUserMark(mark); + framework.ActivateUserMark([self userMark]); if (category) { category->DeleteBookmark(bookmarkAndCategory.second); diff --git a/map/bookmark.cpp b/map/bookmark.cpp index d219a3c3f7..ecfe20339b 100644 --- a/map/bookmark.cpp +++ b/map/bookmark.cpp @@ -126,6 +126,23 @@ void BookmarkCategory::DeleteBookmark(size_t index) { base_t::Controller & c = base_t::GetController(); ASSERT_LESS(index, c.GetUserMarkCount(), ()); + UserMark const * markForDelete = c.GetUserMark(index); + + int animIndex = -1; + for (size_t i = 0; i < m_anims.size(); ++i) + { + anim_node_t const & anim = m_anims[i]; + if (anim.first == markForDelete) + { + anim.second->Cancel(); + animIndex = i; + break; + } + } + + if (animIndex != -1) + m_anims.erase(m_anims.begin() + animIndex); + c.DeleteUserMark(index); } @@ -802,11 +819,32 @@ string BookmarkCategory::GenerateUniqueFileName(const string & path, string name return (path + name + suffix + kmlExt); } +void BookmarkCategory::ReleaseAnimations() +{ + vector tempAnims; + for (size_t i = 0; i < m_anims.size(); ++i) + { + anim_node_t const & anim = m_anims[i]; + if (!anim.second->IsEnded() && + !anim.second->IsCancelled()) + { + tempAnims.push_back(m_anims[i]); + } + } + + swap(m_anims, tempAnims); +} + UserMark * BookmarkCategory::AllocateUserMark(m2::PointD const & ptOrg) { Bookmark * b = new Bookmark(ptOrg, this); if (!m_blockAnimation) - m_framework.GetAnimController()->AddTask(b->CreateAnimTask(m_framework)); + { + shared_ptr animTask = b->CreateAnimTask(m_framework); + animTask->AddCallback(anim::Task::EEnded, bind(&BookmarkCategory::ReleaseAnimations, this)); + m_anims.push_back(make_pair((UserMark *)b, animTask)); + m_framework.GetAnimController()->AddTask(animTask); + } return b; } diff --git a/map/bookmark.hpp b/map/bookmark.hpp index 0c9cc51b52..4a3ada3bf9 100644 --- a/map/bookmark.hpp +++ b/map/bookmark.hpp @@ -188,9 +188,14 @@ protected: virtual string GetTypeName() const { return "search-result"; } virtual string GetActiveTypeName() const { return "search-result-active"; } virtual UserMark * AllocateUserMark(m2::PointD const & ptOrg); + +private: + void ReleaseAnimations(); private: bool m_blockAnimation; + typedef pair > anim_node_t; + vector m_anims; }; ///