public void Update (SearchPopupSearchPattern pattern) { // in case of 'string:' it's not clear if the user ment 'tag:pattern' or 'pattern:line' therefore guess // 'tag:', if no valid tag is found guess 'pattern:' if (!string.IsNullOrEmpty (pattern.Tag) && string.IsNullOrEmpty (pattern.Pattern) && !categories.Any (c => c.IsValidTag (pattern.Tag))) { pattern = new SearchPopupSearchPattern (null, pattern.Tag, pattern.LineNumber, pattern.Column, pattern.UnparsedPattern); } this.pattern = pattern; if (src != null) src.Cancel (); HideTooltip (); src = new CancellationTokenSource (); isInSearch = true; if (results.Count == 0) { QueueDraw (); } var collectors = new List<SearchResultCollector> (); var token = src.Token; foreach (var _cat in categories) { var cat = _cat; if (!string.IsNullOrEmpty (pattern.Tag) && !cat.IsValidTag (pattern.Tag)) continue; var col = new SearchResultCollector (_cat); collectors.Add (col); col.Task = cat.GetResults (col, pattern, token); } Task.WhenAll (collectors.Select (c => c.Task)).ContinueWith (t => { if (token.IsCancellationRequested) return; var newResults = new List<Tuple<SearchCategory, IReadOnlyList<SearchResult>>> (collectors.Count); foreach (var col in collectors) { if (col.Task.IsCanceled) { continue; } else if (col.Task.IsFaulted) { LoggingService.LogError ($"Error getting search results for {col.Category}", col.Task.Exception); } else { newResults.Add (Tuple.Create (col.Category, col.Results)); } } List<Tuple<SearchCategory, IReadOnlyList<SearchResult>>> failedResults = null; ItemIdentifier topResult = null; for (int i = 0; i < newResults.Count; i++) { var tuple = newResults [i]; try { if (tuple.Item2.Count == 0) continue; if (topResult == null || topResult.DataSource [topResult.Item].Weight < tuple.Item2 [0].Weight) topResult = new ItemIdentifier (tuple.Item1, tuple.Item2, 0); } catch (Exception e) { LoggingService.LogError ("Error while showing result " + i, e); if (failedResults == null) failedResults = new List<Tuple<SearchCategory, IReadOnlyList<SearchResult>>> (); failedResults.Add (newResults [i]); continue; } } if (failedResults != null) failedResults.ForEach (failedResult => newResults.Remove (failedResult)); Application.Invoke (delegate { ShowResults (newResults, topResult); isInSearch = false; AnimatedResize (); }); }, token); }
public void Update (SearchPopupSearchPattern pattern) { // in case of 'string:' it's not clear if the user ment 'tag:pattern' or 'pattern:line' therefore guess // 'tag:', if no valid tag is found guess 'pattern:' if (!string.IsNullOrEmpty (pattern.Tag) && string.IsNullOrEmpty (pattern.Pattern) && !categories.Any (c => c.IsValidTag (pattern.Tag))) { pattern = new SearchPopupSearchPattern (null, pattern.Tag, pattern.LineNumber, pattern.Column, pattern.UnparsedPattern); } this.pattern = pattern; if (src != null) src.Cancel (); HideTooltip (); src = new CancellationTokenSource (); isInSearch = true; if (results.Count == 0) { QueueDraw (); } var collectors = new List<SearchResultCollector> (); var token = src.Token; foreach (var _cat in categories) { var cat = _cat; if (!string.IsNullOrEmpty (pattern.Tag) && !cat.IsValidTag (pattern.Tag)) continue; var col = new SearchResultCollector (_cat); collectors.Add (col); col.Task = cat.GetResults (col, pattern, token); } Task.WhenAll (collectors.Select (c => c.Task)).ContinueWith (t => { Application.Invoke (delegate { if (token.IsCancellationRequested) return; var newResults = new List<Tuple<SearchCategory, IReadOnlyList<SearchResult>>> (collectors.Count); foreach (var col in collectors) { if (col.Task.IsCanceled) { continue; } else if (col.Task.IsFaulted) { LoggingService.LogError ($"Error getting search results for {col.Category}", col.Task.Exception); } else { newResults.Add (Tuple.Create (col.Category, col.Results)); } } ShowResults (newResults); isInSearch = false; AnimatedResize (); }); }, token); }