diff --git a/android/jni/com/mapswithme/maps/SearchEngine.cpp b/android/jni/com/mapswithme/maps/SearchEngine.cpp index ad5c8e87de..0f42c5ca3c 100644 --- a/android/jni/com/mapswithme/maps/SearchEngine.cpp +++ b/android/jni/com/mapswithme/maps/SearchEngine.cpp @@ -288,7 +288,7 @@ public: booking::AvailabilityParams::Room room; room.SetAdultsCount(static_cast(env->GetIntField(jroom, m_roomAdultsCountId))); room.SetAgeOfChild(static_cast(env->GetIntField(jroom, m_roomAgeOfChildId))); - result.m_rooms[i] = std::move(room); + result.m_rooms[i] = move(room); } return result; @@ -332,7 +332,7 @@ jmethodID g_mapResultCtor; booking::AvailabilityParams g_lastBookingFilterParams; -jobject ToJavaResult(Result & result, bool isLocalAdsCustomer, float ugcRating, bool hasPosition, +jobject ToJavaResult(Result & result, search::ProductInfo const & productInfo, bool hasPosition, double lat, double lon) { JNIEnv * env = jni::GetEnv(); @@ -376,10 +376,10 @@ jobject ToJavaResult(Result & result, bool isLocalAdsCustomer, float ugcRating, jni::TScopedLocalRef cuisine(env, jni::ToJavaString(env, result.GetCuisine())); jni::TScopedLocalRef pricing(env, jni::ToJavaString(env, result.GetHotelApproximatePricing())); - string ratingTmp = result.GetHotelRating(); - if (ratingTmp.empty() && ugcRating > 0.f) - ratingTmp = place_page::rating::GetRatingFormatted(ugcRating); - jni::TScopedLocalRef rating(env, jni::ToJavaString(env, ratingTmp)); + string ratingStr = result.GetHotelRating(); + if (ratingStr.empty() && productInfo.m_ugcRating != search::ProductInfo::kInvalidRating) + ratingStr = place_page::rating::GetRatingFormatted(productInfo.m_ugcRating); + jni::TScopedLocalRef rating(env, jni::ToJavaString(env, ratingStr)); jni::TScopedLocalRef desc(env, env->NewObject(g_descriptionClass, g_descriptionConstructor, featureId.get(), featureType.get(), address.get(), @@ -389,16 +389,16 @@ jobject ToJavaResult(Result & result, bool isLocalAdsCustomer, float ugcRating, static_cast(result.IsOpenNow()))); jni::TScopedLocalRef name(env, jni::ToJavaString(env, result.GetString())); - jobject ret = env->NewObject(g_resultClass, g_resultConstructor, name.get(), desc.get(), ll.lat, - ll.lon, ranges.get(), result.IsHotel(), isLocalAdsCustomer); + jobject ret = + env->NewObject(g_resultClass, g_resultConstructor, name.get(), desc.get(), ll.lat, ll.lon, + ranges.get(), result.IsHotel(), productInfo.m_isLocalAdsCustomer); ASSERT(ret, ()); return ret; } -void OnResults(Results const & results, vector const & isLocalAdsCustomer, - vector const & ugcRatings, long long timestamp, bool isMapAndTable, - bool hasPosition, double lat, double lon) +void OnResults(Results const & results, vector const & productInfo, + long long timestamp, bool isMapAndTable, bool hasPosition, double lat, double lon) { // Ignore results from obsolete searches. if (g_queryTimestamp > timestamp) @@ -409,7 +409,7 @@ void OnResults(Results const & results, vector const & isLocalAdsCustomer, if (!results.IsEndMarker() || results.IsEndedNormal()) { jni::TScopedLocalObjectArrayRef jResults( - env, BuildSearchResults(results, isLocalAdsCustomer, ugcRatings, hasPosition, lat, lon)); + env, BuildSearchResults(results, productInfo, hasPosition, lat, lon)); env->CallVoidMethod(g_javaListener, g_updateResultsId, jResults.get(), static_cast(timestamp), search::HotelsClassifier::IsHotelResults(results)); @@ -453,7 +453,7 @@ void OnMapSearchResults(storage::DownloaderSearchResults const & results, long l } void OnBookingFilterResults(booking::AvailabilityParams const & params, - std::vector const & featuresSorted) + vector const & featuresSorted) { // Ignore obsolete booking filter results. if (params != g_lastBookingFilterParams) @@ -466,9 +466,9 @@ void OnBookingFilterResults(booking::AvailabilityParams const & params, } } // namespace -jobjectArray BuildSearchResults(Results const & results, vector const & isLocalAdsCustomer, - vector const & ugcRatings, bool hasPosition, double lat, - double lon) +jobjectArray BuildSearchResults(Results const & results, + vector const & productInfo, bool hasPosition, + double lat, double lon) { JNIEnv * env = jni::GetEnv(); @@ -477,13 +477,10 @@ jobjectArray BuildSearchResults(Results const & results, vector const & is int const count = g_results.GetCount(); jobjectArray const jResults = env->NewObjectArray(count, g_resultClass, nullptr); - ASSERT_EQUAL(results.GetCount(), isLocalAdsCustomer.size(), ()); - ASSERT_EQUAL(results.GetCount(), ugcRatings.size(), ()); - for (int i = 0; i < count; i++) { - jni::TScopedLocalRef jRes(env, ToJavaResult(g_results[i], isLocalAdsCustomer[i], ugcRatings[i], - hasPosition, lat, lon)); + jni::TScopedLocalRef jRes(env, + ToJavaResult(g_results[i], productInfo[i], hasPosition, lat, lon)); env->SetObjectArrayElement(jResults, i, jRes.get()); } return jResults; @@ -529,12 +526,12 @@ extern "C" search::EverywhereSearchParams params; params.m_query = jni::ToNativeString(env, bytes); params.m_inputLocale = jni::ToNativeString(env, lang); - params.m_onResults = bind(&OnResults, _1, _2, _3, timestamp, false, hasPosition, lat, lon); + params.m_onResults = bind(&OnResults, _1, _2, timestamp, false, hasPosition, lat, lon); params.m_hotelsFilter = g_hotelsFilterBuilder.Build(env, hotelsFilter); g_lastBookingFilterParams = g_bookingAvailabilityParamsBuilder.Build(env, bookingFilterParams); params.m_bookingFilterParams.m_params = g_lastBookingFilterParams; - params.m_bookingFilterParams.m_callback = std::bind(&OnBookingFilterResults, _1, _2); + params.m_bookingFilterParams.m_callback = bind(&OnBookingFilterResults, _1, _2); bool const searchStarted = g_framework->NativeFramework()->SearchEverywhere(params); if (searchStarted) @@ -552,7 +549,7 @@ extern "C" vparams.m_hotelsFilter = g_hotelsFilterBuilder.Build(env, hotelsFilter); g_lastBookingFilterParams = g_bookingAvailabilityParamsBuilder.Build(env, bookingFilterParams); vparams.m_bookingFilterParams.m_params = g_lastBookingFilterParams; - vparams.m_bookingFilterParams.m_callback = std::bind(&OnBookingFilterResults, _1, _2); + vparams.m_bookingFilterParams.m_callback = bind(&OnBookingFilterResults, _1, _2); // TODO (@alexzatsepin): set up vparams.m_onCompleted here and use // HotelsClassifier for hotel queries detection. @@ -563,7 +560,7 @@ extern "C" search::EverywhereSearchParams eparams; eparams.m_query = vparams.m_query; eparams.m_inputLocale = vparams.m_inputLocale; - eparams.m_onResults = bind(&OnResults, _1, _2, _3, timestamp, isMapAndTable, + eparams.m_onResults = bind(&OnResults, _1, _2, timestamp, isMapAndTable, false /* hasPosition */, 0.0 /* lat */, 0.0 /* lon */); eparams.m_hotelsFilter = vparams.m_hotelsFilter; if (g_framework->NativeFramework()->SearchEverywhere(eparams)) diff --git a/android/jni/com/mapswithme/maps/SearchEngine.hpp b/android/jni/com/mapswithme/maps/SearchEngine.hpp index 7942b95342..c19a8b8d71 100644 --- a/android/jni/com/mapswithme/maps/SearchEngine.hpp +++ b/android/jni/com/mapswithme/maps/SearchEngine.hpp @@ -2,11 +2,11 @@ #include "com/mapswithme/core/jni_helper.hpp" +#include "search/everywhere_search_callback.hpp" #include "search/result.hpp" #include jobjectArray BuildSearchResults(search::Results const & results, - std::vector const & isLocalAdsCustomer, - std::vector const & ugcRatings, bool hasPosition, double lat, - double lon); + std::vector const & productInfo, + bool hasPosition, double lat, double lon); diff --git a/android/jni/com/mapswithme/maps/discovery/DiscoveryManager.cpp b/android/jni/com/mapswithme/maps/discovery/DiscoveryManager.cpp index 963218e1e3..746f655672 100644 --- a/android/jni/com/mapswithme/maps/discovery/DiscoveryManager.cpp +++ b/android/jni/com/mapswithme/maps/discovery/DiscoveryManager.cpp @@ -68,10 +68,9 @@ struct DiscoveryCallback auto const lat = MercatorBounds::YToLat(viewportCenter.y); auto const lon = MercatorBounds::XToLon(viewportCenter.x); - std::vector customers(results.GetCount(), false); - std::vector ugcRatings(results.GetCount(), -1.f); + std::vector productInfo(results.GetCount()); jni::TScopedLocalObjectArrayRef jResults( - env, BuildSearchResults(results, customers, ugcRatings, true /* hasPosition */, lat, lon)); + env, BuildSearchResults(results, productInfo, true /* hasPosition */, lat, lon)); jobject discoveryManagerInstance = env->GetStaticObjectField(g_discoveryManagerClass, g_discoveryManagerInstanceField); env->CallVoidMethod(discoveryManagerInstance, g_onResultReceivedMethod, diff --git a/iphone/Maps/Core/Search/MWMSearch.h b/iphone/Maps/Core/Search/MWMSearch.h index 36f96d6799..27d670109b 100644 --- a/iphone/Maps/Core/Search/MWMSearch.h +++ b/iphone/Maps/Core/Search/MWMSearch.h @@ -6,6 +6,7 @@ namespace search { class Result; +struct ProductInfo; } // namespace search @interface MWMSearch : NSObject @@ -21,8 +22,7 @@ class Result; + (MWMSearchItemType)resultTypeWithRow:(NSUInteger)row; + (NSUInteger)containerIndexWithRow:(NSUInteger)row; + (search::Result const &)resultWithContainerIndex:(NSUInteger)index; -+ (BOOL)isLocalAdsWithContainerIndex:(NSUInteger)index; -+ (CGFloat)ugcRatingWithContainerIndex:(NSUInteger)index; ++ (search::ProductInfo const &)productInfoWithContainerIndex:(NSUInteger)index; + (id)adWithContainerIndex:(NSUInteger)index; + (BOOL)isBookingAvailableWithContainerIndex:(NSUInteger)index; diff --git a/iphone/Maps/Core/Search/MWMSearch.mm b/iphone/Maps/Core/Search/MWMSearch.mm index 2b57ea788c..2d58a580b8 100644 --- a/iphone/Maps/Core/Search/MWMSearch.mm +++ b/iphone/Maps/Core/Search/MWMSearch.mm @@ -49,9 +49,8 @@ using Observers = NSHashTable; search::ViewportSearchParams m_viewportParams; search::Results m_everywhereResults; search::Results m_viewportResults; - std::vector m_isLocalAdsCustomer; std::vector m_bookingAvailableFeatureIDs; - std::vector m_ugcRatings; + std::vector m_productInfo; } #pragma mark - Instance @@ -81,15 +80,14 @@ using Observers = NSHashTable; { self.lastSearchTimestamp += 1; NSUInteger const timestamp = self.lastSearchTimestamp; - m_everywhereParams.m_onResults = [self, timestamp](search::Results const & results, - vector const & isLocalAdsCustomer, - vector const & ugcRatings) { + m_everywhereParams.m_onResults = [self, timestamp]( + search::Results const & results, + std::vector const & productInfo) { if (timestamp == self.lastSearchTimestamp) { self->m_everywhereResults = results; - self->m_isLocalAdsCustomer = isLocalAdsCustomer; - self->m_ugcRatings = ugcRatings; + self->m_productInfo = productInfo; self.suggestionsCount = results.GetSuggestsCount(); [self onSearchResultsUpdated]; @@ -216,14 +214,9 @@ using Observers = NSHashTable; return [MWMSearch manager]->m_everywhereResults[index]; } -+ (BOOL)isLocalAdsWithContainerIndex:(NSUInteger)index ++ (search::ProductInfo const &)productInfoWithContainerIndex:(NSUInteger)index { - return [MWMSearch manager]->m_isLocalAdsCustomer[index]; -} - -+ (CGFloat)ugcRatingWithContainerIndex:(NSUInteger)index -{ - return [MWMSearch manager]->m_ugcRatings[index]; + return [MWMSearch manager]->m_productInfo[index]; } + (id)adWithContainerIndex:(NSUInteger)index diff --git a/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.h b/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.h index decf8114f9..5117c93ab7 100644 --- a/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.h +++ b/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.h @@ -1,12 +1,12 @@ #import "MWMSearchCell.h" +#include "search/everywhere_search_callback.hpp" #include "search/result.hpp" @interface MWMSearchCommonCell : MWMSearchCell - (void)config:(search::Result const &)result - isLocalAds:(BOOL)isLocalAds - isAvailable:(BOOL)isAvailable - ugcRating:(CGFloat)ugcRating; + isAvailable:(BOOL)isAvailable + productInfo:(search::ProductInfo const &)productInfo; @end diff --git a/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm b/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm index 41a50817d3..f306be4e96 100644 --- a/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm +++ b/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm @@ -2,12 +2,12 @@ #import "CLLocation+Mercator.h" #import "MWMLocationManager.h" +#include "map/place_page_info.hpp" + #include "geometry/mercator.hpp" #include "platform/measurement_utils.hpp" -#include "map/place_page_info.hpp" - @interface MWMSearchCommonCell () @property(nonatomic) IBOutletCollection(UIImageView) NSArray * infoRatingStars; @@ -29,15 +29,14 @@ @implementation MWMSearchCommonCell - (void)config:(search::Result const &)result - isLocalAds:(BOOL)isLocalAds - isAvailable:(BOOL)isAvailable - ugcRating:(CGFloat)ugcRating + isAvailable:(BOOL)isAvailable + productInfo:(search::ProductInfo const &)productInfo { [super config:result]; self.typeLabel.text = @(result.GetFeatureTypeName().c_str()).capitalizedString; auto ratingStr = result.GetHotelRating(); - if (ratingStr.empty() && ugcRating > 0.f) - ratingStr = place_page::rating::GetRatingFormatted(ugcRating); + if (ratingStr.empty() && productInfo.m_ugcRating != search::ProductInfo::kInvalidRating) + ratingStr = place_page::rating::GetRatingFormatted(productInfo.m_ugcRating); self.ratingLabel.text = ratingStr.empty() ? @"" : [NSString stringWithFormat:L(@"place_page_booking_rating"), ratingStr.c_str()]; @@ -72,7 +71,7 @@ self.distanceLabel.text = @(distanceStr.c_str()); } - if (isLocalAds) + if (productInfo.m_isLocalAdsCustomer) self.backgroundColor = [UIColor bannerBackground]; else if (isAvailable) self.backgroundColor = [UIColor transparentGreen]; diff --git a/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm b/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm index dd80ad164b..02279b75a0 100644 --- a/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm +++ b/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm @@ -87,10 +87,9 @@ dequeueReusableCellWithCellClass:[MWMSearchCommonCell class] indexPath:indexPath]); auto const & result = [MWMSearch resultWithContainerIndex:containerIndex]; - auto const isLocalAds = [MWMSearch isLocalAdsWithContainerIndex:containerIndex]; auto const isBookingAvailable = [MWMSearch isBookingAvailableWithContainerIndex:containerIndex]; - auto const ugcRating = [MWMSearch ugcRatingWithContainerIndex:containerIndex]; - [cell config:result isLocalAds:isLocalAds isAvailable:isBookingAvailable ugcRating:ugcRating]; + auto const & productInfo = [MWMSearch productInfoWithContainerIndex:containerIndex]; + [cell config:result isAvailable:isBookingAvailable productInfo:productInfo]; return cell; } case MWMSearchItemTypeMopub: diff --git a/map/everywhere_search_params.hpp b/map/everywhere_search_params.hpp index ec1226e4ee..b0ddf018ae 100644 --- a/map/everywhere_search_params.hpp +++ b/map/everywhere_search_params.hpp @@ -2,6 +2,7 @@ #include "map/booking_filter_availability_params.hpp" +#include "search/everywhere_search_callback.hpp" #include "search/hotels_filter.hpp" #include "search/result.hpp" @@ -14,15 +15,11 @@ namespace search { struct EverywhereSearchParams { - using OnResults = - std::function const & isLocalAdsCustomer, - std::vector const & ugcRatings)>; - std::string m_query; std::string m_inputLocale; std::shared_ptr m_hotelsFilter; booking::filter::availability::Params m_bookingFilterParams; - OnResults m_onResults; + EverywhereSearchCallback::OnResults m_onResults; }; } // namespace search diff --git a/map/framework.cpp b/map/framework.cpp index 607471b84c..b9f2d74888 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -3249,23 +3249,20 @@ bool Framework::ParseSearchQueryCommand(search::SearchParams const & params) return false; } -bool Framework::IsLocalAdsCustomer(search::Result const & result) const -{ - if (result.GetResultType() != search::Result::Type::Feature) - return false; - return m_localAdsManager.Contains(result.GetFeatureID()); -} - -float Framework::GetUgcRating(search::Result const & result) const +search::ProductInfo Framework::GetProductInfo(search::Result const & result) const { ASSERT(m_ugcApi, ()); - if (result.GetResultType() != search::Result::Type::Feature) - return -1.f; + return {}; + + search::ProductInfo productInfo; + + productInfo.m_isLocalAdsCustomer = m_localAdsManager.Contains(result.GetFeatureID()); auto const ugc = m_ugcApi->GetLoader().GetUGC(result.GetFeatureID()); + productInfo.m_ugcRating = ugc.m_totalRating; - return ugc.m_totalRating; + return productInfo; } double Framework::GetMinDistanceBetweenResults() const diff --git a/map/framework.hpp b/map/framework.hpp index 13c7f84d63..075b1cbb3f 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -358,8 +358,7 @@ public: void ClearViewportSearchResults() override; boost::optional GetCurrentPosition() const override; bool ParseSearchQueryCommand(search::SearchParams const & params) override; - bool IsLocalAdsCustomer(search::Result const & result) const override; - float GetUgcRating(search::Result const & result) const override; + search::ProductInfo GetProductInfo(search::Result const & result) const override; double GetMinDistanceBetweenResults() const override; private: diff --git a/map/search_api.cpp b/map/search_api.cpp index 7136831a64..85aea8721b 100644 --- a/map/search_api.cpp +++ b/map/search_api.cpp @@ -176,11 +176,10 @@ bool SearchAPI::SearchEverywhere(EverywhereSearchParams const & params) p.m_onResults = EverywhereSearchCallback( static_cast(*this), - [this, params](Results const & results, vector const & isLocalAdsCustomer, - vector const & ugcRatings) { + [this, params](Results const & results, std::vector const & productInfo) { if (params.m_onResults) - RunUITask([params, results, isLocalAdsCustomer, ugcRatings] { - params.m_onResults(results, isLocalAdsCustomer, ugcRatings); + RunUITask([params, results, productInfo] { + params.m_onResults(results, productInfo); }); if (results.IsEndedNormal() && !params.m_bookingFilterParams.IsEmpty()) { @@ -329,20 +328,15 @@ bool SearchAPI::IsViewportSearchActive() const return !m_searchIntents[static_cast(Mode::Viewport)].m_params.m_query.empty(); } -void SearchAPI::ShowViewportSearchResults(bool clear, search::Results::ConstIter begin, - search::Results::ConstIter end) +void SearchAPI::ShowViewportSearchResults(bool clear, Results::ConstIter begin, + Results::ConstIter end) { return m_delegate.ShowViewportSearchResults(clear, begin, end); } -bool SearchAPI::IsLocalAdsCustomer(Result const & result) const +ProductInfo SearchAPI::GetProductInfo(Result const & result) const { - return m_delegate.IsLocalAdsCustomer(result); -} - -float SearchAPI::GetUgcRating(search::Result const & result) const -{ - return m_delegate.GetUgcRating(result); + return m_delegate.GetProductInfo(result); } void SearchAPI::OnBookmarksCreated(vector> const & marks) diff --git a/map/search_api.hpp b/map/search_api.hpp index e81783e8b9..4936d2a44a 100644 --- a/map/search_api.hpp +++ b/map/search_api.hpp @@ -87,8 +87,6 @@ public: virtual double GetMinDistanceBetweenResults() const { return 0.0; }; - virtual bool IsLocalAdsCustomer(search::Result const & /* result */) const { return false; } - virtual void FilterSearchResultsOnBooking(booking::filter::availability::Params const & params, search::Results const & results, bool inViewport) { @@ -96,7 +94,7 @@ public: virtual void OnBookingFilterParamsUpdate(booking::AvailabilityParams const & params) {} - virtual float GetUgcRating(search::Result const & /* result */) const { return -1.f; } + virtual search::ProductInfo GetProductInfo(search::Result const & result) const { return {}; }; }; SearchAPI(Index & index, storage::Storage const & storage, @@ -140,8 +138,7 @@ public: bool IsViewportSearchActive() const override; void ShowViewportSearchResults(bool clear, search::Results::ConstIter begin, search::Results::ConstIter end) override; - bool IsLocalAdsCustomer(search::Result const & result) const override; - float GetUgcRating(search::Result const & result) const override; + search::ProductInfo GetProductInfo(search::Result const & result) const override; void OnBookmarksCreated(std::vector> const & marks); void OnBookmarksUpdated(std::vector> const & marks); diff --git a/qt/search_panel.cpp b/qt/search_panel.cpp index c39e619205..3ca260f594 100644 --- a/qt/search_panel.cpp +++ b/qt/search_panel.cpp @@ -261,8 +261,7 @@ void SearchPanel::OnSearchTextChanged(QString const & str) m_params.m_query = normalized.toUtf8().constData(); auto const timestamp = ++m_timestamp; m_params.m_onResults = [this, timestamp](search::Results const & results, - vector const & /* isLocalAdsCustomer */, - vector const & /* ugcRatings */) { + std::vector const & productInfo) { GetPlatform().RunTask(Platform::Thread::Gui, bind(&SearchPanel::OnSearchResults, this, timestamp, results)); }; diff --git a/search/everywhere_search_callback.cpp b/search/everywhere_search_callback.cpp index 52b9db7d9b..0a157a6dae 100644 --- a/search/everywhere_search_callback.cpp +++ b/search/everywhere_search_callback.cpp @@ -12,18 +12,15 @@ EverywhereSearchCallback::EverywhereSearchCallback(Delegate & delegate, OnResult void EverywhereSearchCallback::operator()(Results const & results) { - ASSERT_EQUAL(m_isLocalAdsCustomer.size(), m_ugcRatings.size(), ()); - - auto const prevSize = m_isLocalAdsCustomer.size(); + auto const prevSize = m_productInfo.size(); ASSERT_LESS_OR_EQUAL(prevSize, results.GetCount(), ()); for (size_t i = prevSize; i < results.GetCount(); ++i) { - m_isLocalAdsCustomer.push_back(m_delegate.IsLocalAdsCustomer(results[i])); - m_ugcRatings.push_back(m_delegate.GetUgcRating(results[i])); + m_productInfo.push_back(m_delegate.GetProductInfo(results[i])); } - ASSERT_EQUAL(m_isLocalAdsCustomer.size(), results.GetCount(), ()); - m_onResults(results, m_isLocalAdsCustomer, m_ugcRatings); + ASSERT_EQUAL(m_productInfo.size(), results.GetCount(), ()); + m_onResults(results, m_productInfo); } } // namespace search diff --git a/search/everywhere_search_callback.hpp b/search/everywhere_search_callback.hpp index 3d9e39b31b..73b617351e 100644 --- a/search/everywhere_search_callback.hpp +++ b/search/everywhere_search_callback.hpp @@ -7,6 +7,13 @@ namespace search { +struct ProductInfo +{ + static float constexpr kInvalidRating = -1; + + bool m_isLocalAdsCustomer = false; + float m_ugcRating = kInvalidRating; +}; // An on-results-callback that should be used for search over all // maps. // @@ -19,15 +26,13 @@ public: public: virtual ~Delegate() = default; - virtual bool IsLocalAdsCustomer(Result const & result) const = 0; - virtual float GetUgcRating(Result const & result) const = 0; + virtual ProductInfo GetProductInfo(Result const & result) const = 0; }; // The signature of the callback should be the same as EverywhereSaerchParams::OnResults, but // EverywhereSaerchParams is located in map project and we do not need dependency. using OnResults = - std::function const & isLocalAdsCustomer, - std::vector const & ugcRatings)>; + std::function const & productInfo)>; EverywhereSearchCallback(Delegate & delegate, OnResults onResults); @@ -36,7 +41,6 @@ public: private: Delegate & m_delegate; OnResults m_onResults; - std::vector m_isLocalAdsCustomer; - std::vector m_ugcRatings; + std::vector m_productInfo; }; } // namespace search diff --git a/ugc/api.cpp b/ugc/api.cpp index f9b45acde3..7fb2a40954 100644 --- a/ugc/api.cpp +++ b/ugc/api.cpp @@ -46,7 +46,7 @@ void Api::SaveUGCOnDisk() Loader & Api::GetLoader() { - return m_loader; + return m_loader; } void Api::GetUGCImpl(FeatureID const & id, UGCCallbackUnsafe const & callback) diff --git a/ugc/loader.cpp b/ugc/loader.cpp index ce57c4c5bc..0326dc06c4 100644 --- a/ugc/loader.cpp +++ b/ugc/loader.cpp @@ -22,13 +22,25 @@ UGC Loader::GetUGC(FeatureID const & featureId) return {}; UGC ugc; + EntryPtr entry; { std::lock_guard lock(m_mutex); + auto it = m_deserializers.find(featureId.m_mwmId); - auto deserializer = m_deserializers[featureId.m_mwmId]; + if (it == m_deserializers.end()) + { + auto const result = m_deserializers.emplace(featureId.m_mwmId, make_shared()); + it = result.first; + } + entry = it->second; + } + + ASSERT(entry, ()); + + { + std::lock_guard lock(entry->m_mutex); auto readerPtr = value.m_cont.GetReader(UGC_FILE_TAG); - - deserializer.Deserialize(*readerPtr.GetPtr(), featureId.m_index, ugc); + entry->m_deserializer.Deserialize(*readerPtr.GetPtr(), featureId.m_index, ugc); } return ugc; diff --git a/ugc/loader.hpp b/ugc/loader.hpp index f141e841c7..ffddf8781b 100644 --- a/ugc/loader.hpp +++ b/ugc/loader.hpp @@ -6,6 +6,7 @@ #include "indexer/mwm_set.hpp" #include +#include #include class Index; @@ -21,8 +22,16 @@ public: UGC GetUGC(FeatureID const & featureId); private: + struct Entry + { + std::mutex m_mutex; + binary::UGCDeserializer m_deserializer; + }; + + using EntryPtr = std::shared_ptr; + Index const & m_index; - std::map m_deserializers; + std::map m_deserializers; std::mutex m_mutex; }; } // namespace ugc