private void LengthChangedHandler(Rope sender, int newLength) { if (Object.Equals(sender, Left)) { LeftLengthCache = newLength; } if (Object.Equals(sender, Right)) { RightLengthCache = newLength; } LengthChangedAction?.Invoke(this, LeftLengthCache + RightLengthCache); }
public Rope Remove(int start, int length) { if (IsLeaf) { if (Leaf.Length < start) { throw new ArgumentOutOfRangeException("Start is after the length of this string. Cant remove"); } if (start + length < Leaf.Length) { //need to split the leaf into left and right var newRight = new Rope { Leaf = new LeafSection(Leaf.Base, Leaf.Start + start + length, Leaf.Length - (start + length)), LengthChangedAction = LengthChangedHandler }; var newLeft = new Rope { Leaf = new LeafSection(Leaf.Base, Leaf.Start, start), LengthChangedAction = LengthChangedHandler }; this.Right = newRight; this.Left = newLeft; } else if (start == 0) { //need to remove the begining Leaf.Start += length; Leaf.Length -= length; } else { //need to remove the end Leaf.Length = start; } LengthChangedAction?.Invoke(this, Length); } else { var leftLen = LeftLength(); if (start < leftLen) { var lenInLeft = Math.Min(leftLen - start, length); Left.Remove(start, lenInLeft); if (lenInLeft < length) { Right.Remove(0, length - lenInLeft); } } else { Right.Remove(start - leftLen, length); } if (Right?.Length == 0) { Right = null; } if (Left?.Length == 0) { //if left is empty then move right to left if (Right == null) { Left = null; } else { Left = Right; Right = null; } } } return(this); }