Beispiel #1
0
        public void LargerThanOperatorWithFirstObjectNull()
        {
            TimeMarker first  = null;
            var        second = new TimeMarker(1);

            Assert.IsFalse(first > second);
        }
        /// <summary>
        /// Moves the history back enough steps to make the last known time is equal to or smaller than the
        /// provided mark.
        /// </summary>
        /// <param name="mark">The mark that indicates to which point in time the roll-back should be performed.</param>
        /// <param name="action">The action that should be executed on each single time step which is rolled back.</param>
        /// <returns>
        ///     The last recorded value.
        /// </returns>
        private T RollBackInTimeTo(TimeMarker mark, Action <TimeMarker, T> action)
        {
            {
                Debug.Assert(!IsAtBeginOfTime(), "Should not roll back past the beginning of time.");
            }

            bool hasChanged = false;

            // We assume that it is more likely that we have a more recent
            // point in time that we want to roll back to. So start searching
            // from the end of the collection
            var lastNode = m_PastValues.Last;

            while ((lastNode != null) && (lastNode.Value.Time > mark))
            {
                m_PastValues.RemoveLast();
                m_FutureValues.AddFirst(lastNode);

                if (action != null)
                {
                    action(lastNode.Value.Time, lastNode.Value.Value);
                }

                lastNode   = m_PastValues.Last;
                hasChanged = true;
            }

            if (hasChanged)
            {
                RaiseOnCurrentValueChange();
            }

            return((m_PastValues.Last != null) ? m_PastValues.Last.Value.Value : default(T));
        }
Beispiel #3
0
        public void CompareToWithSmallerFirstObject()
        {
            var    first  = new TimeMarker(1);
            object second = new TimeMarker(2);

            Assert.IsTrue(first.CompareTo(second) < 0);
        }
Beispiel #4
0
        public void CompareToWithUnequalObjectTypes()
        {
            var first  = new TimeMarker(1);
            var second = new object();

            Assert.Throws <ArgumentException>(() => first.CompareTo(second));
        }
Beispiel #5
0
        public void CompareToWithNullObject()
        {
            var    first  = new TimeMarker(1);
            object second = null;

            Assert.AreEqual(1, first.CompareTo(second));
        }
Beispiel #6
0
        public void CompareToOperatorWithEqualObjects()
        {
            var    first  = new TimeMarker(1);
            object second = new TimeMarker(1);

            Assert.AreEqual(0, first.CompareTo(second));
        }
Beispiel #7
0
        public void SmallerThanOperatorWithFirstObjectSmaller()
        {
            var first  = new TimeMarker(1);
            var second = new TimeMarker(2);

            Assert.IsTrue(first < second);
        }
Beispiel #8
0
        public void Clone()
        {
            var first  = new TimeMarker(1);
            var second = new TimeMarker(first);

            Assert.AreEqual(first, second);
        }
Beispiel #9
0
        public void SmallerThanOperatorWithEqualObjects()
        {
            var first  = new TimeMarker(1);
            var second = new TimeMarker(1);

            Assert.IsFalse(first < second);
        }
Beispiel #10
0
        public void SmallerThanOperatorWithBothObjectsNull()
        {
            TimeMarker first  = null;
            TimeMarker second = null;

            Assert.IsFalse(first < second);
        }
Beispiel #11
0
        public void SmallerThanOperatorWithSecondObjectNull()
        {
            var        first  = new TimeMarker(1);
            TimeMarker second = null;

            Assert.IsFalse(first < second);
        }
        /// <summary>
        /// Moves the history forward enough steps to make the next future time is equal to or larger than the
        /// provided mark.
        /// </summary>
        /// <param name="mark">The mark that indicates to which point in time the roll-forward should be performed.</param>
        /// <param name="action">The action that should be executed on each single time step which is rolled back.</param>
        /// <returns>
        ///     The last recorded value.
        /// </returns>
        private T RollForwardInTimeTo(TimeMarker mark, Action <TimeMarker, T> action)
        {
            {
                Debug.Assert(!IsAtEndOfTime(), "Should not be at the end of time.");
            }

            bool hasChanged = false;

            // We assume that it is more likely that we have a more recent
            // point in time that we want to roll forward to. So start searching
            // from the start of the collection
            while ((m_FutureValues.First != null) && (m_FutureValues.First.Value.Time <= mark))
            {
                var lastNode = m_FutureValues.First;
                m_FutureValues.RemoveFirst();
                m_PastValues.AddLast(lastNode);

                if (action != null)
                {
                    action(lastNode.Value.Time, lastNode.Value.Value);
                }

                hasChanged = true;
            }

            if (hasChanged)
            {
                RaiseOnCurrentValueChange();
            }

            return((m_PastValues.Last != null) ? m_PastValues.Last.Value.Value : default(T));
        }
        /// <summary>
        /// Stores the current value in the history list with the given marker.
        /// </summary>
        /// <param name="marker">The marker which indicates at which point on the timeline the data is stored.</param>
        /// <exception cref="CannotStoreValuesAtTheStartOfTimeException">
        ///     Thrown when <paramref name="marker"/> is equal to <see cref="TimeMarker.TheBeginOfTime"/>.
        /// </exception>
        public void StoreCurrent(TimeMarker marker)
        {
            {
                Lokad.Enforce.With <CannotStoreValuesAtTheStartOfTimeException>(
                    marker > TimeMarker.TheBeginOfTime,
                    Resources.Exceptions_Messages_CannotStoreValuesAtTheStartOfTime);
            }

            if (m_Changes.Count == 0)
            {
                return;
            }

            if (ShouldSnapshot())
            {
                CreateSnapshot(marker);
            }
            else
            {
                m_ValueHistory.StoreCurrent(marker, m_Changes);
            }

            m_Changes = new List <IHistoryChange <T> >();
            ForgetTheFuture();
        }
Beispiel #14
0
        public void RollForwardWithLocalChange()
        {
            var id       = new HistoryId();
            var timeline = new ObjectTimeline <MockHistoryObject>(id, BuildStorageOfType, BuildObject);

            var creationTime = new TimeMarker(1);

            timeline.AddToTimeline();
            timeline.Mark(creationTime);

            timeline.Object.SomeValue = 1;
            timeline.Object.LotsOfValues.Add(2);
            timeline.Mark(new TimeMarker(2));

            timeline.Object.SomeValue = 2;
            timeline.Object.LotsOfValues.Add(4);
            timeline.Mark(new TimeMarker(3));

            timeline.RollBackTo(new TimeMarker(2));
            timeline.Object.SomeValue = 3;
            timeline.Object.LotsOfValues.Add(8);

            timeline.RollForwardTo(new TimeMarker(3));
            Assert.AreEqual(2, timeline.Object.SomeValue);
            Assert.That(
                timeline.Object.LotsOfValues,
                Is.EquivalentTo(new int[] { 2, 4 }));
        }
Beispiel #15
0
        public void LargerThanOperatorWithSecondObjectNull()
        {
            var        first  = new TimeMarker(1);
            TimeMarker second = null;

            Assert.IsTrue(first > second);
        }
Beispiel #16
0
        public void RollBackFromDeathToLife()
        {
            var id       = new HistoryId();
            var timeline = new ObjectTimeline <MockHistoryObject>(id, BuildStorageOfType, BuildObject);

            var creationTime = new TimeMarker(1);

            timeline.AddToTimeline();
            timeline.Mark(creationTime);

            timeline.Object.SomeValue = 1;
            timeline.Object.LotsOfValues.Add(2);
            timeline.Mark(new TimeMarker(2));

            var deletionTime = new TimeMarker(3);

            timeline.DeleteFromTimeline();
            timeline.Mark(deletionTime);

            Assert.DoesNotThrow(() => timeline.RollBackTo(new TimeMarker(2)));
            Assert.IsTrue(timeline.IsAlive());
            Assert.IsNotNull(timeline.Object);
            Assert.AreEqual(1, timeline.Object.SomeValue);
            Assert.That(
                timeline.Object.LotsOfValues,
                Is.EquivalentTo(new int[] { 2 }));
        }
Beispiel #17
0
        public void RollForwardPastDeath()
        {
            var id       = new HistoryId();
            var timeline = new ObjectTimeline <MockHistoryObject>(id, BuildStorageOfType, BuildObject);

            var creationTime = new TimeMarker(1);

            timeline.AddToTimeline();
            timeline.Mark(creationTime);

            timeline.Object.SomeValue = 1;
            timeline.Object.LotsOfValues.Add(2);
            timeline.Mark(new TimeMarker(2));

            var deletionTime = new TimeMarker(3);

            timeline.DeleteFromTimeline();
            timeline.Mark(deletionTime);

            timeline.RollBackTo(new TimeMarker(1));
            Assert.IsTrue(timeline.IsAlive());

            timeline.RollForwardTo(new TimeMarker(4));
            Assert.IsFalse(timeline.IsAlive());
            Assert.IsNull(timeline.Object);
        }
Beispiel #18
0
        public void RollBackToPreviousValue()
        {
            var id       = new HistoryId();
            var timeline = new ObjectTimeline <MockHistoryObject>(id, BuildStorageOfType, BuildObject);

            var creationTime = new TimeMarker(1);

            timeline.AddToTimeline();
            timeline.Mark(creationTime);

            int maximumValue = 10;

            for (int i = 1; i < maximumValue; i++)
            {
                timeline.Object.SomeValue = i;
                timeline.Object.LotsOfValues.Add(i);
                timeline.Mark(new TimeMarker((ulong)(i + 1)));
            }

            for (int i = maximumValue - 1; i > 0; i--)
            {
                timeline.RollBackTo(new TimeMarker((ulong)(i + 1)));
                Assert.AreEqual(i, timeline.Object.SomeValue);

                Assert.AreEqual(i, timeline.Object.LotsOfValues.Count);
                for (int j = 1; j <= i; j++)
                {
                    Assert.IsTrue(timeline.Object.LotsOfValues.Contains(j));
                }
            }
        }
Beispiel #19
0
        public void RollBackToBeginning()
        {
            var id       = new HistoryId();
            var timeline = new ObjectTimeline <MockHistoryObject>(id, BuildStorageOfType, BuildObject);

            var creationTime = new TimeMarker(1);

            timeline.AddToTimeline();
            timeline.Mark(creationTime);

            int maximumValue = 10;

            for (int i = 0; i < maximumValue; i++)
            {
                timeline.Object.SomeValue = i;
                timeline.Object.LotsOfValues.Add(i);
                timeline.Mark(new TimeMarker((ulong)(i + 2)));
            }

            timeline.RollBackTo(new TimeMarker(1));
            Assert.IsTrue(timeline.IsAlive());
            Assert.IsNotNull(timeline.Object);
            Assert.AreEqual(0, timeline.Object.SomeValue);
            Assert.AreEqual(0, timeline.Object.LotsOfValues.Count);
        }
Beispiel #20
0
        /// <summary>
        /// Stores the current object state for the given marker.
        /// </summary>
        /// <param name="marker">The marker which indicates at which point on the timeline the data is stored.</param>
        public void Mark(TimeMarker marker)
        {
            if (!IsAlive() && (m_CreationTime == null))
            {
                return;
            }

            if (!IsAlive() && (m_DeletionTime == null))
            {
                m_DeletionTime = marker;
                return;
            }

            foreach (var timeline in m_Members)
            {
                Debug.Assert(timeline != null, "One of the member timelines has not been initialized.");
                timeline.StoreCurrent(marker);
            }

            if ((m_Object != null) && (m_CreationTime == null))
            {
                m_CreationTime = marker;
            }

            if (m_DeletionTime != null)
            {
                m_DeletionTime = null;
            }
        }
Beispiel #21
0
        public void DeleteFromTimeline()
        {
            var id       = new HistoryId();
            var timeline = new ObjectTimeline <MockHistoryObject>(id, BuildStorageOfType, BuildObject);

            timeline.AddToTimeline();
            var creationTime = new TimeMarker(1);

            timeline.Mark(creationTime);

            Assert.IsTrue(timeline.IsAlive());
            Assert.AreEqual(creationTime, timeline.CreationTime);
            Assert.IsNull(timeline.DeletionTime);
            Assert.IsNotNull(timeline.Object);

            timeline.DeleteFromTimeline();
            var deletionTime = new TimeMarker(2);

            timeline.Mark(deletionTime);

            Assert.IsFalse(timeline.IsAlive());
            Assert.AreEqual(creationTime, timeline.CreationTime);
            Assert.AreEqual(deletionTime, timeline.DeletionTime);
            Assert.IsNull(timeline.Object);
        }
Beispiel #22
0
        /// <summary>
        /// Stores the current state with the given name and the dependencies and returns the <see cref="TimeMarker"/> that
        /// belongs to this change set.
        /// </summary>
        /// <param name="name">The name for the state.</param>
        /// <param name="dependencies">The dependencies that indicate if the current change set can be rolled back or rolled forward.</param>
        /// <returns>The time marker for the stored state.</returns>
        public TimeMarker Mark(string name, IEnumerable <UpdateFromHistoryDependency> dependencies)
        {
            m_Current = !string.IsNullOrEmpty(name) ? m_Current.Next(name) : m_Current.Next();
            MarkAtTime(m_Current, dependencies);

            return(m_Current);
        }
Beispiel #23
0
        /// <summary>
        /// Rolls the current value back to the value stored with the given <see cref="TimeMarker"/>.
        /// </summary>
        /// <param name="marker">The marker that indicates to which point in the history the value should be restored to.</param>
        public void RollBackTo(TimeMarker marker)
        {
            if (m_CreationTime == null)
            {
                // The object doesn't exist and we're trying to roll-back even further.
                return;
            }

            if ((m_DeletionTime != null) && (marker > m_DeletionTime))
            {
                // Rolling back to a time after we've already died. Do nothing
                return;
            }

            // Roll-back to a point in time before we existed
            if (marker < m_CreationTime)
            {
                RollBackToStart();
            }
            else
            {
                RollBackToPointInTime(marker);
            }

            RaiseOnRollBack();
        }
Beispiel #24
0
 private void RollFowardDependencies(TimeMarker mark)
 {
     if (!m_Dependencies.IsAtEndOfTime())
     {
         m_Dependencies.RollForwardTo(mark);
     }
 }
Beispiel #25
0
        /// <summary>
        /// Stores the current value as the default value which will be returned if there are no values stored.
        /// </summary>
        /// <exception cref="CannotSetDefaultAfterStartOfTimeException">
        /// Thrown when the user tries to store the default value after one or more value have been stored.
        /// </exception>
        public void SetCurrentAsDefault()
        {
            {
                Lokad.Enforce.With <CannotSetDefaultAfterStartOfTimeException>(
                    m_Markers.LastValue == null,
                    Resources.Exceptions_Messages_CannotSetDefaultAfterStartOfTime);
            }

            // All these objects have been created between the last mark and the new one.
            // They're about to become embedded in history forever.
            var newIds = new List <HistoryId>(m_NonMarkedObjectTimelines.Count);

            foreach (var pair in m_NonMarkedObjectTimelines)
            {
                m_ObjectTimelines.Add(pair.Key, pair.Value);
                newIds.Add(pair.Key);
            }

            m_NonMarkedObjectTimelines.Clear();

            m_Markers.StoreCurrent(TimeMarker.TheBeginOfTime, null);
            if (newIds.Count > 0)
            {
                m_CreatedObjectHistory.StoreCurrent(TimeMarker.TheBeginOfTime, newIds);
            }

            foreach (var pair in m_ObjectTimelines)
            {
                pair.Value.SetCurrentAsDefault();
            }

            m_Current = TimeMarker.TheBeginOfTime;
            m_Latest  = TimeMarker.TheBeginOfTime;
        }
Beispiel #26
0
 private void RollForwardMarkers(TimeMarker mark)
 {
     if (!m_Markers.IsAtEndOfTime())
     {
         m_Markers.RollForwardTo(mark);
     }
 }
Beispiel #27
0
 private void RollBackDependencies(TimeMarker mark)
 {
     if (!m_Dependencies.IsAtBeginOfTime())
     {
         m_Dependencies.RollBackTo(mark);
     }
 }
Beispiel #28
0
 private void RollBackMarkers(TimeMarker mark)
 {
     if (!m_Markers.IsAtBeginOfTime())
     {
         m_Markers.RollBackTo(mark);
     }
 }
Beispiel #29
0
        public void LargerThanOperatorWithFirstObjectSmaller()
        {
            var first  = new TimeMarker(1);
            var second = new TimeMarker(2);

            Assert.IsFalse(first > second);
        }
Beispiel #30
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TimelineMarkEventArgs"/> class.
        /// </summary>
        /// <param name="marker">The new marker.</param>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="marker"/> is <see langword="null" />.
        /// </exception>
        public TimelineMarkEventArgs(TimeMarker marker)
        {
            {
                Lokad.Enforce.Argument(() => marker);
            }

            m_Marker = marker;
        }