109 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Linq;
 | |
| using JetBrains.Annotations;
 | |
| 
 | |
| namespace UnityEditor.Searcher
 | |
| {
 | |
|     [PublicAPI]
 | |
|     public class Searcher
 | |
|     {
 | |
|         public ISearcherAdapter Adapter { get; }
 | |
|         public Comparison<SearcherItem> SortComparison { get; set; }
 | |
| 
 | |
|         readonly List<SearcherDatabaseBase> m_Databases;
 | |
| 
 | |
|         public Searcher(SearcherDatabaseBase database, string title)
 | |
|             : this(new List<SearcherDatabaseBase> { database }, title, null)
 | |
|         { }
 | |
| 
 | |
|         public Searcher(IEnumerable<SearcherDatabaseBase> databases, string title)
 | |
|             : this(databases, title, null)
 | |
|         { }
 | |
| 
 | |
|         public Searcher(SearcherDatabaseBase database, ISearcherAdapter adapter = null)
 | |
|             : this(new List<SearcherDatabaseBase> { database }, adapter)
 | |
|         { }
 | |
| 
 | |
|         public Searcher(IEnumerable<SearcherDatabaseBase> databases, ISearcherAdapter adapter = null)
 | |
|             : this(databases, string.Empty, adapter)
 | |
|         { }
 | |
| 
 | |
|         Searcher(IEnumerable<SearcherDatabaseBase> databases, string title, ISearcherAdapter adapter)
 | |
|         {
 | |
|             m_Databases = new List<SearcherDatabaseBase>();
 | |
|             var databaseId = 0;
 | |
|             foreach (var database in databases)
 | |
|             {
 | |
|                 // This is needed for sorting items between databases.
 | |
|                 database.OverwriteId(databaseId);
 | |
|                 databaseId++;
 | |
| 
 | |
|                 m_Databases.Add(database);
 | |
|             }
 | |
| 
 | |
|             Adapter = adapter ?? new SearcherAdapter(title);
 | |
|         }
 | |
| 
 | |
|         public void BuildIndices()
 | |
|         {
 | |
|             foreach (var database in m_Databases)
 | |
|             {
 | |
|                 database.BuildIndex();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public IEnumerable<SearcherItem> Search(string query)
 | |
|         {
 | |
|             query = query.ToLower();
 | |
| 
 | |
|             var results = new List<SearcherItem>();
 | |
|             float maxScore = 0;
 | |
|             foreach (var database in m_Databases)
 | |
|             {
 | |
|                 var localResults = database.Search(query, out var localMaxScore);
 | |
|                 if (localMaxScore > maxScore)
 | |
|                 {
 | |
|                     // skip the highest scored item in the local results and
 | |
|                     // insert it back as the first item. The first item should always be
 | |
|                     // the highest scored item. The order of the other items does not matter
 | |
|                     // because they will be reordered to recreate the tree properly.
 | |
|                     if (results.Count > 0)
 | |
|                     {
 | |
|                         // backup previous best result
 | |
|                         results.Add(results[0]);
 | |
|                         // replace it with the new best result
 | |
|                         results[0] = localResults[0];
 | |
|                         // add remaining results at the end
 | |
|                         results.AddRange(localResults.Skip(1));
 | |
|                     }
 | |
|                     else // best result will be the first item
 | |
|                         results.AddRange(localResults);
 | |
| 
 | |
|                     maxScore = localMaxScore;
 | |
|                 }
 | |
|                 else // no new best result just append everything
 | |
|                 {
 | |
|                     results.AddRange(localResults);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return results;
 | |
|         }
 | |
| 
 | |
|         [PublicAPI]
 | |
|         public class AnalyticsEvent
 | |
|         {
 | |
|             [PublicAPI]
 | |
|             public enum EventType{ Pending, Picked, Cancelled }
 | |
|             public readonly EventType eventType;
 | |
|             public readonly string currentSearchFieldText;
 | |
|             public AnalyticsEvent(EventType eventType, string currentSearchFieldText)
 | |
|             {
 | |
|                 this.eventType = eventType;
 | |
|                 this.currentSearchFieldText = currentSearchFieldText;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |