/// <summary> /// Perform a bulk update of a collection of <see cref="Completion"/> instances to match the values /// contained in a pair of source collections. /// </summary> /// <remarks>The <see cref="Completion"/> instances in <paramref name="sourceCompletions"/> and /// <paramref name="secondSourceCompletions"/> are merged and sorted using /// <see cref="CompletionDisplayTextComparer.Default"/>. /// /// <list type="bullet"> /// <item>Any items present in <paramref name="result"/> but not present in the merged collection are /// removed from <paramref name="result"/>.</item> /// <item>Any items not already present in <paramref name="result"/> are inserted at the correct /// location.</item> /// </list> /// /// <note type="caller">The <paramref name="result"/> collection is assumed to already be sorted /// according to <see cref="CompletionDisplayTextComparer.Default"/> before this method is called.</note> /// </remarks> /// <param name="result">The collection holding the merged result.</param> /// <param name="sourceCompletions">The collection of <see cref="Completion"/> instances from the first /// source.</param> /// <param name="secondSourceCompletions">The collection of <see cref="Completion"/> instances from the /// second source.</param> private static void UpdateCompletionList(BulkObservableCollection <Completion> result, IEnumerable <Completion> sourceCompletions, IEnumerable <Completion> secondSourceCompletions) { try { result.BeginBulkOperation(); // SortedSet<Completion> provides for immediate sorting, and also allows Contains() to be used // below instead of a manual call to CompletionDisplayTextComparer.Compare(). SortedSet <Completion> filteredCompletions = new SortedSet <Completion>(CompletionDisplayTextComparer.Default); filteredCompletions.UnionWith(sourceCompletions); filteredCompletions.UnionWith(secondSourceCompletions); int j = 0; foreach (Completion completion in filteredCompletions) { while (j < result.Count && !filteredCompletions.Contains(result[j])) { result.RemoveAt(j); } if (j == result.Count || completion != result[j]) { result.Insert(j, completion); j++; } } } finally { result.EndBulkOperation(); } }
private void Update() { if (debuggerService.State != DebuggerState.Running) { var frames = debuggerService.Machine.GetStackFrames(); stackFrames.BeginBulkOperation(); try { stackFrames.Clear(); for (int i = 0; i < frames.Length; i++) { var frame = frames[i]; uint jumpToAddress = 0; if (i == 0) { jumpToAddress = (uint)debuggerService.Machine.PC; } else { jumpToAddress = frames[i - 1].ReturnAddress; } stackFrames.Add(new StackFrameViewModel(frame, routineService.RoutineTable, jumpToAddress)); } } finally { stackFrames.EndBulkOperation(); } } }
private void UpdateAnalyzers() { if (_analyzerItems == null) { // The set of AnalyzerItems hasn't been realized yet. Just signal that HasItems // may have changed. NotifyPropertyChanged(nameof(HasItems)); return; } var project = _analyzersFolder.Workspace.CurrentSolution.GetProject( _analyzersFolder.ProjectId ); if (project != null && project.AnalyzerReferences != _analyzerReferences) { _analyzerReferences = project.AnalyzerReferences; _analyzerItems.BeginBulkOperation(); var itemsToRemove = _analyzerItems .Where(item => !_analyzerReferences.Contains(item.AnalyzerReference)) .ToArray(); var referencesToAdd = GetFilteredAnalyzers(_analyzerReferences, project) .Where(r => !_analyzerItems.Any(item => item.AnalyzerReference == r)) .ToArray(); foreach (var item in itemsToRemove) { _analyzerItems.Remove(item); } foreach (var reference in referencesToAdd) { _analyzerItems.Add( new AnalyzerItem( _analyzersFolder, reference, _commandHandler.AnalyzerContextMenuController ) ); } var sorted = _analyzerItems .OrderBy(item => item.AnalyzerReference.Display) .ToArray(); for (var i = 0; i < sorted.Length; i++) { _analyzerItems.Move(_analyzerItems.IndexOf(sorted[i]), i); } _analyzerItems.EndBulkOperation(); NotifyPropertyChanged(nameof(HasItems)); } }
//private void MemoryChanged(object sender, MemoryEventArgs e) //{ // // Replace affected lines // int firstLineIndex = e.Address / 16; // int lastLineIndex = (e.Address + e.Length) / 16; // var reader = e.Memory.CreateReader(firstLineIndex * 16); // for (int i = firstLineIndex; i <= lastLineIndex; i++) // { // var address = reader.Address; // var count = Math.Min(8, reader.RemainingBytes); // var values = reader.NextWords(count); // lines[i] = new MemoryLineViewModel(address, values); // } // // TODO: Highlight modified memory //} private void StoryService_StoryOpened(object sender, StoryOpenedEventArgs e) { var reader = new MemoryReader(e.Story.Memory, 0); lines.BeginBulkOperation(); try { while (reader.RemainingBytes > 0) { var address = reader.Address; ushort[] values; if (reader.RemainingBytes >= 16 || reader.RemainingBytes % 2 == 0) { var count = Math.Min(8, reader.RemainingBytes / 2); values = reader.NextWords(count); } else { // if the last line is an odd number of bytes... // TODO: memory view always shows even number of bytes // (padding with zeroes if necessry). Need to fix it to show odd // number of bytes if that's the case. var valueList = new List <ushort>(); while (reader.RemainingBytes > 0) { if (reader.RemainingBytes > 2) { valueList.Add(reader.NextWord()); } else { valueList.Add((ushort)(reader.NextByte() << 8)); } } values = valueList.ToArray(); } lines.Add(new MemoryLineViewModel(address, values)); } } finally { lines.EndBulkOperation(); } PropertyChanged("HasStory"); }
private void StoryService_StoryOpened(object sender, StoryOpenedEventArgs e) { objects.BeginBulkOperation(); try { foreach (var obj in e.Story.ObjectTable) { objects.Add(new ObjectViewModel(obj)); } } finally { objects.EndBulkOperation(); } PropertyChanged("HasStory"); }
private void Update() { if (debuggerService.State != DebuggerState.Running) { var frames = debuggerService.Machine.GetStackFrames(); stackFrames.BeginBulkOperation(); try { stackFrames.Clear(); foreach (var frame in frames) { stackFrames.Add(new StackFrameViewModel(frame, routineService.RoutineTable)); } } finally { stackFrames.EndBulkOperation(); } } }
/// <summary> /// Perform a bulk update of a collection of <see cref="Completion"/> instances to match the values /// contained in a pair of source collections. /// </summary> /// <remarks>The <see cref="Completion"/> instances in <paramref name="sourceCompletions"/> and /// <paramref name="secondSourceCompletions"/> are merged and sorted using /// <see cref="CompletionDisplayTextComparer.Default"/>. /// /// <list type="bullet"> /// <item>Any items present in <paramref name="result"/> but not present in the merged collection are /// removed from <paramref name="result"/>.</item> /// <item>Any items not already present in <paramref name="result"/> are inserted at the correct /// location.</item> /// </list> /// /// <note type="caller">The <paramref name="result"/> collection is assumed to already be sorted /// according to <see cref="CompletionDisplayTextComparer.Default"/> before this method is called.</note> /// </remarks> /// <param name="result">The collection holding the merged result.</param> /// <param name="sourceCompletions">The collection of <see cref="Completion"/> instances from the first /// source.</param> /// <param name="secondSourceCompletions">The collection of <see cref="Completion"/> instances from the /// second source.</param> private static void UpdateCompletionList(BulkObservableCollection<Completion> result, IEnumerable<Completion> sourceCompletions, IEnumerable<Completion> secondSourceCompletions) { try { result.BeginBulkOperation(); // SortedSet<Completion> provides for immediate sorting, and also allows Contains() to be used // below instead of a manual call to CompletionDisplayTextComparer.Compare(). SortedSet<Completion> filteredCompletions = new SortedSet<Completion>(CompletionDisplayTextComparer.Default); filteredCompletions.UnionWith(sourceCompletions); filteredCompletions.UnionWith(secondSourceCompletions); int j = 0; foreach(Completion completion in filteredCompletions) { while(j < result.Count && !filteredCompletions.Contains(result[j])) result.RemoveAt(j); if(j == result.Count || completion != result[j]) { result.Insert(j, completion); j++; } } } finally { result.EndBulkOperation(); } }
private void DebuggerService_MachineCreated(object sender, MachineCreatedEventArgs e) { var reader = new MemoryReader(storyService.Story.Memory, 0); DisassemblyLineViewModel ipLine; lines.BeginBulkOperation(); try { var routineTable = routineService.RoutineTable; for (int rIndex = 0; rIndex < routineTable.Count; rIndex++) { var routine = routineTable[rIndex]; if (rIndex > 0) { var lastRoutine = routineTable[rIndex - 1]; if (lastRoutine.Address + lastRoutine.Length < routine.Address) { var addressGapLine = new DisassemblyAddressGapLineViewModel(lastRoutine, routine) { ShowBlankBefore = true }; lines.Add(addressGapLine); } } var routineHeaderLine = new DisassemblyRoutineHeaderLineViewModel(routine) { ShowBlankBefore = rIndex > 0, ShowBlankAfter = true }; routineAddressAndIndexList.Add(new AddressAndIndex(routineHeaderLine.Address, lines.Count)); lines.Add(routineHeaderLine); addressToLineMap.Add(routine.Address, routineHeaderLine); var instructions = routine.Instructions; var lastIndex = instructions.Length - 1; for (int i = 0; i <= lastIndex; i++) { var instruction = instructions[i]; var instructionLine = new DisassemblyInstructionLineViewModel(instruction, i == lastIndex); if (breakpointService.Exists(instruction.Address)) { instructionLine.HasBreakpoint = true; } lines.Add(instructionLine); addressToLineMap.Add(instruction.Address, instructionLine); } } ipLine = GetLineByAddress(debuggerService.Machine.PC); ipLine.HasIP = true; } finally { lines.EndBulkOperation(); } BringLineIntoView(ipLine); routineService.RoutineTable.RoutineAdded += RoutineTable_RoutineAdded; }