diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 295a259809..cf12d836f9 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -7,6 +7,8 @@ #include "map/user_mark.hpp" +#include "search/everywhere_search_params.hpp" + #include "storage/storage_helpers.hpp" #include "drape_frontend/visual_params.hpp" @@ -307,10 +309,10 @@ void Framework::Scale(m2::PointD const & centerPt, int targetZoom, bool animate) return &m_work; } -bool Framework::Search(search::SearchParams const & params) +bool Framework::Search(search::EverywhereSearchParams const & params) { m_searchQuery = params.m_query; - return m_work.Search(params); + return m_work.SearchEverywhere(params); } void Framework::AddLocalMaps() diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index 1e4f34c3d6..a9b719a4f4 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -27,6 +27,11 @@ #include "std/unique_ptr.hpp" #include "std/cstdint.hpp" +namespace search +{ +struct EverywhereSearchParams; +} + namespace android { class Framework @@ -101,7 +106,7 @@ namespace android void Touch(int action, Finger const & f1, Finger const & f2, uint8_t maskedPointer); - bool Search(search::SearchParams const & params); + bool Search(search::EverywhereSearchParams const & params); string GetLastSearchQuery() { return m_searchQuery; } void ClearLastSearchQuery() { m_searchQuery.clear(); } diff --git a/android/jni/com/mapswithme/maps/SearchEngine.cpp b/android/jni/com/mapswithme/maps/SearchEngine.cpp index cdd70a9aa1..0c04e4e2bb 100644 --- a/android/jni/com/mapswithme/maps/SearchEngine.cpp +++ b/android/jni/com/mapswithme/maps/SearchEngine.cpp @@ -1,7 +1,12 @@ #include "Framework.hpp" -#include "base/thread.hpp" +#include "search/everywhere_search_params.hpp" +#include "search/mode.hpp" #include "search/result.hpp" +#include "search/viewport_search_params.hpp" + +#include "base/thread.hpp" + #include "std/atomic.hpp" #include "std/mutex.hpp" @@ -183,17 +188,14 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_search_SearchEngine_nativeRunSearch(JNIEnv * env, jclass clazz, jbyteArray bytes, jstring lang, - jlong timestamp, jboolean force, jboolean hasPosition, jdouble lat, jdouble lon) + jlong timestamp, jboolean hasPosition, jdouble lat, jdouble lon) { - search::SearchParams params; + search::EverywhereSearchParams params; params.m_query = jni::ToNativeString(env, bytes); - params.SetInputLocale(ReplaceDeprecatedLanguageCode(jni::ToNativeString(env, lang))); - params.SetForceSearch(force); - if (hasPosition) - params.SetPosition(lat, lon); + params.m_inputLocale = ReplaceDeprecatedLanguageCode(jni::ToNativeString(env, lang)); params.m_onResults = bind(&OnResults, _1, timestamp, false, hasPosition, lat, lon); - bool const searchStarted = g_framework->NativeFramework()->Search(params); + bool const searchStarted = g_framework->NativeFramework()->SearchEverywhere(params); if (searchStarted) g_queryTimestamp = timestamp; return searchStarted; @@ -203,16 +205,20 @@ extern "C" Java_com_mapswithme_maps_search_SearchEngine_nativeRunInteractiveSearch(JNIEnv * env, jclass clazz, jbyteArray bytes, jstring lang, jlong timestamp, jboolean isMapAndTable) { - search::SearchParams params; - params.m_query = jni::ToNativeString(env, bytes); - params.SetInputLocale(ReplaceDeprecatedLanguageCode(jni::ToNativeString(env, lang))); + search::ViewportSearchParams vparams; + vparams.m_query = jni::ToNativeString(env, bytes); + vparams.m_inputLocale = ReplaceDeprecatedLanguageCode(jni::ToNativeString(env, lang)); - g_framework->NativeFramework()->StartInteractiveSearch(params); + g_framework->NativeFramework()->SearchInViewport(vparams); if (isMapAndTable) { - params.m_onResults = bind(&OnResults, _1, timestamp, isMapAndTable, false /* hasPosition */, 0.0, 0.0); - if (g_framework->NativeFramework()->Search(params)) + search::EverywhereSearchParams eparams; + eparams.m_query = vparams.m_query; + eparams.m_inputLocale = vparams.m_inputLocale; + eparams.m_onResults = bind(&OnResults, _1, timestamp, isMapAndTable, false /* hasPosition */, + 0.0 /* lat */, 0.0 /* lon */); + if (g_framework->NativeFramework()->SearchEverywhere(eparams)) g_queryTimestamp = timestamp; } } @@ -256,7 +262,7 @@ extern "C" { GetPlatform().RunOnGuiThread([]() { - g_framework->NativeFramework()->CancelInteractiveSearch(); + g_framework->NativeFramework()->CancelSearch(search::Mode::Viewport); }); } } // extern "C" diff --git a/android/src/com/mapswithme/maps/search/SearchEngine.java b/android/src/com/mapswithme/maps/search/SearchEngine.java index 5c73e48d1d..b235e490b8 100644 --- a/android/src/com/mapswithme/maps/search/SearchEngine.java +++ b/android/src/com/mapswithme/maps/search/SearchEngine.java @@ -93,14 +93,13 @@ public enum SearchEngine implements NativeSearchListener, /** * @param timestamp Search results are filtered according to it after multiple requests. - * @param force Should be false for repeating requests with the same query. * @return whether search was actually started. */ - public static boolean search(String query, long timestamp, boolean force, boolean hasLocation, double lat, double lon) + public static boolean search(String query, long timestamp, boolean hasLocation, double lat, double lon) { try { - return nativeRunSearch(query.getBytes("utf-8"), Language.getKeyboardLocale(), timestamp, force, hasLocation, lat, lon); + return nativeRunSearch(query.getBytes("utf-8"), Language.getKeyboardLocale(), timestamp, hasLocation, lat, lon); } catch (UnsupportedEncodingException ignored) { } return false; @@ -155,7 +154,7 @@ public enum SearchEngine implements NativeSearchListener, /** * @param bytes utf-8 formatted bytes of query. */ - private static native boolean nativeRunSearch(byte[] bytes, String language, long timestamp, boolean force, boolean hasLocation, double lat, double lon); + private static native boolean nativeRunSearch(byte[] bytes, String language, long timestamp, boolean hasLocation, double lat, double lon); /** * @param bytes utf-8 formatted query bytes diff --git a/android/src/com/mapswithme/maps/search/SearchFragment.java b/android/src/com/mapswithme/maps/search/SearchFragment.java index dbeaa8760b..ed4749b14c 100644 --- a/android/src/com/mapswithme/maps/search/SearchFragment.java +++ b/android/src/com/mapswithme/maps/search/SearchFragment.java @@ -412,7 +412,7 @@ public class SearchFragment extends BaseMwmFragment } else { - if (!SearchEngine.search(getQuery(), mLastQueryTimestamp, true, mLastPosition.valid, mLastPosition.lat, mLastPosition.lon)) + if (!SearchEngine.search(getQuery(), mLastQueryTimestamp, mLastPosition.valid, mLastPosition.lat, mLastPosition.lon)) return; } diff --git a/android/src/com/mapswithme/maps/search/SearchResult.java b/android/src/com/mapswithme/maps/search/SearchResult.java index 5a4f5c8077..82e0ed3d10 100644 --- a/android/src/com/mapswithme/maps/search/SearchResult.java +++ b/android/src/com/mapswithme/maps/search/SearchResult.java @@ -72,4 +72,4 @@ public class SearchResult this.description = description; this.highlightRanges = highlightRanges; } -} \ No newline at end of file +} diff --git a/iphone/Maps/Classes/Search/MWMSearch.mm b/iphone/Maps/Classes/Search/MWMSearch.mm index a63d0baada..01a41b196b 100644 --- a/iphone/Maps/Classes/Search/MWMSearch.mm +++ b/iphone/Maps/Classes/Search/MWMSearch.mm @@ -5,8 +5,8 @@ #include "Framework.h" -#include "search/params.hpp" #include "search/query_saver.hpp" +#include "search/search_params.hpp" namespace { diff --git a/map/framework.cpp b/map/framework.cpp index 099fd6f8fb..5ab3159a20 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -12,12 +12,13 @@ #include "routing/routing_algorithm.hpp" #include "search/engine.hpp" +#include "search/everywhere_search_params.hpp" #include "search/geometry_utils.hpp" -#include "search/interactive_search_callback.hpp" #include "search/intermediate_result.hpp" #include "search/processor_factory.hpp" #include "search/result.hpp" #include "search/reverse_geocoder.hpp" +#include "search/viewport_search_params.hpp" #include "storage/storage_helpers.hpp" @@ -138,8 +139,7 @@ void ParseSetGpsTrackMinAccuracyCommand(string const & query) // Cancels search query by |handle|. void CancelQuery(weak_ptr & handle) { - auto queryHandle = handle.lock(); - if (queryHandle) + if (auto queryHandle = handle.lock()) queryHandle->Cancel(); handle.reset(); } @@ -504,8 +504,7 @@ bool Framework::OnCountryFileDelete(storage::TCountryId const & countryId, stora if (countryId == m_lastReportedCountry) m_lastReportedCountry = kInvalidCountryId; - if (auto handle = m_lastProcessorHandle.lock()) - handle->Cancel(); + CancelAllSearches(); m2::RectD rect = MercatorBounds::FullRect(); @@ -1045,37 +1044,6 @@ void Framework::InvalidateRect(m2::RectD const & rect) CallDrapeFunction(bind(&df::DrapeEngine::InvalidateRect, _1, rect)); } -void Framework::StartInteractiveSearch(search::SearchParams const & params) -{ - auto const originalOnResults = params.m_onResults; - - auto setMode = [this]() { - SetDisplacementMode(DisplacementModeManager::SLOT_INTERACTIVE_SEARCH, true /* show */); - }; - - auto onResults = [this, originalOnResults](search::Results const & results) { - if (!results.IsEndMarker()) - { - GetPlatform().RunOnGuiThread([this, results]() { - if (IsInteractiveSearchActive()) - FillSearchResultsMarks(results); - }); - } - - if (originalOnResults) - originalOnResults(results); - }; - - m_lastInteractiveSearchParams = params; - m_lastInteractiveSearchParams.SetForceSearch(false); - m_lastInteractiveSearchParams.SetMode(search::Mode::Viewport); - m_lastInteractiveSearchParams.SetSuggestsEnabled(false); - m_lastInteractiveSearchParams.m_onResults = - search::InteractiveSearchCallback(move(setMode), move(onResults)); - - UpdateUserViewportChanged(); -} - void Framework::ClearAllCaches() { m_model.ClearCaches(); @@ -1109,43 +1077,12 @@ void Framework::SetCurrentCountryChangedListener(TCurrentCountryChanged const & void Framework::UpdateUserViewportChanged() { - if (IsInteractiveSearchActive()) - { - (void)GetCurrentPosition(m_lastInteractiveSearchParams.m_lat, - m_lastInteractiveSearchParams.m_lon); - Search(m_lastInteractiveSearchParams); - } -} + if (!IsViewportSearchActive()) + return; -bool Framework::Search(search::SearchParams const & params) -{ -#ifdef FIXED_LOCATION - search::SearchParams rParams(params); - if (params.IsValidPosition()) - { - m_fixedPos.GetLat(rParams.m_lat); - m_fixedPos.GetLon(rParams.m_lon); - } -#else - search::SearchParams const & rParams = params; -#endif - - ParseSetGpsTrackMinAccuracyCommand(params.m_query); - if (ParseEditorDebugCommand(params)) - return true; - - m2::RectD const viewport = GetCurrentViewport(); - - if (QueryMayBeSkipped(rParams, viewport)) - return false; - - m_lastQueryParams = rParams; - m_lastQueryViewport = viewport; - - // Cancels previous search request (if any) and initiates new search request. - CancelQuery(m_lastProcessorHandle); - m_lastProcessorHandle = m_searchEngine->Search(m_lastQueryParams, m_lastQueryViewport); - return true; + auto & params = m_searchIntents[static_cast(search::Mode::Viewport)].m_params; + SetCurrentPositionIfPossible(params); + Search(params); } bool Framework::GetGroupCountryIdFromFeature(FeatureType const & ft, string & name) const @@ -1164,25 +1101,67 @@ bool Framework::GetGroupCountryIdFromFeature(FeatureType const & ft, string & na return false; } +bool Framework::SearchEverywhere(search::EverywhereSearchParams const & params) +{ + search::SearchParams p; + p.m_query = params.m_query; + p.SetInputLocale(params.m_inputLocale); + p.SetForceSearch(true); + p.SetMode(search::Mode::Everywhere); + p.SetSuggestsEnabled(true); + p.m_onResults = [params](search::Results const & results) { + if (params.m_onResults) + GetPlatform().RunOnGuiThread([params, results]() { params.m_onResults(results); }); + }; + SetCurrentPositionIfPossible(p); + + return Search(p); +} + +bool Framework::SearchInViewport(search::ViewportSearchParams const & params) +{ + search::SearchParams p; + p.m_query = params.m_query; + p.SetInputLocale(params.m_inputLocale); + p.SetForceSearch(false); + p.SetMode(search::Mode::Viewport); + p.SetSuggestsEnabled(false); + + p.m_onStarted = [params]() { + if (params.m_onStarted) + GetPlatform().RunOnGuiThread([params]() { params.m_onStarted(); }); + }; + + p.m_onResults = search::ViewportSearchCallback( + static_cast(*this), + [params](search::Results const & results) { + if (results.IsEndMarker() && params.m_onCompleted) + GetPlatform().RunOnGuiThread([params]() { params.m_onCompleted(); }); + }); + SetCurrentPositionIfPossible(p); + + return Search(p); +} + bool Framework::SearchInDownloader(DownloaderSearchParams const & params) { - search::SearchParams searchParam; - searchParam.m_query = params.m_query; - searchParam.m_inputLocale = params.m_inputLocale; - searchParam.SetMode(search::Mode::World); - searchParam.SetSuggestsEnabled(false); - searchParam.SetForceSearch(true); - searchParam.m_onResults = [this, params](search::Results const & results) + search::SearchParams p; + p.m_query = params.m_query; + p.m_inputLocale = params.m_inputLocale; + p.SetMode(search::Mode::Downloader); + p.SetSuggestsEnabled(false); + p.SetForceSearch(true); + p.m_onResults = [this, params](search::Results const & results) { DownloaderSearchResults downloaderSearchResults; - for (auto it = results.Begin(); it != results.End(); ++it) + for (auto const & result : results) { - if (!it->HasPoint()) + if (!result.HasPoint()) continue; - if (it->GetResultType() != search::Result::RESULT_LATLON) + if (result.GetResultType() != search::Result::RESULT_LATLON) { - FeatureID const & fid = it->GetFeatureID(); + FeatureID const & fid = result.GetFeatureID(); Index::FeaturesLoaderGuard loader(m_model.GetIndex(), fid.m_mwmId); FeatureType ft; if (!loader.GetFeatureByIndex(fid.m_index, ft)) @@ -1199,25 +1178,51 @@ bool Framework::SearchInDownloader(DownloaderSearchParams const & params) if (GetGroupCountryIdFromFeature(ft, groupFeatureName)) { downloaderSearchResults.m_results.emplace_back(groupFeatureName, - it->GetString() /* m_matchedName */); + result.GetString() /* m_matchedName */); continue; } } } - auto const & mercator = it->GetFeatureCenter(); + auto const & mercator = result.GetFeatureCenter(); TCountryId const & countryId = CountryInfoGetter().GetRegionCountryId(mercator); if (countryId == kInvalidCountryId) continue; downloaderSearchResults.m_results.emplace_back(countryId, - it->GetString() /* m_matchedName */); + result.GetString() /* m_matchedName */); } downloaderSearchResults.m_query = params.m_query; downloaderSearchResults.m_endMarker = results.IsEndMarker(); - params.m_onResults(downloaderSearchResults); + + if (params.m_onResults) + { + GetPlatform().RunOnGuiThread( + [params, downloaderSearchResults]() { params.m_onResults(downloaderSearchResults); }); + } }; - return Search(searchParam); + return Search(p); +} + +void Framework::CancelSearch(search::Mode mode) +{ + ASSERT_NOT_EQUAL(mode, search::Mode::Count, ()); + + if (mode == search::Mode::Viewport) + { + ClearSearchResultsMarks(); + SetDisplacementMode(DisplacementModeManager::SLOT_INTERACTIVE_SEARCH, false /* show */); + } + + auto & intent = m_searchIntents[static_cast(mode)]; + intent.m_params.Clear(); + CancelQuery(intent.m_handle); +} + +void Framework::CancelAllSearches() +{ + for (size_t i = 0; i < static_cast(search::Mode::Count); ++i) + CancelSearch(static_cast(i)); } void Framework::MemoryWarning() @@ -1307,21 +1312,64 @@ string Framework::GetCountryName(m2::PointD const & pt) const return info.m_name; } -bool Framework::QueryMayBeSkipped(search::SearchParams const & params, +bool Framework::Search(search::SearchParams const & params) +{ + auto const mode = params.GetMode(); + auto & intent = m_searchIntents[static_cast(mode)]; + +#ifdef FIXED_LOCATION + search::SearchParams rParams(params); + if (params.IsValidPosition()) + { + m_fixedPos.GetLat(rParams.m_lat); + m_fixedPos.GetLon(rParams.m_lon); + } +#else + search::SearchParams const & rParams = params; +#endif + + ParseSetGpsTrackMinAccuracyCommand(params.m_query); + if (ParseEditorDebugCommand(params)) + return true; + + m2::RectD const viewport = GetCurrentViewport(); + + if (QueryMayBeSkipped(intent, rParams, viewport)) + return false; + + intent.m_params = rParams; + intent.m_viewport = viewport; + + // Cancels previous search request (if any) and initiates new search request. + CancelQuery(intent.m_handle); + intent.m_handle = m_searchEngine->Search(intent.m_params, intent.m_viewport); + + return true; +} + +void Framework::SetCurrentPositionIfPossible(search::SearchParams & params) +{ + double lat; + double lon; + if (GetCurrentPosition(lat, lon)) + params.SetPosition(lat, lon); +} + +bool Framework::QueryMayBeSkipped(SearchIntent const & intent, search::SearchParams const & params, m2::RectD const & viewport) const { + auto const & lastParams = intent.m_params; + auto const & lastViewport = intent.m_viewport; + if (params.IsForceSearch()) return false; - if (!m_lastQueryParams.IsEqualCommon(params)) + if (!lastParams.IsEqualCommon(params)) return false; - if (!m_lastQueryViewport.IsValid() || - !search::IsEqualMercator(m_lastQueryViewport, viewport, kDistEqualQuery)) - { + if (!lastViewport.IsValid() || !search::IsEqualMercator(lastViewport, viewport, kDistEqualQuery)) return false; - } - if (!m_lastQueryParams.IsSearchAroundPosition() || - ms::DistanceOnEarth(m_lastQueryParams.m_lat, m_lastQueryParams.m_lon, params.m_lat, - params.m_lon) <= kDistEqualQuery) + if (!lastParams.IsSearchAroundPosition() || + ms::DistanceOnEarth(lastParams.m_lat, lastParams.m_lon, params.m_lat, params.m_lon) <= + kDistEqualQuery) { return false; } @@ -1330,7 +1378,7 @@ bool Framework::QueryMayBeSkipped(search::SearchParams const & params, void Framework::ShowSearchResult(search::Result const & res) { - CancelInteractiveSearch(); + CancelAllSearches(); StopLocationFollow(); alohalytics::LogEvent("searchShowResult", {{"pos", strings::to_string(res.GetPositionInResults())}, @@ -1435,7 +1483,6 @@ void Framework::FillSearchResultsMarks(search::Results const & results) UserMarkControllerGuard guard(m_bmManager, UserMarkType::SEARCH_MARK); guard.m_controller.SetIsVisible(true); guard.m_controller.SetIsDrawable(true); - guard.m_controller.Clear(); size_t const count = results.GetCount(); for (size_t i = 0; i < count; ++i) @@ -1455,15 +1502,9 @@ void Framework::FillSearchResultsMarks(search::Results const & results) } } -void Framework::CancelInteractiveSearch() +void Framework::ClearSearchResultsMarks() { UserMarkControllerGuard(m_bmManager, UserMarkType::SEARCH_MARK).m_controller.Clear(); - if (IsInteractiveSearchActive()) - { - m_lastInteractiveSearchParams.Clear(); - SetDisplacementMode(DisplacementModeManager::SLOT_INTERACTIVE_SEARCH, false /* show */); - CancelQuery(m_lastProcessorHandle); - } } bool Framework::GetDistanceAndAzimut(m2::PointD const & point, diff --git a/map/framework.hpp b/map/framework.hpp index 4c84508a66..a0f823778a 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -25,7 +25,9 @@ #include "editor/user_stats.hpp" #include "search/engine.hpp" +#include "search/mode.hpp" #include "search/query_saver.hpp" +#include "search/viewport_search_callback.hpp" #include "storage/downloader_search_params.hpp" #include "storage/downloading_policy.hpp" @@ -33,6 +35,7 @@ #include "platform/country_defines.hpp" #include "platform/location.hpp" +#include "platform/platform.hpp" #include "routing/router.hpp" #include "routing/routing_session.hpp" @@ -58,9 +61,11 @@ class EditableMapObject; namespace search { - class Result; - class Results; - struct AddressInfo; +class Result; +class Results; +struct AddressInfo; +struct EverywhereSearchParams; +struct ViewportSearchParams; } namespace storage @@ -82,7 +87,7 @@ namespace df /// build version for screenshots. //#define FIXED_LOCATION -class Framework +class Framework : public search::ViewportSearchCallback::Delegate { DISALLOW_COPY(Framework); @@ -271,6 +276,27 @@ public: BookmarkAndCategory FindBookmark(UserMark const * mark) const; BookmarkManager & GetBookmarkManager() { return m_bmManager; } +protected: + // search::ViewportSearchCallback::Delegate overrides: + void RunUITask(function fn) override { GetPlatform().RunOnGuiThread(move(fn)); } + + void SetHotelDisplacementMode() override + { + SetDisplacementMode(DisplacementModeManager::SLOT_INTERACTIVE_SEARCH, true /* show */); + } + + bool IsViewportSearchActive() const override + { + return !m_searchIntents[static_cast(search::Mode::Viewport)].m_params.m_query.empty(); + } + + void ShowViewportSearchResults(search::Results const & results) override + { + FillSearchResultsMarks(results); + } + + void ClearViewportSearchResults() override { ClearSearchResultsMarks(); } + private: void ActivateMapSelection(bool needAnimation, df::SelectionShape::ESelectedObject selectionType, @@ -386,37 +412,44 @@ public: void SetDisplacementMode(DisplacementModeManager::Slot slot, bool show); private: + struct SearchIntent + { + search::SearchParams m_params; + weak_ptr m_handle; + m2::RectD m_viewport; + }; + void InitCountryInfoGetter(); void InitSearchEngine(); DisplacementModeManager m_displacementModeManager; - // Last search query params for the interactive search. - search::SearchParams m_lastInteractiveSearchParams; - bool m_connectToGpsTrack; // need to connect to tracker when Drape is being constructed + void Search(SearchIntent const & intent); + + void SetCurrentPositionIfPossible(search::SearchParams & params); + void FillSearchResultsMarks(search::Results const & results); + void ClearSearchResultsMarks(); + void OnUpdateCurrentCountry(m2::PointF const & pt, int zoomLevel); storage::TCountryId m_lastReportedCountry; TCurrentCountryChanged m_currentCountryChanged; - // Search query params and viewport for the latest search - // query. These fields are used to check whether a new search query - // can be skipped. Note that these fields are not guarded by a mutex - // because we're assuming that they will be accessed only from the - // UI thread. - search::SearchParams m_lastQueryParams; - m2::RectD m_lastQueryViewport; + // Descriptions of last search queries for different modes. May be + // used for search requests skipping. This field is not guarded + // because it must be used from the UI thread only. + SearchIntent m_searchIntents[static_cast(search::Mode::Count)]; - // A handle for the latest search processor. - weak_ptr m_lastProcessorHandle; + bool Search(search::SearchParams const & params); // Returns true when |params| and |viewport| are almost the same as - // the latest search query's params and viewport. - bool QueryMayBeSkipped(search::SearchParams const & params, m2::RectD const & viewport) const; + // the latest search query's params and viewport in the |intent|. + bool QueryMayBeSkipped(SearchIntent const & intent, search::SearchParams const & params, + m2::RectD const & viewport) const; void OnUpdateGpsTrackPointsCallback(vector> && toAdd, pair const & toRemove); @@ -427,21 +460,23 @@ public: void UpdateUserViewportChanged(); - /// Call this function before entering search GUI. - /// While it's loading, we can cache features in viewport. - bool Search(search::SearchParams const & params); - /// Searches for mwm based on |params|. - /// Calling |params::m_onResults| for returning the result. + /// Search everywhere. + bool SearchEverywhere(search::EverywhereSearchParams const & params); + + /// Search in the viewport. + bool SearchInViewport(search::ViewportSearchParams const & params); + + /// Search for maps by countries or cities. bool SearchInDownloader(storage::DownloaderSearchParams const & params); + + void CancelSearch(search::Mode mode); + void CancelAllSearches(); + bool GetCurrentPosition(double & lat, double & lon) const; void ShowSearchResult(search::Result const & res); size_t ShowSearchResults(search::Results const & results); - void StartInteractiveSearch(search::SearchParams const & params); - bool IsInteractiveSearchActive() const { return !m_lastInteractiveSearchParams.m_query.empty(); } - void CancelInteractiveSearch(); - list const & GetLastSearchQueries() const { return m_searchQuerySaver.Get(); } void SaveSearchQuery(TSearchRequest const & query) { m_searchQuerySaver.Add(query); } void ClearSearchHistory() { m_searchQuerySaver.Clear(); } diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp index ba54ad127b..16a8c45380 100644 --- a/qt/draw_widget.cpp +++ b/qt/draw_widget.cpp @@ -458,13 +458,9 @@ void DrawWidget::wheelEvent(QWheelEvent * e) m_framework->Scale(exp(e->delta() / 360.0), m2::PointD(L2D(e->x()), L2D(e->y())), false); } -bool DrawWidget::Search(search::SearchParams params) +bool DrawWidget::Search(search::EverywhereSearchParams const & params) { - double lat, lon; - if (m_framework->GetCurrentPosition(lat, lon)) - params.SetPosition(lat, lon); - - return m_framework->Search(params); + return m_framework->SearchEverywhere(params); } string DrawWidget::GetDistance(search::Result const & res) const diff --git a/qt/draw_widget.hpp b/qt/draw_widget.hpp index 4125ffed22..ec69452f20 100644 --- a/qt/draw_widget.hpp +++ b/qt/draw_widget.hpp @@ -4,13 +4,15 @@ #include "map/framework.hpp" +#include "search/everywhere_search_params.hpp" + #include "drape_frontend/gui/skin.hpp" #include "drape_frontend/drape_engine.hpp" -#include "std/unique_ptr.hpp" -#include "std/mutex.hpp" #include "std/condition_variable.hpp" +#include "std/mutex.hpp" +#include "std/unique_ptr.hpp" #include @@ -52,7 +54,7 @@ namespace qt void SetScaleControl(QScaleSlider * pScale); - bool Search(search::SearchParams params); + bool Search(search::EverywhereSearchParams const & params); string GetDistance(search::Result const & res) const; void ShowSearchResult(search::Result const & res); diff --git a/qt/search_panel.cpp b/qt/search_panel.cpp index 65095e57b1..6cf1654c12 100644 --- a/qt/search_panel.cpp +++ b/qt/search_panel.cpp @@ -117,10 +117,8 @@ void SearchPanel::OnSearchResult(ResultsT * results) { ClearResults(); - for (ResultsT::IterT i = results->Begin(); i != results->End(); ++i) + for (auto const & res : *results) { - ResultT const & res = *i; - QString const name = QString::fromStdString(res.GetString()); QString strHigh; int pos = 0; @@ -298,7 +296,7 @@ void SearchPanel::OnSearchTextChanged(QString const & str) { ClearResults(); - m_pDrawWidget->GetFramework().CancelInteractiveSearch(); + m_pDrawWidget->GetFramework().CancelSearch(search::Mode::Everywhere); // hide X button m_pClearButton->setVisible(false); @@ -324,7 +322,7 @@ void SearchPanel::OnSearchPanelItemClicked(int row, int) void SearchPanel::hideEvent(QHideEvent *) { - m_pDrawWidget->GetFramework().CancelInteractiveSearch(); + m_pDrawWidget->GetFramework().CancelSearch(search::Mode::Everywhere); } void SearchPanel::OnAnimationTimer() diff --git a/qt/search_panel.hpp b/qt/search_panel.hpp index d1ff5ad1bc..1d253481fb 100644 --- a/qt/search_panel.hpp +++ b/qt/search_panel.hpp @@ -1,7 +1,7 @@ #pragma once #include "search/result.hpp" -#include "search/params.hpp" +#include "search/everywhere_search_params.hpp" #include "std/vector.hpp" @@ -37,7 +37,7 @@ class SearchPanel : public QWidget typedef search::Result ResultT; vector m_results; - search::SearchParams m_params; + search::EverywhereSearchParams m_params; Q_OBJECT diff --git a/search/engine.cpp b/search/engine.cpp index 97b63a2ea2..0f8c129a77 100644 --- a/search/engine.cpp +++ b/search/engine.cpp @@ -1,8 +1,8 @@ #include "search/engine.hpp" #include "search/geometry_utils.hpp" -#include "search/params.hpp" #include "search/processor.hpp" +#include "search/search_params.hpp" #include "storage/country_info_getter.hpp" diff --git a/search/engine.hpp b/search/engine.hpp index 4760d9ba68..d46faa5a7e 100644 --- a/search/engine.hpp +++ b/search/engine.hpp @@ -1,9 +1,9 @@ #pragma once -#include "params.hpp" -#include "processor_factory.hpp" -#include "result.hpp" -#include "suggest.hpp" +#include "search/processor_factory.hpp" +#include "search/result.hpp" +#include "search/search_params.hpp" +#include "search/suggest.hpp" #include "indexer/categories_holder.hpp" diff --git a/search/everywhere_search_params.hpp b/search/everywhere_search_params.hpp new file mode 100644 index 0000000000..f3df639644 --- /dev/null +++ b/search/everywhere_search_params.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "search/search_params.hpp" + +#include "std/string.hpp" + +namespace search +{ +struct EverywhereSearchParams +{ + string m_query; + string m_inputLocale; + + SearchParams::TOnResults m_onResults; +}; +} // namespace search diff --git a/search/geocoder.cpp b/search/geocoder.cpp index 8ff1add25c..cea3c3f4f9 100644 --- a/search/geocoder.cpp +++ b/search/geocoder.cpp @@ -411,6 +411,7 @@ void UniteCBVs(vector & cbvs) // Geocoder::Params -------------------------------------------------------------------------------- Geocoder::Params::Params() : m_mode(Mode::Everywhere) {} + // Geocoder::Geocoder ------------------------------------------------------------------------------ Geocoder::Geocoder(Index const & index, storage::CountryInfoGetter const & infoGetter, PreRanker & preRanker, my::Cancellable const & cancellable) @@ -850,7 +851,7 @@ void Geocoder::ForEachCountry(vector> const & infos, TFn && auto const & info = infos[i]; if (info->GetType() != MwmInfo::COUNTRY && info->GetType() != MwmInfo::WORLD) continue; - if (info->GetType() == MwmInfo::COUNTRY && m_params.m_mode == Mode::World) + if (info->GetType() == MwmInfo::COUNTRY && m_params.m_mode == Mode::Downloader) continue; auto handle = m_index.GetMwmHandleById(MwmSet::MwmId(info)); diff --git a/search/interactive_search_callback.cpp b/search/interactive_search_callback.cpp deleted file mode 100644 index d7981bab4d..0000000000 --- a/search/interactive_search_callback.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "search/interactive_search_callback.hpp" - -#include "search/result.hpp" - -namespace search -{ -InteractiveSearchCallback::InteractiveSearchCallback(TSetDisplacementMode && setMode, - TOnResults && onResults) - : m_setMode(move(setMode)), m_onResults(move(onResults)), m_hotelsModeSet(false) -{ -} - -void InteractiveSearchCallback::operator()(search::Results const & results) -{ - m_hotelsClassif.AddBatch(results); - - if (!m_hotelsModeSet && m_hotelsClassif.IsHotelQuery()) - { - m_setMode(); - m_hotelsModeSet = true; - } - - m_onResults(results); -} -} // namespace search diff --git a/search/interactive_search_callback.hpp b/search/interactive_search_callback.hpp deleted file mode 100644 index 8d42f537a0..0000000000 --- a/search/interactive_search_callback.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "search/hotels_classifier.hpp" -#include "search/params.hpp" - -#include "std/function.hpp" - -namespace search -{ -class Results; - -// An on-results-callback that should be used for interactive search. -// -// *NOTE* the class is NOT thread safe. -class InteractiveSearchCallback -{ -public: - using TSetDisplacementMode = function; - using TOnResults = search::TOnResults; - - InteractiveSearchCallback(TSetDisplacementMode && setMode, TOnResults && onResults); - - void operator()(search::Results const & results); - -private: - TSetDisplacementMode m_setMode; - TOnResults m_onResults; - - search::HotelsClassifier m_hotelsClassif; - bool m_hotelsModeSet; -}; -} // namespace search diff --git a/search/mode.cpp b/search/mode.cpp index 59c7eb751b..bd2bdc8c81 100644 --- a/search/mode.cpp +++ b/search/mode.cpp @@ -6,9 +6,10 @@ string DebugPrint(Mode mode) { switch (mode) { - case Mode::Viewport: return "Viewport"; case Mode::Everywhere: return "Everywhere"; - case Mode::World: return "World"; + case Mode::Viewport: return "Viewport"; + case Mode::Downloader: return "Downloader"; + case Mode::Count: return "Count"; } return "Unknown"; } diff --git a/search/mode.hpp b/search/mode.hpp index 0b3b00cfbe..d5e6dabf10 100644 --- a/search/mode.hpp +++ b/search/mode.hpp @@ -6,9 +6,10 @@ namespace search { enum class Mode { - Viewport, Everywhere, - World + Viewport, + Downloader, + Count }; string DebugPrint(Mode mode); diff --git a/search/params.hpp b/search/params.hpp deleted file mode 100644 index 0c688a1e3b..0000000000 --- a/search/params.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include "search/mode.hpp" - -#include "geometry/point2d.hpp" -#include "geometry/rect2d.hpp" - -#include "std/function.hpp" -#include "std/string.hpp" - - -namespace search -{ - class Results; - - using TOnStarted = function; - using TOnResults = function; - - class SearchParams - { - public: - SearchParams(); - - /// @name Force run search without comparing with previous search params. - //@{ - void SetForceSearch(bool b) { m_forceSearch = b; } - bool IsForceSearch() const { return m_forceSearch; } - //@} - - inline void SetMode(Mode mode) { m_mode = mode; } - inline Mode GetMode() const { return m_mode; } - - void SetPosition(double lat, double lon); - inline bool IsValidPosition() const { return m_validPos; } - inline bool IsSearchAroundPosition() const - { - return (m_searchRadiusM > 0 && IsValidPosition()); - } - - inline void SetSearchRadiusMeters(double radiusM) { m_searchRadiusM = radiusM; } - bool GetSearchRect(m2::RectD & rect) const; - - /// @param[in] locale can be "fr", "en-US", "ru_RU" etc. - inline void SetInputLocale(string const & locale) { m_inputLocale = locale; } - - inline void SetSuggestsEnabled(bool enabled) { m_suggestsEnabled = enabled; } - inline bool GetSuggestsEnabled() const { return m_suggestsEnabled; } - - bool IsEqualCommon(SearchParams const & rhs) const; - - inline void Clear() { m_query.clear(); } - - TOnStarted m_onStarted; - TOnResults m_onResults; - - string m_query; - string m_inputLocale; - - double m_lat, m_lon; - - friend string DebugPrint(SearchParams const & params); - - private: - double m_searchRadiusM; - Mode m_mode; - bool m_forceSearch; - bool m_validPos; - bool m_suggestsEnabled; - }; -} // namespace search diff --git a/search/processor.hpp b/search/processor.hpp index ddc340556e..d28c43c4ab 100644 --- a/search/processor.hpp +++ b/search/processor.hpp @@ -1,10 +1,10 @@ #pragma once #include "search/geocoder.hpp" #include "search/mode.hpp" -#include "search/params.hpp" #include "search/pre_ranker.hpp" -#include "search/ranker.hpp" #include "search/rank_table_cache.hpp" +#include "search/ranker.hpp" +#include "search/search_params.hpp" #include "search/search_trie.hpp" #include "search/suggest.hpp" #include "search/token_slice.hpp" @@ -84,7 +84,7 @@ public: inline void SetMode(Mode mode) { m_mode = mode; } inline void SetSuggestsEnabled(bool enabled) { m_suggestsEnabled = enabled; } inline void SetPosition(m2::PointD const & position) { m_position = position; } - inline void SetOnResults(TOnResults const & onResults) { m_onResults = onResults; } + inline void SetOnResults(SearchParams::TOnResults const & onResults) { m_onResults = onResults; } inline string const & GetPivotRegion() const { return m_region; } inline m2::PointD const & GetPosition() const { return m_position; } @@ -152,7 +152,7 @@ protected: m2::PointD m_position; Mode m_mode; bool m_suggestsEnabled; - TOnResults m_onResults; + SearchParams::TOnResults m_onResults; /// @name Get ranking params. //@{ diff --git a/search/processor_factory.hpp b/search/processor_factory.hpp index 4eeb8cec74..b8946f6d23 100644 --- a/search/processor_factory.hpp +++ b/search/processor_factory.hpp @@ -1,7 +1,7 @@ #pragma once -#include "search/params.hpp" #include "search/processor.hpp" +#include "search/search_params.hpp" #include "search/suggest.hpp" #include "std/unique_ptr.hpp" diff --git a/search/ranker.hpp b/search/ranker.hpp index fbea55b50c..9f81147177 100644 --- a/search/ranker.hpp +++ b/search/ranker.hpp @@ -6,9 +6,9 @@ #include "search/keyword_lang_matcher.hpp" #include "search/locality_finder.hpp" #include "search/mode.hpp" -#include "search/params.hpp" #include "search/result.hpp" #include "search/reverse_geocoder.hpp" +#include "search/search_params.hpp" #include "search/suggest.hpp" #include "indexer/categories_holder.hpp" @@ -62,7 +62,7 @@ public: TLocales m_categoryLocales; size_t m_limit = 0; - TOnResults m_onResults; + SearchParams::TOnResults m_onResults; }; static size_t const kBatchSize; diff --git a/search/result.cpp b/search/result.cpp index 0fad1be9e5..6a9a00f3cc 100644 --- a/search/result.cpp +++ b/search/result.cpp @@ -319,10 +319,10 @@ string DebugPrint(AddressInfo const & info) return info.FormatNameAndAddress(); } -string DebugPrint(Result const & r) +string DebugPrint(Result const & result) { - return "Result { Name: " + r.GetString() + "; Type: " + r.GetFeatureType() + - "; Info: " + DebugPrint(r.GetRankingInfo()) + " }"; + return "Result { Name: " + result.GetString() + "; Type: " + result.GetFeatureType() + + "; Info: " + DebugPrint(result.GetRankingInfo()) + " }"; } } // namespace search diff --git a/search/result.hpp b/search/result.hpp index e541c9b1f4..916d28726d 100644 --- a/search/result.hpp +++ b/search/result.hpp @@ -15,7 +15,6 @@ namespace search { - // Search result. Search returns a list of them, ordered by score. class Result { @@ -152,14 +151,14 @@ class Results 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); } - //@} + bool IsEndedCancelled() const { return m_status == ENDED_CANCELLED; } bool AddResult(Result && res); + /// Fast function that don't do any duplicates checks. /// Used in viewport search only. void AddResultNoChecks(Result && res) @@ -172,8 +171,6 @@ public: inline void Clear() { m_vec.clear(); } typedef vector::const_iterator IterT; - inline IterT Begin() const { return m_vec.begin(); } - inline IterT End() const { return m_vec.end(); } inline IterT begin() const { return m_vec.begin(); } inline IterT end() const { return m_vec.end(); } @@ -221,11 +218,10 @@ struct AddressInfo // Caroline, 7 vulica Frunze, Minsk, Belarus string FormatNameAndAddress(AddressType type = DEFAULT) const; - friend string DebugPrint(AddressInfo const & info); - void Clear(); + + friend string DebugPrint(AddressInfo const & info); }; -string DebugPrint(search::Result const &); - +string DebugPrint(search::Result const & result); } // namespace search diff --git a/search/search.pro b/search/search.pro index 3f50c1dadf..6827455004 100644 --- a/search/search.pro +++ b/search/search.pro @@ -16,6 +16,7 @@ HEADERS += \ common.hpp \ dummy_rank_table.hpp \ engine.hpp \ + everywhere_search_params.hpp \ feature_offset_match.hpp \ features_filter.hpp \ features_layer.hpp \ @@ -29,7 +30,6 @@ HEADERS += \ house_detector.hpp \ house_numbers_matcher.hpp \ house_to_street_table.hpp \ - interactive_search_callback.hpp \ intermediate_result.hpp \ intersection_result.hpp \ interval_set.hpp \ @@ -44,7 +44,6 @@ HEADERS += \ model.hpp \ mwm_context.hpp \ nested_rects_cache.hpp \ - params.hpp \ pre_ranker.hpp \ pre_ranking_info.hpp \ processor.hpp \ @@ -61,6 +60,7 @@ HEADERS += \ retrieval.hpp \ reverse_geocoder.hpp \ search_index_values.hpp \ + search_params.hpp \ search_trie.hpp \ stats_cache.hpp \ street_vicinity_loader.hpp \ @@ -70,6 +70,8 @@ HEADERS += \ token_slice.hpp \ types_skipper.hpp \ utils.hpp \ + viewport_search_callback.hpp \ + viewport_search_params.hpp SOURCES += \ approximate_string_match.cpp \ @@ -88,7 +90,6 @@ SOURCES += \ house_detector.cpp \ house_numbers_matcher.cpp \ house_to_street_table.cpp \ - interactive_search_callback.cpp \ intermediate_result.cpp \ intersection_result.cpp \ keyword_lang_matcher.cpp \ @@ -102,7 +103,6 @@ SOURCES += \ model.cpp \ mwm_context.cpp \ nested_rects_cache.cpp \ - params.cpp \ pre_ranker.cpp \ pre_ranking_info.cpp \ processor.cpp \ @@ -117,7 +117,9 @@ SOURCES += \ result.cpp \ retrieval.cpp \ reverse_geocoder.cpp \ + search_params.cpp \ street_vicinity_loader.cpp \ streets_matcher.cpp \ token_slice.cpp \ types_skipper.cpp \ + viewport_search_callback.cpp diff --git a/search/search_integration_tests/interactive_search_test.cpp b/search/search_integration_tests/interactive_search_test.cpp index d7b28ac138..f344973861 100644 --- a/search/search_integration_tests/interactive_search_test.cpp +++ b/search/search_integration_tests/interactive_search_test.cpp @@ -2,7 +2,7 @@ #include "generator/generator_tests_support/test_feature.hpp" -#include "search/interactive_search_callback.hpp" +#include "search/viewport_search_callback.hpp" #include "search/mode.hpp" #include "search/search_integration_tests/helpers.hpp" #include "search/search_tests_support/test_results_matching.hpp" @@ -37,16 +37,33 @@ public: } }; -class InteractiveSearchRequest : public TestSearchRequest +class TestDelegate : public ViewportSearchCallback::Delegate +{ +public: + TestDelegate(bool & mode) : m_mode(mode) {} + + // ViewportSearchCallback::Delegate overrides: + void RunUITask(function /* fn */) override {} + void SetHotelDisplacementMode() override { m_mode = true; } + bool IsViewportSearchActive() const override { return true; } + void ShowViewportSearchResults(Results const & /* results */) override {} + void ClearViewportSearchResults() override {} + + private: + bool & m_mode; +}; + +class InteractiveSearchRequest : public TestDelegate, public TestSearchRequest { public: InteractiveSearchRequest(TestSearchEngine & engine, string const & query, m2::RectD const & viewport, bool & mode) - : TestSearchRequest( + : TestDelegate(mode) + , TestSearchRequest( engine, query, "en" /* locale */, Mode::Viewport, viewport, bind(&InteractiveSearchRequest::OnStarted, this), - InteractiveSearchCallback([&mode]() { mode = true; }, - bind(&InteractiveSearchRequest::OnResults, this, _1))) + ViewportSearchCallback(static_cast(*this), + bind(&InteractiveSearchRequest::OnResults, this, _1))) { } }; diff --git a/search/search_integration_tests/processor_test.cpp b/search/search_integration_tests/processor_test.cpp index 93d979cfa0..1797aa81bc 100644 --- a/search/search_integration_tests/processor_test.cpp +++ b/search/search_integration_tests/processor_test.cpp @@ -267,7 +267,7 @@ UNIT_CLASS_TEST(ProcessorTest, SearchByName) SetViewport(m2::RectD(m2::PointD(0.5, 0.5), m2::PointD(1.5, 1.5))); { TRules rules = {ExactMatch(worldId, london)}; - TEST(ResultsMatch("london", Mode::World, rules), ()); + TEST(ResultsMatch("london", Mode::Downloader, rules), ()); } { TRules rules = {ExactMatch(worldId, london), ExactMatch(wonderlandId, cafe)}; @@ -291,7 +291,7 @@ UNIT_CLASS_TEST(ProcessorTest, DisableSuggests) SearchParams params; params.m_query = "londo"; params.m_inputLocale = "en"; - params.SetMode(Mode::World); + params.SetMode(Mode::Downloader); params.SetSuggestsEnabled(false); TestSearchRequest request(m_engine, params, m_viewport); diff --git a/search/params.cpp b/search/search_params.cpp similarity index 82% rename from search/params.cpp rename to search/search_params.cpp index fa47eb86c7..aa8d490dd9 100644 --- a/search/params.cpp +++ b/search/search_params.cpp @@ -1,10 +1,9 @@ -#include "params.hpp" +#include "search/search_params.hpp" #include "geometry/mercator.hpp" #include "coding/multilang_utf8_string.hpp" - namespace search { SearchParams::SearchParams() @@ -37,10 +36,8 @@ bool SearchParams::GetSearchRect(m2::RectD & rect) const bool SearchParams::IsEqualCommon(SearchParams const & rhs) const { - return (m_query == rhs.m_query && - m_inputLocale == rhs.m_inputLocale && - m_validPos == rhs.m_validPos && - m_mode == rhs.m_mode && + return (m_query == rhs.m_query && m_inputLocale == rhs.m_inputLocale && + m_validPos == rhs.m_validPos && m_mode == rhs.m_mode && m_searchRadiusM == rhs.m_searchRadiusM); } @@ -51,4 +48,4 @@ string DebugPrint(SearchParams const & params) << ", Mode = " << DebugPrint(params.m_mode) << " }"; return ss.str(); } -} // namespace search +} // namespace search diff --git a/search/search_params.hpp b/search/search_params.hpp new file mode 100644 index 0000000000..d3de882ee9 --- /dev/null +++ b/search/search_params.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include "search/mode.hpp" + +#include "geometry/point2d.hpp" +#include "geometry/rect2d.hpp" + +#include "std/function.hpp" +#include "std/string.hpp" + +namespace search +{ +class Results; + +class SearchParams +{ +public: + using TOnStarted = function; + using TOnResults = function; + + SearchParams(); + + /// @name Force run search without comparing with previous search params. + //@{ + void SetForceSearch(bool b) { m_forceSearch = b; } + bool IsForceSearch() const { return m_forceSearch; } + //@} + + inline void SetMode(Mode mode) { m_mode = mode; } + inline Mode GetMode() const { return m_mode; } + void SetPosition(double lat, double lon); + inline bool IsValidPosition() const { return m_validPos; } + inline bool IsSearchAroundPosition() const { return (m_searchRadiusM > 0 && IsValidPosition()); } + inline void SetSearchRadiusMeters(double radiusM) { m_searchRadiusM = radiusM; } + bool GetSearchRect(m2::RectD & rect) const; + + /// @param[in] locale can be "fr", "en-US", "ru_RU" etc. + inline void SetInputLocale(string const & locale) { m_inputLocale = locale; } + inline void SetSuggestsEnabled(bool enabled) { m_suggestsEnabled = enabled; } + inline bool GetSuggestsEnabled() const { return m_suggestsEnabled; } + bool IsEqualCommon(SearchParams const & rhs) const; + + inline void Clear() { m_query.clear(); } + TOnStarted m_onStarted; + TOnResults m_onResults; + + string m_query; + string m_inputLocale; + + double m_lat, m_lon; + + friend string DebugPrint(SearchParams const & params); + +private: + double m_searchRadiusM; + Mode m_mode; + bool m_forceSearch; + bool m_validPos; + bool m_suggestsEnabled; +}; +} // namespace search diff --git a/search/search_quality/search_quality_tool/search_quality_tool.cpp b/search/search_quality/search_quality_tool/search_quality_tool.cpp index 19b06c93e6..5be0d527ea 100644 --- a/search/search_quality/search_quality_tool/search_quality_tool.cpp +++ b/search/search_quality/search_quality_tool/search_quality_tool.cpp @@ -1,4 +1,4 @@ -#include "search/params.hpp" +#include "search/search_params.hpp" #include "indexer/classificator_loader.hpp" #include "indexer/data_header.hpp" diff --git a/search/search_tests_support/test_search_request.cpp b/search/search_tests_support/test_search_request.cpp index 1c7f50d3ac..fc0b99c90c 100644 --- a/search/search_tests_support/test_search_request.cpp +++ b/search/search_tests_support/test_search_request.cpp @@ -31,7 +31,8 @@ TestSearchRequest::TestSearchRequest(TestSearchEngine & engine, SearchParams par TestSearchRequest::TestSearchRequest(TestSearchEngine & engine, string const & query, string const & locale, Mode mode, m2::RectD const & viewport, - TOnStarted onStarted, TOnResults onResults) + SearchParams::TOnStarted onStarted, + SearchParams::TOnResults onResults) { SearchParams params; params.m_query = query; @@ -88,7 +89,7 @@ void TestSearchRequest::OnResults(search::Results const & results) } else { - m_results.assign(results.Begin(), results.End()); + m_results.assign(results.begin(), results.end()); } } } // namespace tests_support diff --git a/search/search_tests_support/test_search_request.hpp b/search/search_tests_support/test_search_request.hpp index 4b86d5a3e2..5da71d2336 100644 --- a/search/search_tests_support/test_search_request.hpp +++ b/search/search_tests_support/test_search_request.hpp @@ -2,8 +2,8 @@ #include "geometry/rect2d.hpp" -#include "search/params.hpp" #include "search/result.hpp" +#include "search/search_params.hpp" #include "std/condition_variable.hpp" #include "std/mutex.hpp" @@ -36,8 +36,8 @@ public: protected: TestSearchRequest(TestSearchEngine & engine, string const & query, string const & locale, - Mode mode, m2::RectD const & viewport, TOnStarted onStarted, - TOnResults onResults); + Mode mode, m2::RectD const & viewport, SearchParams::TOnStarted onStarted, + SearchParams::TOnResults onResults); void SetUpCallbacks(SearchParams & params); diff --git a/search/viewport_search_callback.cpp b/search/viewport_search_callback.cpp new file mode 100644 index 0000000000..6fce48768b --- /dev/null +++ b/search/viewport_search_callback.cpp @@ -0,0 +1,43 @@ +#include "search/viewport_search_callback.hpp" + +#include "search/result.hpp" + +namespace search +{ +ViewportSearchCallback::ViewportSearchCallback(Delegate & delegate, TOnResults onResults) + : m_delegate(delegate), m_onResults(move(onResults)), m_hotelsModeSet(false), m_firstCall(true) +{ +} + +void ViewportSearchCallback::operator()(Results const & results) +{ + m_hotelsClassif.AddBatch(results); + + if (!m_hotelsModeSet && m_hotelsClassif.IsHotelQuery()) + { + m_delegate.SetHotelDisplacementMode(); + m_hotelsModeSet = true; + } + + if (!results.IsEndMarker()) + { + auto & delegate = m_delegate; + bool const firstCall = m_firstCall; + + m_delegate.RunUITask([&delegate, firstCall, results]() { + if (!delegate.IsViewportSearchActive()) + return; + + if (firstCall) + delegate.ClearViewportSearchResults(); + + delegate.ShowViewportSearchResults(results); + }); + } + + if (m_onResults) + m_onResults(results); + + m_firstCall = false; +} +} // namespace search diff --git a/search/viewport_search_callback.hpp b/search/viewport_search_callback.hpp new file mode 100644 index 0000000000..ffc4c25c02 --- /dev/null +++ b/search/viewport_search_callback.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "search/hotels_classifier.hpp" +#include "search/search_params.hpp" + +#include "std/function.hpp" + +namespace search +{ +class Results; + +// An on-results-callback that should be used for interactive search. +// +// *NOTE* the class is NOT thread safe. +class ViewportSearchCallback +{ +public: + class Delegate + { + public: + virtual ~Delegate() = default; + + virtual void RunUITask(function fn) = 0; + virtual void SetHotelDisplacementMode() = 0; + virtual bool IsViewportSearchActive() const = 0; + virtual void ShowViewportSearchResults(Results const & results) = 0; + virtual void ClearViewportSearchResults() = 0; + }; + + using TOnResults = SearchParams::TOnResults; + + ViewportSearchCallback(Delegate & delegate, TOnResults onResults); + + void operator()(Results const & results); + +private: + Delegate & m_delegate; + TOnResults m_onResults; + + HotelsClassifier m_hotelsClassif; + bool m_hotelsModeSet; + bool m_firstCall; +}; +} // namespace search diff --git a/search/viewport_search_params.hpp b/search/viewport_search_params.hpp new file mode 100644 index 0000000000..5067ef5eb4 --- /dev/null +++ b/search/viewport_search_params.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "std/function.hpp" +#include "std/string.hpp" + +namespace search +{ +struct ViewportSearchParams +{ + using TOnStarted = function; + using TOnCompleted = function; + + string m_query; + string m_inputLocale; + + TOnStarted m_onStarted; + TOnCompleted m_onCompleted; +}; +} // namespace search