Task IScreenBuffer.SetDisplayTextGetter(MessageTextGetter displayTextGetter, CancellationToken cancellation) { if (this.displayTextGetter == displayTextGetter) { return(Task.FromResult(0)); } this.displayTextGetter = displayTextGetter; changeNotification.Post(); var currentTop = EnumScreenBufferLines().FirstOrDefault(); return(PerformBuffersTransaction( string.Format("SetDisplayTextGetter({0})", displayTextGetter), cancellation, modifyBuffers: tmp => Task.WhenAll(tmp.Select(b => b.LoadAround(GetMaxBufferSize(viewSize), cancellation))), getPivotLine: (lines, bufs) => { var candidate = new DisplayLine(); if (!currentTop.IsEmpty) { candidate = lines.FirstOrDefault(l => MessagesComparer.Compare(l.Message, currentTop.Message) == 0 && l.LineIndex == currentTop.LineIndex); if (candidate.IsEmpty) { candidate = lines.FirstOrDefault(l => MessagesComparer.Compare(l.Message, currentTop.Message) == 0); } } if (candidate.IsEmpty) { candidate = lines.FirstOrDefault(); } if (candidate.IsEmpty) { return null; } return Tuple.Create(candidate, -scrolledLines); } )); }
async Task <double> IScreenBuffer.ShiftBy(double nrOfDisplayLines, CancellationToken cancellation) { var currentTop = EnumScreenBufferLines().FirstOrDefault(); if (currentTop.IsEmpty) { return(0); } var saveScrolledLines = scrolledLines; var pivotLinePosition = await PerformBuffersTransaction( string.Format("ShiftBy({0})", nrOfDisplayLines), cancellation, modifyBuffers : tmp => Task.WhenAll(tmp.Select(buf => buf.LoadAround(GetMaxBufferSize(viewSize + Math.Abs(nrOfDisplayLines)), cancellation) )), getPivotLine : MakePivotLineGetter(l => { if (MessagesComparer.Compare(l.Message, currentTop.Message) == 0 && l.LineIndex == currentTop.LineIndex) { return(-nrOfDisplayLines - scrolledLines); } return(null); }) ); if (!pivotLinePosition.HasValue) { return(0); } return(-saveScrolledLines - pivotLinePosition.Value); }
public static int Compare(CursorPosition p1, CursorPosition p2) { if (p1 == null && p2 == null) { return(0); } if (p1 == null) { return(-1); } if (p2 == null) { return(1); } int i; i = MessagesComparer.Compare(p1.Message, p2.Message); if (i != 0) { return(i); } i = p1.TextLineIndex - p2.TextLineIndex; if (i != 0) { return(i); } i = p1.LineCharIndex - p2.LineCharIndex; return(i); }
void IPresenter.SetMasterFocusedMessage(IBookmark value) { if (focusedMessage == value) { return; } if (focusedMessage != null && value != null && MessagesComparer.Compare(focusedMessage, value) == 0) { return; } focusedMessage = value; UpdateFocusedMessagePosition(); }
async Task IScreenBuffer.SetSources(IEnumerable <IMessagesSource> sources, CancellationToken cancellation) { string opName = "SetSources"; var currentTop = EnumScreenBufferLines().FirstOrDefault(); var oldBuffers = buffers; buffers = sources.ToDictionary(s => s, s => oldBuffers.ContainsKey(s) ? oldBuffers[s] : new SourceBuffer(s, diagnostics, displayTextGetter)); if (!buffers.Keys.ToHashSet().SetEquals(oldBuffers.Keys)) { buffersVersion++; changeNotification.Post(); } if (!currentTop.IsEmpty) { var currentTopSourcePresent = buffers.ContainsKey(currentTop.Source); await PerformBuffersTransaction( opName, cancellation, modifyBuffers : tmp => Task.WhenAll(tmp.Select(s => oldBuffers.ContainsKey(s.Source) ? s.LoadAround(GetMaxBufferSize(viewSize), cancellation) : s.LoadAt(currentTop.Message.Time.ToLocalDateTime(), GetMaxBufferSize(viewSize), cancellation) )), getPivotLine : currentTopSourcePresent?MakePivotLineGetter(l => { if (MessagesComparer.Compare(l.Message, currentTop.Message) == 0 && l.LineIndex == currentTop.LineIndex) { return(-scrolledLines); } return(null); }) : (lines, bufs) => { var best = lines .Select(l => new { l, diff = (l.Message.Time.ToLocalDateTime() - currentTop.Message.Time.ToLocalDateTime()).Abs() }) .Aggregate(new { l = new DisplayLine(), diff = TimeSpan.MaxValue }, (acc, l) => l.diff < acc.diff ? l : acc); return(!best.l.IsEmpty ? Tuple.Create(best.l, 0d) : null); } ); } else { await PerformBuffersTransaction( opName, cancellation, modifyBuffers : tmp => Task.FromResult(0), getPivotLine : MakePivotLineGetter(l => 0) ); } }
async Task <bool> IScreenBuffer.MoveToBookmark( IBookmark bookmark, BookmarkLookupMode mode, CancellationToken cancellation) { var matchMode = mode & BookmarkLookupMode.MatchModeMask; Func <DisplayLine, int> cmp = (DisplayLine l) => { var ret = MessagesComparer.CompareLogSourceConnectionIds(l.Message.GetConnectionId(), bookmark.LogSourceConnectionId); if (ret == 0) { ret = Math.Sign(l.Message.Position - bookmark.Position); } if (ret == 0) { ret = Math.Sign(l.LineIndex - bookmark.LineIndex); } return(ret); }; return(await PerformBuffersTransaction( string.Format("MoveToBookmark({0})", mode), cancellation, modifyBuffers : tmp => Task.WhenAll(tmp.Select(buf => matchMode == BookmarkLookupMode.ExactMatch && buf.Source.LogSourceHint?.ConnectionId == bookmark.LogSourceConnectionId ? buf.LoadAround(bookmark.Position, GetMaxBufferSize(viewSize) + bookmark.LineIndex, cancellation) : buf.LoadAt(bookmark.Time.ToLocalDateTime(), GetMaxBufferSize(viewSize) + bookmark.LineIndex, cancellation) )), getPivotLine : (lines, bufs) => { DisplayLine ret = new DisplayLine(); if (matchMode == BookmarkLookupMode.ExactMatch) { ret = lines.FirstOrDefault(l => cmp(l) == 0); } else if (matchMode == BookmarkLookupMode.FindNearestMessage) { ret = lines.FirstOrDefault(l => cmp(l) >= 0); if (ret.IsEmpty) { ret = lines.LastOrDefault(l => cmp(l) < 0); } } return ret.Message == null ? null : Tuple.Create(ret, ComputeMatchedLinePosition(mode)); } ) != null); }
public static int Compare(StateInspectorEvent evt1, MessageTimestamp evt2time, ILogSource evt2source, long evt2Position) { int sign = MessageTimestamp.Compare(evt1.Trigger.Timestamp.Adjust(evt1.Output.LogSource.TimeOffsets), evt2time); if (sign != 0) { return(sign); } sign = MessagesComparer.CompareLogSourceConnectionIds( evt1.Output.LogSource.GetSafeConnectionId(), evt2source.GetSafeConnectionId()); if (sign != 0) { return(sign); } sign = Math.Sign(evt1.Trigger.StreamPosition - evt2Position); return(sign); }
Task IScreenBuffer.Refresh(CancellationToken cancellation) { var currentTop = EnumScreenBufferLines().FirstOrDefault(); return(PerformBuffersTransaction( string.Format("Refresh()"), cancellation, modifyBuffers: tmp => Task.WhenAll(tmp.Select(b => b.LoadAround(GetMaxBufferSize(viewSize), cancellation))), getPivotLine: MakePivotLineGetter(l => { if (currentTop.IsEmpty) { return 0; } if (MessagesComparer.Compare(l.Message, currentTop.Message) == 0 && l.LineIndex == currentTop.LineIndex) { return -scrolledLines; } return null; }) )); }
async Task <List <ScreenBufferEntry> > GetSelectedDisplayMessagesEntries() { var viewLines = screenBuffer.Messages; Func <CursorPosition, bool> isGoodDisplayPosition = p => { if (p.Message == null) { return(true); } return(p.DisplayIndex >= 0 && p.DisplayIndex < viewLines.Count); }; var normSelection = selection.Normalize(); if (normSelection.IsEmpty) { return(new List <ScreenBufferEntry>()); } Func <List <ScreenBufferEntry> > defaultGet = () => { int selectedLinesCount = normSelection.Last.DisplayIndex - normSelection.First.DisplayIndex + 1; return(viewLines.Skip(normSelection.First.DisplayIndex).Take(selectedLinesCount).ToList()); }; if (isGoodDisplayPosition(normSelection.First) && isGoodDisplayPosition(normSelection.Last)) { // most common case: both positions are in the screen buffer at the moment return(defaultGet()); } CancellationToken cancellation = CancellationToken.None; IScreenBuffer tmpBuf = screenBufferFactory.CreateScreenBuffer(initialBufferPosition: InitialBufferPosition.Nowhere); await tmpBuf.SetSources(screenBuffer.Sources.Select(s => s.Source), cancellation); if (!await tmpBuf.MoveToBookmark(bookmarksFactory.CreateBookmark(normSelection.First.Message, 0), BookmarkLookupMode.ExactMatch, cancellation)) { // Impossible to load selected message into screen buffer. Rather impossible. return(defaultGet()); } var tasks = screenBuffer.Sources.Select(async sourceBuf => { var sourceMessages = new List <IMessage>(); await sourceBuf.Source.EnumMessages( tmpBuf.Sources.First(sb => sb.Source == sourceBuf.Source).Begin, m => { if (MessagesComparer.Compare(m, normSelection.Last.Message) > 0) { return(false); } sourceMessages.Add(m); return(true); }, EnumMessagesFlag.Forward, LogProviderCommandPriority.AsyncUserAction, cancellation ); return(new { Source = sourceBuf.Source, Messages = sourceMessages }); }).ToList(); await Task.WhenAll(tasks); cancellation.ThrowIfCancellationRequested(); var messagesToSource = tasks.ToDictionary( t => (IMessagesCollection) new MessagesContainers.SimpleCollection(t.Result.Messages), t => t.Result.Source); return (new MessagesContainers.SimpleMergingCollection(messagesToSource.Keys) .Forward(0, int.MaxValue) .SelectMany(m => Enumerable.Range(0, GetTextToDisplay(m.Message.Message).GetLinesCount()).Select( lineIdx => new ScreenBufferEntry() { TextLineIndex = lineIdx, Message = m.Message.Message, Source = messagesToSource[m.SourceCollection], } ) ) .TakeWhile(m => CursorPosition.Compare(CursorPosition.FromViewLine(m.ToViewLine(), 0), normSelection.Last) <= 0) .ToList()); }
public int Compare(IEnumerator <PostprocessedMessage> x, IEnumerator <PostprocessedMessage> y) { return(MessagesComparer.Compare(x.Current.Message, y.Current.Message)); }
async Task <bool> IScreenBuffer.MoveToBookmark( IBookmark bookmark, BookmarkLookupMode mode, CancellationToken cancellation) { using (CreateTrackerForNewOperation(string.Format("MoveToBookmark({0})", mode), cancellation)) { var matchMode = mode & BookmarkLookupMode.MatchModeMask; MessageTimestamp dt = bookmark.Time; long position = bookmark.Position; int lineIndex = bookmark.LineIndex; string logSourceCollectionId = bookmark.LogSourceConnectionId; var tmp = buffers.ToDictionary(s => s.Key, s => new SourceBuffer(s.Value)); var tasks = tmp.Select(s => new { buf = s.Value, task = (buffers.Count == 1 && matchMode == BookmarkLookupMode.ExactMatch) ? GetScreenBufferLines(s.Key, position, bufferSize, EnumMessagesFlag.Forward | EnumMessagesFlag.IsActiveLogPositionHint, isRawLogMode, cancellation) : GetScreenBufferLines(s.Key, dt.ToLocalDateTime(), bufferSize, isRawLogMode, cancellation), }).ToList(); await Task.WhenAll(tasks.Select(i => i.task)); cancellation.ThrowIfCancellationRequested(); foreach (var t in tasks) { t.buf.Set(t.task.Result); } bool messageFound = false; if (matchMode == BookmarkLookupMode.FindNearestTime) { messageFound = true; } else { foreach (var i in GetMessagesInternal(tmp.Values).Forward(0, int.MaxValue)) { var cmp = MessagesComparer.CompareLogSourceConnectionIds(i.Message.Message.GetConnectionId(), logSourceCollectionId); if (cmp == 0) { cmp = Math.Sign(i.Message.Message.Position - position); } if (cmp == 0) { cmp = Math.Sign(((SourceBuffer)i.SourceCollection).Get(i.SourceIndex).LineIndex - lineIndex); } if (matchMode == BookmarkLookupMode.ExactMatch) { messageFound = cmp == 0; } else if (matchMode == BookmarkLookupMode.FindNearestBookmark) { messageFound = cmp > 0; } if (messageFound) { break; } var sb = ((SourceBuffer)i.SourceCollection); sb.UnnededTopMessages++; } } if (!messageFound) { if (matchMode == BookmarkLookupMode.FindNearestBookmark) { await MoveToStreamsEndInternal(cancellation); return(true); } return(false); } buffers = tmp; FinalizeSourceBuffers(); if (AllLogsAreAtEnd()) { await MoveToStreamsEndInternal(cancellation); } else { SetScrolledLines(0); if ((mode & BookmarkLookupMode.MoveBookmarkToMiddleOfScreen) != 0) { var additionalSpace = ((int)Math.Floor(viewSize) - 1) / 2; if (additionalSpace > 0) { await ShiftByInternal(-additionalSpace, cancellation); } } } return(true); } }
public int Compare(QueueEntry x, QueueEntry y) { return(directionSign * MessagesComparer.Compare(x.enumerator.Current.Message, y.enumerator.Current.Message)); }