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 SortComparison { get; set; } readonly List m_Databases; public Searcher(SearcherDatabaseBase database, string title) : this(new List { database }, title, null) { } public Searcher(IEnumerable databases, string title) : this(databases, title, null) { } public Searcher(SearcherDatabaseBase database, ISearcherAdapter adapter = null) : this(new List { database }, adapter) { } public Searcher(IEnumerable databases, ISearcherAdapter adapter = null) : this(databases, string.Empty, adapter) { } Searcher(IEnumerable databases, string title, ISearcherAdapter adapter) { m_Databases = new List(); 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 Search(string query) { query = query.ToLower(); var results = new List(); 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; } } } }