You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
3.7 KiB
108 lines
3.7 KiB
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; |
|
} |
|
} |
|
} |
|
}
|
|
|