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();
         }
     }
 }
 public virtual void Reset(object itemEnumerator, long maxFetchTimePerUpdate = k_MaxTimePerUpdate)
 {
     // Remove and add the event handler in case it was already removed.
     Stop();
     this.maxFetchTimePerUpdate = maxFetchTimePerUpdate;
     if (itemEnumerator != null)
     {
         lock (this)
             m_ItemsEnumerator = new SearchEnumerator <T>(itemEnumerator);
         Utils.tick += OnUpdate;
     }
 }
 /// <summary>
 /// Hard reset an async search session.
 /// </summary>
 /// <param name="itemEnumerator">The enumerator that will yield new search results. This object can be an IEnumerator or IEnumerable</param>
 /// <param name="maxFetchTimePerProviderMs">The amount of time allowed to yield new results.</param>
 /// <remarks>Normally async search sessions are re-used per search provider.</remarks>
 public void Reset(SearchContext context, object itemEnumerator, long maxFetchTimePerProviderMs = k_MaxTimePerUpdate)
 {
     // Remove and add the event handler in case it was already removed.
     Stop();
     searchInProgress      = true;
     m_Context             = context;
     maxFetchTimePerUpdate = maxFetchTimePerProviderMs;
     if (itemEnumerator != null)
     {
         lock (this)
             m_ItemsEnumerator = new SearchEnumerator <SearchItem>(itemEnumerator);
         Utils.tick += OnUpdate;
     }
 }
Exemple #4
0
        /// <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());
        }