コード例 #1
0
 /// <summary>
 /// Gets whether this checkpoint belongs to the same document as the other checkpoint.
 /// </summary>
 public bool BelongsToSameDocumentAs(ChangeTrackingCheckpoint other)
 {
     if (other == null)
         throw new ArgumentNullException("other");
     return documentIdentifier == other.documentIdentifier;
 }
コード例 #2
0
 /// <summary>
 /// Compares the age of this checkpoint to the other checkpoint.
 /// </summary>
 /// <remarks>This method is thread-safe.</remarks>
 /// <exception cref="ArgumentException">Raised if 'other' belongs to a different document than this checkpoint.</exception>
 /// <returns>-1 if this checkpoint is older than <paramref name="other"/>.
 /// 0 if <c>this</c>==<paramref name="other"/>.
 /// 1 if this checkpoint is newer than <paramref name="other"/>.</returns>
 public int CompareAge(ChangeTrackingCheckpoint other)
 {
     if (other == null)
         throw new ArgumentNullException("other");
     if (other.documentIdentifier != this.documentIdentifier)
         throw new ArgumentException("Checkpoints do not belong to the same document.");
     // We will allow overflows, but assume that the maximum distance between checkpoints is 2^31-1.
     // This is guaranteed on x86 because so many checkpoints don't fit into memory.
     return Math.Sign(unchecked( this.id - other.id ));
 }
コード例 #3
0
 internal ChangeTrackingCheckpoint Append(DocumentChangeEventArgs change)
 {
     Debug.Assert(this.next == null);
     this.next = new ChangeTrackingCheckpoint(this.documentIdentifier, change, unchecked( this.id + 1 ));
     return this.next;
 }
コード例 #4
0
 IEnumerable<DocumentChangeEventArgs> GetForwardChanges(ChangeTrackingCheckpoint other)
 {
     // Return changes from this(exclusive) to other(inclusive).
     ChangeTrackingCheckpoint node = this;
     do {
         node = node.next;
         yield return node.value;
     } while (node != other);
 }
コード例 #5
0
 /// <summary>
 /// Calculates where the offset has moved in the other buffer version.
 /// </summary>
 /// <remarks>This method is thread-safe.</remarks>
 /// <exception cref="ArgumentException">Raised if 'other' belongs to a different document than this checkpoint.</exception>
 public int MoveOffsetTo(ChangeTrackingCheckpoint other, int oldOffset, AnchorMovementType movement)
 {
     int offset = oldOffset;
     foreach (DocumentChangeEventArgs e in GetChangesTo(other)) {
         offset = e.GetNewOffset(offset, movement);
     }
     return offset;
 }
コード例 #6
0
 /// <summary>
 /// Gets the changes from this checkpoint to the other checkpoint.
 /// If 'other' is older than this checkpoint, reverse changes are calculated.
 /// </summary>
 /// <remarks>This method is thread-safe.</remarks>
 /// <exception cref="ArgumentException">Raised if 'other' belongs to a different document than this checkpoint.</exception>
 public IEnumerable<DocumentChangeEventArgs> GetChangesTo(ChangeTrackingCheckpoint other)
 {
     int result = CompareAge(other);
     if (result < 0)
         return GetForwardChanges(other);
     else if (result > 0)
         return other.GetForwardChanges(this).Reverse().Select(change => change.Invert());
     else
         return Empty<DocumentChangeEventArgs>.Array;
 }
コード例 #7
0
ファイル: TextDocument.cs プロジェクト: eolandezhang/Diagram
        void DoReplace(int offset, int length, string newText, OffsetChangeMap offsetChangeMap)
        {
            if (length == 0 && newText.Length == 0)
                return;

            // trying to replace a single character in 'Normal' mode?
            // for single characters, 'CharacterReplace' mode is equivalent, but more performant
            // (we don't have to touch the anchorTree at all in 'CharacterReplace' mode)
            if (length == 1 && newText.Length == 1 && offsetChangeMap == null)
                offsetChangeMap = OffsetChangeMap.Empty;

            string removedText = rope.ToString(offset, length);
            DocumentChangeEventArgs args = new DocumentChangeEventArgs(offset, removedText, newText, offsetChangeMap);

            // fire DocumentChanging event
            if (Changing != null)
                Changing(this, args);

            undoStack.Push(this, args);

            cachedText = null; // reset cache of complete document text
            fireTextChanged = true;
            DelayedEvents delayedEvents = new DelayedEvents();

            lock (lockObject) {
                // create linked list of checkpoints, if required
                if (currentCheckpoint != null) {
                    currentCheckpoint = currentCheckpoint.Append(args);
                }

                // now update the textBuffer and lineTree
                if (offset == 0 && length == rope.Length) {
                    // optimize replacing the whole document
                    rope.Clear();
                    rope.InsertText(0, newText);
                    lineManager.Rebuild();
                } else {
                    rope.RemoveRange(offset, length);
                    lineManager.Remove(offset, length);
                    #if DEBUG
                    lineTree.CheckProperties();
                    #endif
                    rope.InsertText(offset, newText);
                    lineManager.Insert(offset, newText);
                    #if DEBUG
                    lineTree.CheckProperties();
                    #endif
                }
            }

            // update text anchors
            if (offsetChangeMap == null) {
                anchorTree.HandleTextChange(args.CreateSingleChangeMapEntry(), delayedEvents);
            } else {
                foreach (OffsetChangeMapEntry entry in offsetChangeMap) {
                    anchorTree.HandleTextChange(entry, delayedEvents);
                }
            }

            // raise delayed events after our data structures are consistent again
            delayedEvents.RaiseEvents();

            // fire DocumentChanged event
            if (Changed != null)
                Changed(this, args);
        }
コード例 #8
0
ファイル: TextDocument.cs プロジェクト: eolandezhang/Diagram
 internal ChangeTrackingCheckpoint CreateChangeTrackingCheckpoint()
 {
     lock (lockObject) {
         if (currentCheckpoint == null)
             currentCheckpoint = new ChangeTrackingCheckpoint(lockObject);
         return currentCheckpoint;
     }
 }
コード例 #9
0
ファイル: TextDocument.cs プロジェクト: eolandezhang/Diagram
 public ITextSource CreateSnapshot(out ChangeTrackingCheckpoint checkpoint)
 {
     lock (lockObject) {
         if (currentCheckpoint == null)
             currentCheckpoint = new ChangeTrackingCheckpoint(lockObject);
         checkpoint = currentCheckpoint;
         return new RopeTextSource(rope.Clone());
     }
 }