From 95e92382d503239bf76e926dce0aec959116a66f Mon Sep 17 00:00:00 2001 From: vng Date: Thu, 18 Oct 2012 19:54:28 +0300 Subject: Emit "end search marker" with cancelled flag. It helps to determine whether the indicator should be shown. --- android/jni/com/mapswithme/maps/SearchActivity.cpp | 7 ++ iphone/Maps/Classes/SearchVC.mm | 75 +++++++++++++++------- search/result.hpp | 21 ++++++ search/search_engine.cpp | 6 ++ 4 files changed, 85 insertions(+), 24 deletions(-) diff --git a/android/jni/com/mapswithme/maps/SearchActivity.cpp b/android/jni/com/mapswithme/maps/SearchActivity.cpp index 97677c6f52..c9509744ef 100644 --- a/android/jni/com/mapswithme/maps/SearchActivity.cpp +++ b/android/jni/com/mapswithme/maps/SearchActivity.cpp @@ -29,6 +29,13 @@ class SearchAdapter void OnResults(search::Results const & res, int queryID) { + if (res.IsEndMarker()) + { + /// @todo Process end markers for Android in future. + /// It's not so necessary now because we store search ID's. + return; + } + if (s_pInstance == 0) { // In case when activity is destroyed, but search thread passed any results. diff --git a/iphone/Maps/Classes/SearchVC.mm b/iphone/Maps/Classes/SearchVC.mm index 963ae928bc..46c0b16f4b 100644 --- a/iphone/Maps/Classes/SearchVC.mm +++ b/iphone/Maps/Classes/SearchVC.mm @@ -30,43 +30,63 @@ SearchVC * g_searchVC = nil; @interface ResultsWrapper : NSObject { - vector m_results; - NSString * m_searchString; + search::Results m_results; } // Stores search string which corresponds to these results. -@property(nonatomic, retain) NSString * m_searchString; +@property(nonatomic, retain) NSString * searchString; - (id)initWithResults:(search::Results const &)res; -- (vector const &)get; + +- (int)getCount; +- (search::Result const &)getWithPosition:(int)pos; + +- (BOOL)isEndMarker; +- (BOOL)isEndedNormal; @end @implementation ResultsWrapper -@synthesize m_searchString; +@synthesize searchString; - (void)dealloc { - [m_searchString release]; + [searchString release]; [super dealloc]; } - (id)initWithResults:(search::Results const &)res { if ((self = [super init])) - m_results.assign(res.Begin(), res.End()); + m_results = res; return self; } -- (vector const &)get +- (int)getCount +{ + return static_cast(m_results.GetCount()); +} + +- (search::Result const &)getWithPosition:(int)pos +{ + return m_results.GetResult(pos); +} + +- (BOOL)isEndMarker +{ + return m_results.IsEndMarker(); +} + +- (BOOL)isEndedNormal { - return m_results; + return m_results.IsEndedNormal(); } + @end -// Last search results are stored betweel SearchVC sessions -// to appear instantly for the user, they also store last search text query +// Last search results are stored between SearchVC sessions +// to appear instantly for the user, they also store last search text query. ResultsWrapper * g_lastSearchResults = nil; static void OnSearchResultCallback(search::Results const & res) @@ -148,7 +168,7 @@ static void OnSearchResultCallback(search::Results const & res) m_searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; // restore previous search query if (g_lastSearchResults) - m_searchBar.text = g_lastSearchResults.m_searchString; + m_searchBar.text = g_lastSearchResults.searchString; m_searchBar.delegate = self; m_searchBar.placeholder = NSLocalizedString(@"search_map", @"Search box placeholder text"); item.titleView = m_searchBar; @@ -303,7 +323,7 @@ static void OnSearchResultCallback(search::Results const & res) { m_suggestionsCount = [m_searchBar.text length] ? 0 : 1; if (g_lastSearchResults) - return [g_lastSearchResults get].size() + m_suggestionsCount; + return [g_lastSearchResults getCount] + m_suggestionsCount; else return 0 + m_suggestionsCount; } @@ -335,13 +355,13 @@ static void OnSearchResultCallback(search::Results const & res) realRowIndex -= m_suggestionsCount; } - if (g_lastSearchResults == nil || realRowIndex >= (NSInteger)[g_lastSearchResults get].size()) + if (g_lastSearchResults == nil || realRowIndex >= (NSInteger)[g_lastSearchResults getCount]) { - ASSERT(false, ("Invalid m_results with size", [g_lastSearchResults get].size())); + ASSERT(false, ("Invalid m_results with size", [g_lastSearchResults getCount])); return nil; } - search::Result const & r = [g_lastSearchResults get][realRowIndex]; + search::Result const & r = [g_lastSearchResults getWithPosition:realRowIndex]; switch (r.GetResultType()) { case search::Result::RESULT_FEATURE: @@ -435,9 +455,9 @@ static void OnSearchResultCallback(search::Results const & res) realRowIndex -= m_suggestionsCount; } - if (realRowIndex < (NSInteger)[g_lastSearchResults get].size()) + if (realRowIndex < (NSInteger)[g_lastSearchResults getCount]) { - search::Result const & res = [g_lastSearchResults get][realRowIndex]; + search::Result const & res = [g_lastSearchResults getWithPosition:realRowIndex]; switch(res.GetResultType()) { // Zoom to the feature @@ -468,13 +488,20 @@ static void OnSearchResultCallback(search::Results const & res) { ResultsWrapper * w = (ResultsWrapper *)res; - [g_lastSearchResults release]; - g_lastSearchResults = [w retain]; + if ([w isEndMarker]) + { + if ([w isEndedNormal]) + [self hideIndicator]; + } + else + { + [g_lastSearchResults release]; + g_lastSearchResults = [w retain]; - w.m_searchString = m_searchBar.text; + w.searchString = m_searchBar.text; - [self hideIndicator]; - [m_table reloadData]; + [m_table reloadData]; + } } //****************************************************************** @@ -519,7 +546,7 @@ static void OnSearchResultCallback(search::Results const & res) realRowIndex -= m_suggestionsCount; } - search::Result const & res = [g_lastSearchResults get][realRowIndex]; + search::Result const & res = [g_lastSearchResults getWithPosition:realRowIndex]; if (res.GetResultType() == search::Result::RESULT_FEATURE) { // Show compass only for cells without flags diff --git a/search/result.hpp b/search/result.hpp index 697e810c19..6a1326b804 100644 --- a/search/result.hpp +++ b/search/result.hpp @@ -57,7 +57,28 @@ class Results { vector m_vec; + enum StatusT { + NONE, // default status + ENDED_CANCELLED, // search ended with canceling + ENDED // search ended itself + }; + StatusT m_status; + + explicit Results(bool isCancelled) + { + m_status = (isCancelled ? ENDED_CANCELLED : ENDED); + } + public: + Results() : m_status(NONE) {} + + /// @name To implement end of search notification. + //@{ + static Results GetEndMarker(bool isCancelled) { return Results(isCancelled); } + bool IsEndMarker() const { return (m_status != NONE); } + bool IsEndedNormal() const { return (m_status == ENDED); } + //@} + inline void AddResult(Result const & r) { m_vec.push_back(r); } void AddResultCheckExisting(Result const & r); diff --git a/search/search_engine.cpp b/search/search_engine.cpp index 4f7b150382..078c845d04 100644 --- a/search/search_engine.cpp +++ b/search/search_engine.cpp @@ -246,6 +246,9 @@ void Engine::SearchAsync() Results res; + // Call m_pQuery->IsCanceled() everywhere it needed without storing return value. + // This flag can be changed from another thread. + try { if (params.m_query.empty()) @@ -291,6 +294,9 @@ void Engine::SearchAsync() if (res.GetCount() > count) params.m_callback(res); } + + // Emit finish marker to client. + params.m_callback(Results::GetEndMarker(m_pQuery->IsCanceled())); } string Engine::GetCountryFile(m2::PointD const & pt) -- cgit v1.2.3