static void HandleItemsIteratorSession(object iterator, List <SearchItem> allItems, string id, SearchContext context, SearchFlags options) { if (iterator != null && options.HasAny(SearchFlags.Synchronous)) { using (var stackedEnumerator = new SearchEnumerator <SearchItem>(iterator)) { while (stackedEnumerator.MoveNext()) { if (stackedEnumerator.Current != null) { allItems.Add(stackedEnumerator.Current); } } } } else { var session = context.sessions.GetProviderSession(context, id); session.Reset(context, iterator, k_MaxFetchTimeMs); session.Start(); var sessionEnded = !session.FetchSome(allItems, k_MaxFetchTimeMs); if (options.HasAny(SearchFlags.FirstBatchAsync)) { session.SendItems(context.subset != null ? allItems.Intersect(context.subset) : allItems); allItems.Clear(); } if (sessionEnded) { session.Stop(); } } }
/// <summary> /// Initiate a search and return all search items matching the search context. Other items can be found later using the asynchronous searches. /// </summary> /// <param name="context">The current search context</param> /// <param name="options">Options defining how the query will be performed</param> /// <returns>A list of search items matching the search query.</returns> public static List <SearchItem> GetItems(SearchContext context, SearchFlags options = SearchFlags.Default) { // Stop all search sessions every time there is a new search. context.sessions.StopAllAsyncSearchSessions(); context.searchFinishTime = context.searchStartTime = DateTime.Now.Ticks; context.sessionEnded -= OnSearchEnded; context.sessionEnded += OnSearchEnded; if (options.HasAny(SearchFlags.WantsMore)) { context.wantsMore = true; } if (options.HasAny(SearchFlags.Synchronous)) { context.options |= SearchFlags.Synchronous; } int fetchProviderCount = 0; var allItems = new List <SearchItem>(3); foreach (var provider in context.providers) { try { var watch = new System.Diagnostics.Stopwatch(); watch.Start(); fetchProviderCount++; var iterator = provider.fetchItems(context, allItems, provider); if (iterator != null && options.HasAny(SearchFlags.Synchronous)) { using (var stackedEnumerator = new SearchEnumerator <SearchItem>(iterator)) { while (stackedEnumerator.MoveNext()) { if (stackedEnumerator.Current != null) { allItems.Add(stackedEnumerator.Current); } } } } else { var session = context.sessions.GetProviderSession(context, provider.id); session.Reset(context, iterator, k_MaxFetchTimeMs); session.Start(); var sessionEnded = !session.FetchSome(allItems, k_MaxFetchTimeMs); if (options.HasAny(SearchFlags.FirstBatchAsync)) { session.SendItems(context.subset != null ? allItems.Intersect(context.subset) : allItems); allItems.Clear(); } if (sessionEnded) { session.Stop(); } } provider.RecordFetchTime(watch.Elapsed.TotalMilliseconds); } catch (Exception ex) { Debug.LogException(new Exception($"Failed to get fetch {provider.name} provider items.", ex)); } } if (fetchProviderCount == 0) { OnSearchEnded(context); context.sessions.StopAllAsyncSearchSessions(); } if (context.subset != null) { allItems = new List <SearchItem>(allItems.Intersect(context.subset)); } if (!options.HasAny(SearchFlags.Sorted)) { return(allItems); } allItems.Sort(SortItemComparer); return(allItems.GroupBy(i => i.id).Select(i => i.First()).ToList()); }