cancel previous searches
This commit is contained in:
@@ -7,7 +7,7 @@ namespace SharpIDE.Application.Features.Search;
|
|||||||
|
|
||||||
public static class SearchService
|
public static class SearchService
|
||||||
{
|
{
|
||||||
public static async Task<List<SearchResult>> FindInFiles(SharpIdeSolutionModel solutionModel, string searchTerm)
|
public static async Task<List<SearchResult>> FindInFiles(SharpIdeSolutionModel solutionModel, string searchTerm, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (searchTerm.Length < 4)
|
if (searchTerm.Length < 4)
|
||||||
{
|
{
|
||||||
@@ -17,10 +17,12 @@ public static class SearchService
|
|||||||
var timer = Stopwatch.StartNew();
|
var timer = Stopwatch.StartNew();
|
||||||
var files = solutionModel.AllFiles;
|
var files = solutionModel.AllFiles;
|
||||||
ConcurrentBag<SearchResult> results = [];
|
ConcurrentBag<SearchResult> results = [];
|
||||||
await Parallel.ForEachAsync(files, async (file, ct) =>
|
await Parallel.ForEachAsync(files, cancellationToken, async (file, ct) =>
|
||||||
{
|
{
|
||||||
|
if (cancellationToken.IsCancellationRequested) return;
|
||||||
await foreach (var (index, line) in File.ReadLinesAsync(file.Path, ct).Index().WithCancellation(ct))
|
await foreach (var (index, line) in File.ReadLinesAsync(file.Path, ct).Index().WithCancellation(ct))
|
||||||
{
|
{
|
||||||
|
if (cancellationToken.IsCancellationRequested) return;
|
||||||
if (line.Contains(searchTerm, StringComparison.OrdinalIgnoreCase))
|
if (line.Contains(searchTerm, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
results.Add(new SearchResult
|
results.Add(new SearchResult
|
||||||
@@ -32,9 +34,9 @@ public static class SearchService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
|
||||||
timer.Stop();
|
timer.Stop();
|
||||||
Console.WriteLine($"Search completed in {timer.ElapsedMilliseconds} ms. Found {results.Count} results.");
|
Console.WriteLine($"Search completed in {timer.ElapsedMilliseconds} ms. Found {results.Count} results. {(cancellationToken.IsCancellationRequested ? "(Cancelled)" : "")}");
|
||||||
return results.ToList();
|
return results.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ public partial class SearchWindow : PopupPanel
|
|||||||
private VBoxContainer _searchResultsContainer = null!;
|
private VBoxContainer _searchResultsContainer = null!;
|
||||||
public SharpIdeSolutionModel Solution { get; set; } = null!;
|
public SharpIdeSolutionModel Solution { get; set; } = null!;
|
||||||
private readonly PackedScene _searchResultEntryScene = ResourceLoader.Load<PackedScene>("res://Features/Search/SearchResultComponent.tscn");
|
private readonly PackedScene _searchResultEntryScene = ResourceLoader.Load<PackedScene>("res://Features/Search/SearchResultComponent.tscn");
|
||||||
|
|
||||||
|
private CancellationTokenSource _cancellationTokenSource = new();
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
@@ -20,22 +22,25 @@ public partial class SearchWindow : PopupPanel
|
|||||||
|
|
||||||
private async void OnTextChanged(string newText)
|
private async void OnTextChanged(string newText)
|
||||||
{
|
{
|
||||||
GD.Print("Search text changed");
|
await _cancellationTokenSource.CancelAsync();
|
||||||
await Task.GodotRun(() => Search(newText));
|
// TODO: Investigate allocations
|
||||||
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
var token = _cancellationTokenSource.Token;
|
||||||
|
await Task.GodotRun(() => Search(newText, token));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Search(string text)
|
private async Task Search(string text, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await SearchService.FindInFiles(Solution, text);
|
var result = await SearchService.FindInFiles(Solution, text, cancellationToken);
|
||||||
await this.InvokeAsync(() =>
|
await this.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
_searchResultsContainer.GetChildren().ToList().ForEach(s => s.QueueFree());
|
_searchResultsContainer.GetChildren().ToList().ForEach(s => s.QueueFree());
|
||||||
foreach (var searchResult in result)
|
foreach (var searchResult in result)
|
||||||
{
|
{
|
||||||
var result = _searchResultEntryScene.Instantiate<SearchResultComponent>();
|
var resultNode = _searchResultEntryScene.Instantiate<SearchResultComponent>();
|
||||||
result.Result = searchResult;
|
resultNode.Result = searchResult;
|
||||||
_searchResultsContainer.AddChild(result);
|
_searchResultsContainer.AddChild(resultNode);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user