private void AddSourceBuffer(IProjectionBufferBase projBuffer, ITextBuffer sourceBuffer, FrugalList <ITextBuffer> addedToGraphBuffers) { bool firstEncounter = false; FrugalList <IProjectionBufferBase> importingProjectionBuffers; if (!this.importingProjectionBufferMap.TryGetValue(sourceBuffer, out importingProjectionBuffers)) { // sourceBuffer is new to this buffer graph addedToGraphBuffers.Add(sourceBuffer); firstEncounter = true; importingProjectionBuffers = new FrugalList <IProjectionBufferBase>(); this.importingProjectionBufferMap.Add(sourceBuffer, importingProjectionBuffers); this.eventHooks.Add(new WeakEventHookForBufferGraph(this, sourceBuffer)); } importingProjectionBuffers.Add(projBuffer); if (firstEncounter) { IProjectionBufferBase addedProjBufferBase = sourceBuffer as IProjectionBufferBase; if (addedProjBufferBase != null) { foreach (ITextBuffer furtherSourceBuffer in addedProjBufferBase.SourceBuffers) { AddSourceBuffer(addedProjBufferBase, furtherSourceBuffer, addedToGraphBuffers); } } } }
private void PopulateSourceEdits(ITextBuffer buffer) { IProjectionBufferBase projectionBuffer = buffer as IProjectionBufferBase; if (projectionBuffer != null) { // Add ITextEdit objects to the edit map for all source buffers of the current projection buffer that // are themselves projection buffers. This is so that such buffers are not considered independent buffers // if it happens that the master edit does not touch them directly (even though not touched directly, they // may receive events from their source buffers that were touched directly, and so FinalApply() will need // to be invoked on them in order to construct a snapshot that matches the last snapshots of their source buffers). foreach (ITextBuffer sourceBuffer in projectionBuffer.SourceBuffers) { IProjectionBufferBase sourceProjectionBuffer = sourceBuffer as IProjectionBufferBase; if (sourceProjectionBuffer != null) { BaseBuffer baseSourceBuffer = (BaseBuffer)sourceBuffer; if (!this.buffer2EditMap.ContainsKey(baseSourceBuffer)) { this.buffer2EditMap.Add(sourceBuffer, (baseSourceBuffer.CreateSubordinateEdit(this.masterOptions, null, this.masterEditTag))); } } } } }
private void RemoveSourceBuffer(IProjectionBufferBase projBuffer, ITextBuffer sourceBuffer, FrugalList <ITextBuffer> removedFromGraphBuffers) { IList <IProjectionBufferBase> importingProjectionBuffers = this.importingProjectionBufferMap[sourceBuffer]; importingProjectionBuffers.Remove(projBuffer); if (importingProjectionBuffers.Count == 0) { removedFromGraphBuffers.Add(sourceBuffer); this.importingProjectionBufferMap.Remove(sourceBuffer); for (int i = 0; (i < this.eventHooks.Count); ++i) { if (this.eventHooks[i].SourceBuffer == sourceBuffer) { this.eventHooks[i].UnsubscribeFromSourceBuffer(); this.eventHooks.RemoveAt(i); break; } } IProjectionBufferBase removedProjBufferBase = sourceBuffer as IProjectionBufferBase; if (removedProjBufferBase != null) { foreach (ITextBuffer furtherSourceBuffer in removedProjBufferBase.SourceBuffers) { RemoveSourceBuffer(removedProjBufferBase, furtherSourceBuffer, removedFromGraphBuffers); } } } }
private void BuildGraph() { // Police this.members by removing the expired ones this.members.RemoveWhere((member) => member.Buffer == null); this.graph = new Dictionary <BaseBuffer, GraphEntry>(this.members.Count); foreach (BufferWeakReference bufferWeakReference in this.members) { var buffer = bufferWeakReference.Buffer; if (buffer != null) //There could have been a GC between the police action above and here. { graph.Add(buffer, new GraphEntry(new HashSet <IProjectionBufferBase>(), false, false)); } } foreach (BufferWeakReference bufferWeakReference in this.members) { IProjectionBufferBase p = bufferWeakReference.Buffer as IProjectionBufferBase; if (p != null) { foreach (BaseBuffer source in p.SourceBuffers) { graph[source].Targets.Add(p); } } } MarkMasterClosure(this.masterBuffer); }
private static bool IsSourceBuffer(IProjectionBufferBase top, ITextBuffer bottom) { return(top.SourceBuffers.Contains(bottom) || top.SourceBuffers .OfType <IProjectionBufferBase>() .Any(b => IsSourceBuffer(b, bottom))); }
private void SourceBuffersChanged(object sender, ProjectionSourceBuffersChangedEventArgs e) { IProjectionBufferBase projBuffer = (IProjectionBufferBase)sender; FrugalList <ITextBuffer> addedToGraphBuffers = new FrugalList <ITextBuffer>(); FrugalList <ITextBuffer> removedFromGraphBuffers = new FrugalList <ITextBuffer>(); foreach (ITextBuffer addedBuffer in e.AddedBuffers) { AddSourceBuffer(projBuffer, addedBuffer, addedToGraphBuffers); } foreach (ITextBuffer removedBuffer in e.RemovedBuffers) { RemoveSourceBuffer(projBuffer, removedBuffer, removedFromGraphBuffers); } if (addedToGraphBuffers.Count > 0 || removedFromGraphBuffers.Count > 0) { var listeners = GraphBuffersChanged; if (listeners != null) { ((BaseBuffer)projBuffer).group.EnqueueEvents (new GraphEventRaiser(this, new GraphBuffersChangedEventArgs(addedToGraphBuffers, removedFromGraphBuffers)), null); } } }
public BufferGraph(ITextBuffer topBuffer, GuardedOperations guardedOperations) { if (topBuffer == null) { throw new ArgumentNullException("topBuffer"); } if (guardedOperations == null) { throw new ArgumentNullException("guardedOperations"); } this.topBuffer = topBuffer; this.guardedOperations = guardedOperations; this.importingProjectionBufferMap.Add(topBuffer, null); // The top buffer has no targets, but it is put here so membership in this map can be used uniformly // to determine whether a buffer is in the buffer graph // Subscribe to content type changed events on the toplevel buffer this.eventHooks.Add(new WeakEventHookForBufferGraph(this, topBuffer)); IProjectionBufferBase projectionBufferBase = topBuffer as IProjectionBufferBase; if (projectionBufferBase != null) { IList <ITextBuffer> sourceBuffers = projectionBufferBase.SourceBuffers; FrugalList <ITextBuffer> dontCare = new FrugalList <ITextBuffer>(); foreach (ITextBuffer sourceBuffer in sourceBuffers) { AddSourceBuffer(projectionBufferBase, sourceBuffer, dontCare); } } }
private void RaiseProjectionBufferCreatedEvent(IProjectionBufferBase buffer) { EventHandler <TextBufferCreatedEventArgs> handler = ProjectionBufferCreated; if (handler != null) { handler(this, new TextBufferCreatedEventArgs(buffer)); } }
public SnapshotPoint?MapDownToFirstMatch(SnapshotPoint position, PointTrackingMode trackingMode, Predicate <ITextSnapshot> match, PositionAffinity affinity) { if (position.Snapshot == null) { throw new ArgumentNullException("position"); } if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative) { throw new ArgumentOutOfRangeException("trackingMode"); } if (match == null) { throw new ArgumentNullException("match"); } if (affinity < PositionAffinity.Predecessor || affinity > PositionAffinity.Successor) { throw new ArgumentOutOfRangeException("affinity"); } if (!this.importingProjectionBufferMap.ContainsKey(position.Snapshot.TextBuffer)) { return(null); } ITextBuffer currentBuffer = position.Snapshot.TextBuffer; ITextSnapshot currentSnapshot = currentBuffer.CurrentSnapshot; int currentPosition = position.TranslateTo(currentSnapshot, trackingMode).Position; while (!match(currentSnapshot)) { IProjectionBufferBase projBuffer = currentBuffer as IProjectionBufferBase; if (projBuffer == null) { return(null); } IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot; if (projSnap.SourceSnapshots.Count == 0) { return(null); } SnapshotPoint currentPoint = projSnap.MapToSourceSnapshot(currentPosition, affinity); currentPosition = currentPoint.Position; currentSnapshot = currentPoint.Snapshot; currentBuffer = currentSnapshot.TextBuffer; } return(new SnapshotPoint(currentSnapshot, currentPosition)); }
private void Traverse(ITextBuffer buffer, List <ITextBuffer> result, HashSet <ITextBuffer> processed) { processed.Add(buffer); IProjectionBufferBase proj = buffer as IProjectionBufferBase; if (proj != null) { foreach (ITextBuffer sourceBuffer in proj.SourceBuffers) { if (!processed.Contains(sourceBuffer)) { Traverse(sourceBuffer, result, processed); } } } result.Add(buffer); }
private void MarkMasterClosure(BaseBuffer buffer) { GraphEntry g = this.graph[buffer]; if (!g.Dependent) { g.Dependent = true; IProjectionBufferBase projectionBuffer = buffer as IProjectionBufferBase; if (projectionBuffer != null) { foreach (BaseBuffer source in projectionBuffer.SourceBuffers) { MarkMasterClosure(source); } } } }
public SnapshotPoint?MapDownToBuffer(SnapshotPoint position, PointTrackingMode trackingMode, ITextBuffer targetBuffer, PositionAffinity affinity) { if (position.Snapshot == null) { throw new ArgumentNullException("position"); } if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative) { throw new ArgumentOutOfRangeException("trackingMode"); } if (targetBuffer == null) { throw new ArgumentNullException("targetBuffer"); } if (affinity < PositionAffinity.Predecessor || affinity > PositionAffinity.Successor) { throw new ArgumentOutOfRangeException("affinity"); } ITextBuffer currentBuffer = position.Snapshot.TextBuffer; ITextSnapshot currentSnapshot = currentBuffer.CurrentSnapshot; int currentPosition = position.TranslateTo(currentSnapshot, trackingMode).Position; while (currentBuffer != targetBuffer) { IProjectionBufferBase projBuffer = currentBuffer as IProjectionBufferBase; if (projBuffer == null) { return(null); } IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot; if (projSnap.SourceSnapshots.Count == 0) { return(null); } SnapshotPoint currentPoint = projSnap.MapToSourceSnapshot(currentPosition, affinity); currentPosition = currentPoint.Position; currentSnapshot = currentPoint.Snapshot; currentBuffer = currentSnapshot.TextBuffer; } return(new SnapshotPoint(currentSnapshot, currentPosition)); }
public SnapshotPoint?MapDownToInsertionPoint(SnapshotPoint position, PointTrackingMode trackingMode, Predicate <ITextSnapshot> match) { if (position.Snapshot == null) { throw new ArgumentNullException("position"); } if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative) { throw new ArgumentOutOfRangeException("trackingMode"); } if (match == null) { throw new ArgumentNullException("match"); } ITextBuffer currentBuffer = position.Snapshot.TextBuffer; int currentPosition = position.TranslateTo(currentBuffer.CurrentSnapshot, trackingMode); ITextSnapshot currentSnapshot = currentBuffer.CurrentSnapshot; while (!match(currentSnapshot)) { IProjectionBufferBase projBuffer = currentBuffer as IProjectionBufferBase; if (projBuffer == null) { return(null); } IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot; if (projSnap.SourceSnapshots.Count == 0) { return(null); } SnapshotPoint currentPoint = projSnap.MapToSourceSnapshot(currentPosition); currentPosition = currentPoint.Position; currentSnapshot = currentPoint.Snapshot; currentBuffer = currentSnapshot.TextBuffer; } return(new SnapshotPoint(currentSnapshot, currentPosition)); }
private static FrugalList <SnapshotSpan> MapDownOneLevel(FrugalList <SnapshotSpan> inputSpans, Predicate <ITextSnapshot> match, ref ITextSnapshot chosenSnapshot, ref FrugalList <Span> targetSpans) { FrugalList <SnapshotSpan> downSpans = new FrugalList <SnapshotSpan>(); foreach (SnapshotSpan inputSpan in inputSpans) { IProjectionBufferBase projBuffer = (IProjectionBufferBase)inputSpan.Snapshot.TextBuffer; IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot; if (projSnap.SourceSnapshots.Count > 0) { IList <SnapshotSpan> mappedSpans = projSnap.MapToSourceSnapshots(inputSpan); for (int s = 0; s < mappedSpans.Count; ++s) { SnapshotSpan mappedSpan = mappedSpans[s]; ITextBuffer mappedBuffer = mappedSpan.Snapshot.TextBuffer; if (mappedBuffer.CurrentSnapshot == chosenSnapshot) { targetSpans.Add(mappedSpan.Span); } else if (chosenSnapshot == null && match(mappedBuffer.CurrentSnapshot)) { chosenSnapshot = mappedBuffer.CurrentSnapshot; targetSpans.Add(mappedSpan.Span); } else { IProjectionBufferBase mappedProjBuffer = mappedBuffer as IProjectionBufferBase; if (mappedProjBuffer != null) { downSpans.Add(mappedSpan); } } } } } return(downSpans); }
public IDifferenceBuffer TryGetDifferenceBuffer(IProjectionBufferBase projectionBuffer) => throw new System.NotImplementedException();
private static bool IsSourceBuffer(IProjectionBufferBase top, ITextBuffer bottom) { return top.SourceBuffers.Contains(bottom) || top.SourceBuffers.OfType<IProjectionBufferBase>().Any(b => IsSourceBuffer(b, bottom)); }
private static bool IsSourceBuffer(IProjectionBufferBase top, ITextBuffer bottom) { return top.SourceBuffers.Contains(bottom) || top.SourceBuffers.Any((ITextBuffer tb) => tb is IProjectionBufferBase && IsSourceBuffer((IProjectionBufferBase)tb, bottom)); }
private static bool IsSourceBuffer(IProjectionBufferBase top, ITextBuffer bottom) { return(top.SourceBuffers.Contains(bottom) || top.SourceBuffers.Any((ITextBuffer tb) => tb is IProjectionBufferBase && IsSourceBuffer((IProjectionBufferBase)tb, bottom))); }