Esempio n. 1
0
        internal HighFidelityTrackingPoint(ITextVersion version, int position, PointTrackingMode trackingMode, TrackingFidelityMode fidelity)
            : base(version, position, trackingMode)
        {
            if (fidelity != TrackingFidelityMode.UndoRedo && fidelity != TrackingFidelityMode.Backward)
            {
                throw new ArgumentOutOfRangeException(nameof(fidelity));
            }
            List <VersionNumberPosition> initialHistory = null;

            if (fidelity == TrackingFidelityMode.UndoRedo && version.VersionNumber > 0)
            {
                // The system may perform undo operations that reach prior to the initial version; if any of
                // those transitions are noninvertible, then redoing back to the initial version will give the
                // wrong answer. Thus we save the state of the point for the initial version, unless the
                // initial version happens to be version zero (in which case we could not undo past it).

                initialHistory = new List <VersionNumberPosition>();

                if (version.VersionNumber != version.ReiteratedVersionNumber)
                {
                    Debug.Assert(version.ReiteratedVersionNumber < version.VersionNumber);
                    // If the current version and reiterated version differ, also remember the position
                    // using the reiterated version number, since when undoing back to this point it
                    // will be the key that is used.
                    initialHistory.Add(new VersionNumberPosition(version.ReiteratedVersionNumber, position));
                }

                initialHistory.Add(new VersionNumberPosition(version.VersionNumber, position));
            }
            this.cachedPosition = new VersionPositionHistory(version, position, initialHistory);
            this.fidelity       = fidelity;
        }
Esempio n. 2
0
        protected override int TrackPosition(ITextVersion targetVersion)
        {
            // Compute the new position on the requested snapshot.
            // This object caches the most recently requested version and the position in that version.
            //
            // We are relying on the atomicity of pointer copies (this.cachedPosition might change after we've
            // fetched it below but we will always get a self-consistent VersionPosition). This ensures we
            // have proper behavior when called from multiple threads (multiple threads may all track and update the
            // cached value if called at inconvenient times, but they will return consistent results).
            //
            // In most cases, one can track backwards from the cached version to a previously computed
            // version and get the same result, but this is not always the case: in particular, when the
            // position lies in a deleted region, simulating reinsertion of that region will not cause
            // the previous value of the position to be recovered. Such transitions are called noninvertible.
            // This class explicitly tracks the positions of the point for versions for which the subsequent
            // transition is noninvertible; this allows the value to be computed properly when tracking backwards
            // or in undo/redo situations.

            VersionPositionHistory cached = this.cachedPosition;    // must fetch just once

            if (targetVersion == cached.Version)
            {
                // easy!
                return(cached.Position);
            }

            List <VersionNumberPosition> noninvertibleHistory = cached.NoninvertibleHistory;
            int targetPosition;

            if (targetVersion.VersionNumber > cached.Version.VersionNumber)
            {
                // Roll the cached version forward to the requested version.
                targetPosition = TrackPositionForwardInTime
                                     (this.trackingMode,
                                     this.fidelity,
                                     ref noninvertibleHistory,
                                     cached.Position,
                                     cached.Version,
                                     targetVersion);

                // Cache new position
                this.cachedPosition = new VersionPositionHistory(targetVersion, targetPosition, noninvertibleHistory);
            }
            else
            {
                // roll backwards from the cached version
                targetPosition = TrackPositionBackwardInTime
                                     (this.trackingMode,
                                     this.fidelity == TrackingFidelityMode.Backward ? noninvertibleHistory : null,
                                     cached.Position,
                                     cached.Version,
                                     targetVersion);
            }
            return(targetPosition);
        }
Esempio n. 3
0
        public override string ToString()
        {
            VersionPositionHistory c = this.cachedPosition;

            System.Text.StringBuilder sb = new System.Text.StringBuilder("*");
            sb.Append(ToString(c.Version, c.Position, this.trackingMode));
            if (c.NoninvertibleHistory != null)
            {
                sb.Append("[");
                foreach (VersionNumberPosition vp in c.NoninvertibleHistory)
                {
                    sb.Append(string.Format(System.Globalization.CultureInfo.CurrentCulture, "V{0}@{1}", vp.VersionNumber, vp.Position));
                }
                sb.Append("]");
            }
            return(sb.ToString());
        }