diff --git a/map/balloon_manager.cpp b/map/balloon_manager.cpp index 83de9e4f95..e2d6c974ca 100644 --- a/map/balloon_manager.cpp +++ b/map/balloon_manager.cpp @@ -35,7 +35,7 @@ void PinClickManager::OnClick(m2::PointD const & pxPoint, bool isLongTouch) void PinClickManager::OnBookmarkClick(BookmarkAndCategory const & bnc) { Bookmark * mark = m_f.GetBmCategory(bnc.first)->GetBookmark(bnc.second); - m_f.GetBookmarkManager().ActivateMark(mark); + m_f.GetBookmarkManager ().ActivateMark(mark); SetBalloonVisible(true); } diff --git a/map/bookmark.cpp b/map/bookmark.cpp index 9752fc739a..5859e13f74 100644 --- a/map/bookmark.cpp +++ b/map/bookmark.cpp @@ -741,6 +741,11 @@ string BookmarkCategory::GenerateUniqueFileName(const string & path, string name return (path + name + suffix + kmlExt); } +UserMark * BookmarkCategory::AllocateUserMark(m2::PointD const & ptOrg) +{ + return new Bookmark(ptOrg, this); +} + bool BookmarkCategory::SaveToKMLFile() { string oldFile; diff --git a/map/bookmark.hpp b/map/bookmark.hpp index ada4544caf..0c43368e08 100644 --- a/map/bookmark.hpp +++ b/map/bookmark.hpp @@ -56,11 +56,11 @@ private: time_t m_timeStamp; }; -class Bookmark : public UserMark +class Bookmark : public ICustomDrawable { public: - Bookmark(UserMarkContainer * container) - : UserMark(m2::PointD(0.0, 0.0), container) + Bookmark(m2::PointD const & ptOrg, UserMarkContainer * container) + : ICustomDrawable(ptOrg, container) { Inject(); } @@ -83,6 +83,11 @@ public: double GetScale() const { return GetData()->GetScale(); } void SetScale(double scale) { GetData()->SetScale(scale); } + virtual graphics::DisplayList * GetDisplayList(UserMarkDLCache * cache) const + { + return cache->FindUserMark(UserMarkDLCache::Key(GetType(), graphics::EPosAbove, GetContainer()->GetDepth())); + } + private: void Inject(m2::PointD const & org = m2::PointD(), string const & name = "", string const & type = "", string const & descr = "", @@ -167,6 +172,9 @@ public: /// Get unique bookmark file name from path and valid file name. static string GenerateUniqueFileName(const string & path, string name); //@} + +protected: + virtual UserMark * AllocateUserMark(m2::PointD const & ptOrg); }; /// diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index 07b54dffe2..324f6c5fdf 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -23,6 +23,7 @@ BookmarkManager::BookmarkManager(Framework & f) , m_activeMark(NULL) , m_bmScreen(0) , m_lastScale(1.0) + , m_cache(NULL) { m_userMarkLayers.reserve(2); m_userMarkLayers.push_back(new UserMarkContainer(UserMarkContainer::SEARCH_MARK, graphics::activePinDepth, m_framework)); @@ -125,14 +126,13 @@ public: } -void BookmarkManager::DrawCategory(BookmarkCategory const * cat, shared_ptr const & e) const +void BookmarkManager::DrawCategory(BookmarkCategory const * cat, PaintOverlayEvent const & e) const { /// TODO cutomize draw in UserMarkContainer for user Draw method Navigator const & navigator = m_framework.GetNavigator(); - InformationDisplay & informationDisplay = m_framework.GetInformationDisplay(); ScreenBase const & screen = navigator.Screen(); - Drawer * pDrawer = e->drawer(); + Drawer * pDrawer = e.GetDrawer(); graphics::Screen * pScreen = pDrawer->screen(); LazyMatrixCalc matrix(screen, m_lastScale); @@ -145,16 +145,7 @@ void BookmarkManager::DrawCategory(BookmarkCategory const * cat, shared_ptrDraw(pScreen, matrix.GetFinalG2P()); } - // Draw bookmarks. - m2::AnyRectD const & glbRect = screen.GlobalRect(); - for (size_t j = 0; j < cat->GetBookmarksCount(); ++j) - { - Bookmark const * bm = cat->GetBookmark(j); - m2::PointD const & org = bm->GetOrg(); - - if (glbRect.IsPointInside(org)) - informationDisplay.drawPlacemark(pDrawer, bm->GetType().c_str(), navigator.GtoP(org) + m2::PointD(0.0, 4.0)); - } + cat->Draw(e, m_cache); } void BookmarkManager::ClearItems() @@ -243,6 +234,7 @@ size_t BookmarkManager::CreateBmCategory(string const & name) void BookmarkManager::DrawItems(shared_ptr const & e) const { + ASSERT(m_cache != NULL, ()); ScreenBase const & screen = m_framework.GetNavigator().Screen(); m2::RectD const limitRect = screen.ClipRect(); @@ -272,13 +264,8 @@ void BookmarkManager::DrawItems(shared_ptr const & e) const pScreen->beginFrame(); PaintOverlayEvent event(e->drawer(), screen); - for_each(m_userMarkLayers.begin(), m_userMarkLayers.end(), bind(&UserMarkContainer::Draw, _1, event)); - - for (size_t i = 0; i < m_categories.size(); ++i) - { - if (m_categories[i]->IsVisible()) - DrawCategory(m_categories[i], e); - } + for_each(m_userMarkLayers.begin(), m_userMarkLayers.end(), bind(&UserMarkContainer::Draw, _1, event, m_cache)); + for_each(m_categories.begin(), m_categories.end(), bind(&BookmarkManager::DrawCategory, this, _1, event)); pScreen->endFrame(); } @@ -317,21 +304,6 @@ void BookmarkManager::ActivateMark(UserMark const * mark) return; m_activeMark = mark; - /// TODO remove this hack when resctuct Bookmark drawing code. - /// now it's need to activate bookmark element - UserCustomData const & data = m_activeMark->GetCustomData(); - if (data.GetType() == UserCustomData::BOOKMARK) - { - m_activeMark = UserMarkContainer::UserMarkForPoi(mark->GetOrg()); - BookmarkCustomData const & bookmarkData = static_cast(data); - search::AddressInfo addrInfo; - m_framework.GetAddressInfoForGlobalPoint(mark->GetOrg(), addrInfo); - UserMark * hackMark = const_cast(m_activeMark); - hackMark->InjectCustomData(new PoiCustomData(bookmarkData.GetName(), - bookmarkData.GetTypeName(), - addrInfo.FormatNameAndAddress())); - } - m_activeMark->Activate(); } @@ -397,12 +369,13 @@ void BookmarkManager::SetScreen(graphics::Screen * screen) { ResetScreen(); m_bmScreen = screen; - for_each(m_userMarkLayers.begin(), m_userMarkLayers.end(), - bind(&UserMarkContainer::SetScreen, _1, m_bmScreen)); + m_cache = new UserMarkDLCache(m_bmScreen); } void BookmarkManager::ResetScreen() { + delete m_cache; + m_cache = NULL; if (m_bmScreen) { // Delete display lists for all tracks @@ -410,9 +383,6 @@ void BookmarkManager::ResetScreen() for (size_t j = 0; j < m_categories[i]->GetTracksCount(); ++j) m_categories[i]->GetTrack(j)->DeleteDisplayList(); - for (size_t i = 0; i < m_userMarkLayers.size(); ++i) - m_userMarkLayers[i]->SetScreen(0); - m_bmScreen = 0; } } diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index dd1011c624..ec170727e8 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -1,6 +1,7 @@ #pragma once #include "bookmark.hpp" #include "user_mark_container.hpp" +#include "user_mark_dl_cache.hpp" class Framework; class PaintEvent; @@ -23,7 +24,7 @@ class BookmarkManager : private noncopyable typedef vector::iterator CategoryIter; - void DrawCategory(BookmarkCategory const * cat, shared_ptr const & e) const; + void DrawCategory(BookmarkCategory const * cat, PaintOverlayEvent const & e) const; void SaveState() const; void LoadState(); @@ -74,4 +75,6 @@ public: private: UserMarkContainer const * FindUserMarksContainer(UserMarkContainer::Type type) const; UserMarkContainer * FindUserMarksContainer(UserMarkContainer::Type type); + + UserMarkDLCache * m_cache; }; diff --git a/map/map.pro b/map/map.pro index 6a871ab0b1..dfdd657933 100644 --- a/map/map.pro +++ b/map/map.pro @@ -66,7 +66,8 @@ HEADERS += \ track.hpp \ alfa_animation_task.hpp \ user_mark_container.hpp \ - user_mark.hpp + user_mark.hpp \ + user_mark_dl_cache.hpp SOURCES += \ feature_vec_model.cpp \ @@ -119,7 +120,8 @@ SOURCES += \ track.cpp \ alfa_animation_task.cpp \ user_mark_container.cpp \ - user_mark.cpp + user_mark.cpp \ + user_mark_dl_cache.cpp !iphone*:!tizen*:!android* { HEADERS += qgl_render_context.hpp diff --git a/map/user_mark.hpp b/map/user_mark.hpp index 3490985729..f3fbc4b901 100644 --- a/map/user_mark.hpp +++ b/map/user_mark.hpp @@ -6,6 +6,13 @@ #include "../std/noncopyable.hpp" class UserMarkContainer; +class PaintOverlayEvent; +class UserMarkDLCache; + +namespace graphics +{ + class DisplayList; +} class UserCustomData { @@ -95,6 +102,7 @@ public: UserMarkContainer const * GetContainer() const; m2::PointD const & GetOrg() const; void GetLatLon(double & lat, double & lon) const; + virtual bool IsCustomDrawable() const { return false;} // custom data must be allocated in head // memory where allocated custom data will be deallocated by UserMark @@ -112,3 +120,11 @@ protected: mutable UserMarkContainer * m_container; UserCustomData * m_customData; }; + +class ICustomDrawable : public UserMark +{ +public: + ICustomDrawable(m2::PointD const & ptOrg, UserMarkContainer * container) : UserMark(ptOrg, container) {} + bool IsCustomDrawable() const { return true; } + virtual graphics::DisplayList * GetDisplayList(UserMarkDLCache * cache) const = 0; +}; diff --git a/map/user_mark_container.cpp b/map/user_mark_container.cpp index a63279e3e1..00f1728e83 100644 --- a/map/user_mark_container.cpp +++ b/map/user_mark_container.cpp @@ -127,35 +127,40 @@ namespace m2::PointD m_globalCenter; }; - class DrawFunctor + void DrawUserMarkImpl(double scale, + PaintOverlayEvent const & event, + graphics::DisplayList * dl, + UserMark const * mark) { - public: - DrawFunctor(double scale, - ScreenBase const & modelView, - graphics::DisplayList * dl, - graphics::Screen * screen) - : m_scale(scale) - , m_modelView(modelView) - , m_dl(dl) - , m_screen(screen) - { - } + ScreenBase modelView = event.GetModelView(); + graphics::Screen * screen = event.GetDrawer()->screen(); + m2::PointD pxPoint = modelView.GtoP(mark->GetOrg()); + math::Matrix m = math::Shift(math::Scale(math::Identity(), + scale, scale), + pxPoint.x, pxPoint.y); + dl->draw(screen, m); + } - void operator()(UserMark const * mark) - { - m2::PointD pxPoint = m_modelView.GtoP(mark->GetOrg()); - math::Matrix m = math::Shift(math::Scale(math::Identity(), - m_scale, m_scale), - pxPoint.x, pxPoint.y); - m_dl->draw(m_screen, m); - } + void DefaultDrawUserMark(double scale, + PaintOverlayEvent const & event, + UserMarkDLCache * cache, + UserMarkDLCache::Key const & defaultKey, + UserMark const * mark) + { + DrawUserMarkImpl(scale, event, cache->FindUserMark(defaultKey), mark); + } - private: - double m_scale; - ScreenBase const & m_modelView; - graphics::DisplayList * m_dl; - graphics::Screen * m_screen; - }; + void DrawUserMark(double scale, + PaintOverlayEvent const & event, + UserMarkDLCache * cache, + UserMarkDLCache::Key const & defaultKey, + UserMark const * mark) + { + if (mark->IsCustomDrawable()) + DrawUserMarkImpl(scale, event, static_cast(mark)->GetDisplayList(cache), mark); + else + DefaultDrawUserMark(scale, event, cache, defaultKey, mark); + } } UserMarkContainer::UserMarkContainer(Type type, double layerDepth, Framework & framework) @@ -164,9 +169,6 @@ UserMarkContainer::UserMarkContainer(Type type, double layerDepth, Framework & f , m_isVisible(true) , m_layerDepth(layerDepth) , m_activeMark(NULL) - , m_symbolDL(NULL) - , m_activeSymbolDL(NULL) - , m_cacheScreen(NULL) , m_framework(framework) { ASSERT(m_type >= 0 && m_type < TERMINANT, ()); @@ -175,13 +177,6 @@ UserMarkContainer::UserMarkContainer(Type type, double layerDepth, Framework & f UserMarkContainer::~UserMarkContainer() { Clear(); - ReleaseScreen(); -} - -void UserMarkContainer::SetScreen(graphics::Screen * cacheScreen) -{ - Purge(); - m_cacheScreen = cacheScreen; } UserMark const * UserMarkContainer::FindMarkInRect(m2::AnyRectD const & rect, double & d) @@ -193,25 +188,19 @@ UserMark const * UserMarkContainer::FindMarkInRect(m2::AnyRectD const & rect, do return mark; } -void UserMarkContainer::Draw(PaintOverlayEvent const & e) +void UserMarkContainer::Draw(PaintOverlayEvent const & e, UserMarkDLCache * cache) const { if (m_isVisible == false) return; - ASSERT(m_cacheScreen != NULL, ()); - if (m_cacheScreen == NULL) - return; - - graphics::Screen * screen = e.GetDrawer()->screen(); - ScreenBase modelView = e.GetModelView(); if (m_activeMark != NULL) { - LOG(LINFO, ("Scale for active mark = ", GetActiveMarkScale())); - (void)DrawFunctor(GetActiveMarkScale(), modelView, GetActiveDL(), screen)(m_activeMark); + UserMarkDLCache::Key defaultKey(GetActiveTypeName(), graphics::EPosCenter, m_layerDepth); + DefaultDrawUserMark(GetActiveMarkScale(), e, cache, defaultKey, m_activeMark); } - DrawFunctor f(1.0, modelView, GetDL(), screen); - for_each(m_userMarks.begin(), m_userMarks.end(), f); + UserMarkDLCache::Key defaultKey(GetTypeName(), graphics::EPosCenter, m_layerDepth); + for_each(m_userMarks.begin(), m_userMarks.end(), bind(&DrawUserMark, 1.0, e, cache, defaultKey, _1)); } void UserMarkContainer::ActivateMark(UserMark const * mark) @@ -229,7 +218,6 @@ void UserMarkContainer::DiactivateMark() void UserMarkContainer::Clear() { - Purge(); DeleteRange(m_userMarks, DeleteFunctor()); m_activeMark = NULL; } @@ -237,15 +225,26 @@ void UserMarkContainer::Clear() static string s_TypeNames[] = { "search-result", - "api-result" + "api-result", + "search-result" // Bookmark active we draw as a search active }; -string const & UserMarkContainer::GetTypeName() const +string UserMarkContainer::GetTypeName() const { ASSERT(m_type < ARRAY_SIZE(s_TypeNames), ()); return s_TypeNames[m_type]; } +string UserMarkContainer::GetActiveTypeName() const +{ + return GetTypeName() + "-active"; +} + +UserMark * UserMarkContainer::AllocateUserMark(m2::PointD const & ptOrg) +{ + return new UserMark(ptOrg, this); +} + namespace { class PoiUserMark : public UserMark @@ -273,9 +272,9 @@ UserMark * UserMarkContainer::UserMarkForPoi(m2::PointD const & ptOrg) return s_selectionUserMark.get(); } -UserMark * UserMarkContainer::CreateUserMark(m2::PointD ptOrg) +UserMark * UserMarkContainer::CreateUserMark(m2::PointD const & ptOrg) { - m_userMarks.push_back(new UserMark(ptOrg, this)); + m_userMarks.push_back(AllocateUserMark(ptOrg)); return m_userMarks.back(); } @@ -329,79 +328,6 @@ void UserMarkContainer::DeleteUserMark(size_t index) DeleteItem(m_userMarks, index); } -graphics::DisplayList * UserMarkContainer::GetDL() -{ - if (m_symbolDL == NULL) - m_symbolDL = CreateDL(GetTypeName()); - - return m_symbolDL; -} - -graphics::DisplayList * UserMarkContainer::GetActiveDL() -{ - if (m_activeSymbolDL == NULL) - m_activeSymbolDL = CreateDL(GetTypeName() + "-active"); - - return m_activeSymbolDL; -} - -graphics::DisplayList * UserMarkContainer::CreateDL(const string & symbolName) -{ - using namespace graphics; - - graphics::DisplayList * dl = m_cacheScreen->createDisplayList(); - m_cacheScreen->beginFrame(); - m_cacheScreen->setDisplayList(dl); - - Icon::Info infoKey(symbolName); - Resource const * res = m_cacheScreen->fromID(m_cacheScreen->findInfo(infoKey)); - shared_ptr texture = m_cacheScreen->pipeline(res->m_pipelineID).texture(); - - m2::RectU texRect = res->m_texRect; - double halfSizeX = texRect.SizeX() / 2.0; - double halfSizeY = texRect.SizeY() / 2.0; - - m2::PointD coords[] = - { - m2::PointD(-halfSizeX, -halfSizeY), - m2::PointD(-halfSizeX, halfSizeY), - m2::PointD(halfSizeX, -halfSizeY), - m2::PointD(halfSizeX, halfSizeY) - }; - m2::PointF normal(0.0, 0.0); - - m2::PointF texCoords[] = - { - texture->mapPixel(m2::PointF(texRect.minX(), texRect.minY())), - texture->mapPixel(m2::PointF(texRect.minX(), texRect.maxY())), - texture->mapPixel(m2::PointF(texRect.maxX(), texRect.minY())), - texture->mapPixel(m2::PointF(texRect.maxX(), texRect.maxY())) - }; - - m_cacheScreen->addTexturedStripStrided(coords, sizeof(m2::PointD), - &normal, 0, - texCoords, sizeof(m2::PointF), - 4, m_layerDepth, res->m_pipelineID); - - m_cacheScreen->setDisplayList(NULL); - m_cacheScreen->endFrame(); - - return dl; -} - -void UserMarkContainer::Purge() -{ - delete m_symbolDL; - m_symbolDL = NULL; - delete m_activeSymbolDL; - m_activeSymbolDL = NULL; -} - -void UserMarkContainer::ReleaseScreen() -{ - m_cacheScreen = NULL; -} - void UserMarkContainer::StartActivationAnim() { PinAnimation * anim = new PinAnimation(m_framework); diff --git a/map/user_mark_container.hpp b/map/user_mark_container.hpp index 16f5347225..2ea5a34e68 100644 --- a/map/user_mark_container.hpp +++ b/map/user_mark_container.hpp @@ -2,6 +2,7 @@ #include "events.hpp" #include "user_mark.hpp" +#include "user_mark_dl_cache.hpp" #include "../geometry/point2d.hpp" #include "../geometry/rect2d.hpp" @@ -49,7 +50,7 @@ public: }; UserMarkContainer(Type type, double layerDepth, Framework & framework); - ~UserMarkContainer(); + virtual ~UserMarkContainer(); void SetScreen(graphics::Screen * cacheScreen); @@ -61,14 +62,14 @@ public: // In multiple select choose mark with min(d) UserMark const * FindMarkInRect(m2::AnyRectD const & rect, double & d); - void Draw(PaintOverlayEvent const & e); + void Draw(PaintOverlayEvent const & e, UserMarkDLCache * cache) const; void ActivateMark(UserMark const * mark); void DiactivateMark(); void Clear(); Type const & GetType() const { return m_type; } - string const & GetTypeName() const; + double GetDepth() const { return m_layerDepth; } static void InitPoiSelectionMark(UserMarkContainer * container); static UserMark * UserMarkForPoi(m2::PointD const & ptOrg); @@ -76,22 +77,20 @@ public: Controller const & GetController() const { return m_controller; } Controller & GetController() { return m_controller; } +protected: + virtual string GetTypeName() const; + virtual string GetActiveTypeName() const; + virtual UserMark * AllocateUserMark(m2::PointD const & ptOrg); + private: friend class Controller; - UserMark * CreateUserMark(m2::PointD ptOrg); + UserMark * CreateUserMark(m2::PointD const & ptOrg); size_t GetUserMarkCount() const; UserMark const * GetUserMark(size_t index) const; UserMark * GetUserMark(size_t index); void EditUserMark(size_t index, UserCustomData * data); void DeleteUserMark(size_t index); -private: - graphics::DisplayList * GetDL(); - graphics::DisplayList * GetActiveDL(); - graphics::DisplayList * CreateDL(string const & symbolName); - void Purge(); - void ReleaseScreen(); - private: Controller m_controller; Type m_type; @@ -99,9 +98,6 @@ private: double m_layerDepth; vector m_userMarks; UserMark const * m_activeMark; - graphics::DisplayList * m_symbolDL; - graphics::DisplayList * m_activeSymbolDL; - graphics::Screen * m_cacheScreen; private: /// animation support diff --git a/map/user_mark_dl_cache.cpp b/map/user_mark_dl_cache.cpp new file mode 100644 index 0000000000..6135a99112 --- /dev/null +++ b/map/user_mark_dl_cache.cpp @@ -0,0 +1,102 @@ +#include "user_mark_dl_cache.hpp" + +#include "../base/stl_add.hpp" + +#include "../graphics/display_list.hpp" +#include "../graphics/screen.hpp" + +namespace +{ + struct Deleter + { + void operator()(pair const & node) + { + delete node.second; + } + }; +} + +UserMarkDLCache::UserMarkDLCache(graphics::Screen * cacheScreen) + : m_cacheScreen(cacheScreen) +{ +} + +UserMarkDLCache::~UserMarkDLCache() +{ + DeleteRange(m_dls, Deleter()); + m_cacheScreen = NULL; +} + +graphics::DisplayList * UserMarkDLCache::FindUserMark(UserMarkDLCache::Key const & key) +{ + node_t node = m_dls.find(key); + if (node != m_dls.end()) + return node->second; + + return CreateDL(key); +} + +namespace +{ + m2::RectD CalcCoords(double const & halfSizeX, double const & halfSizeY, graphics::EPosition anchor) + { + m2::RectD result(-halfSizeX, -halfSizeY, halfSizeX, halfSizeY); + + if (anchor & graphics::EPosAbove) + result.Offset(0.0, -halfSizeY); + else if (anchor & graphics::EPosUnder) + result.Offset(0.0, halfSizeY); + + if (anchor & graphics::EPosLeft) + result.Offset(halfSizeX, 0.0); + else if (anchor & graphics::EPosRight) + result.Offset(-halfSizeX, 0.0); + + return result; + } +} + +graphics::DisplayList * UserMarkDLCache::CreateDL(UserMarkDLCache::Key const & key) +{ + using namespace graphics; + + graphics::DisplayList * dl = m_cacheScreen->createDisplayList(); + m_cacheScreen->beginFrame(); + m_cacheScreen->setDisplayList(dl); + + Icon::Info infoKey(key.m_name); + Resource const * res = m_cacheScreen->fromID(m_cacheScreen->findInfo(infoKey)); + shared_ptr texture = m_cacheScreen->pipeline(res->m_pipelineID).texture(); + + m2::RectU texRect = res->m_texRect; + m2::RectD coord = CalcCoords(texRect.SizeX() / 2.0, texRect.SizeY() / 2.0, key.m_anchor); + + m2::PointD coords[] = + { + coord.LeftBottom(), + coord.LeftTop(), + coord.RightBottom(), + coord.RightTop() + }; + m2::PointF normal(0.0, 0.0); + + m2::PointF texCoords[] = + { + texture->mapPixel(m2::PointF(texRect.minX(), texRect.minY())), + texture->mapPixel(m2::PointF(texRect.minX(), texRect.maxY())), + texture->mapPixel(m2::PointF(texRect.maxX(), texRect.minY())), + texture->mapPixel(m2::PointF(texRect.maxX(), texRect.maxY())) + }; + + m_cacheScreen->addTexturedStripStrided(coords, sizeof(m2::PointD), + &normal, 0, + texCoords, sizeof(m2::PointF), + 4, key.m_depthLayer, res->m_pipelineID); + + m_cacheScreen->setDisplayList(NULL); + m_cacheScreen->endFrame(); + + m_dls.insert(make_pair(key, dl)); + + return dl; +} diff --git a/map/user_mark_dl_cache.hpp b/map/user_mark_dl_cache.hpp new file mode 100644 index 0000000000..0a22718be1 --- /dev/null +++ b/map/user_mark_dl_cache.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "../base/math.hpp" +#include "../graphics/defines.hpp" + +#include "../std/map.hpp" + +namespace graphics +{ + class Screen; + class DisplayList; +} + +class UserMarkDLCache +{ +public: + struct Key + { + Key(string const & name, graphics::EPosition anchor, double depthLayer) + : m_name(name), m_anchor(anchor), m_depthLayer(depthLayer) {} + + string m_name; + graphics::EPosition m_anchor; + double m_depthLayer; + + bool operator < (Key const & other) const + { + if (m_name != other.m_name) + return m_name < other.m_name; + if (!my::AlmostEqual(m_depthLayer, other.m_depthLayer)) + return m_depthLayer < other.m_depthLayer; + + return m_anchor < other.m_anchor; + } + }; + + UserMarkDLCache(graphics::Screen * cacheScreen); + ~UserMarkDLCache(); + + graphics::DisplayList * FindUserMark(Key const & key); + +private: + graphics::DisplayList * CreateDL(Key const & key); + +private: + graphics::Screen * m_cacheScreen; + typedef map cache_t; + typedef cache_t::iterator node_t; + cache_t m_dls; +};