From 3f8e571b7887758514645c46b2b26d7c3fc82e45 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 18 Jul 2011 02:01:12 +0100 Subject: Use a standard generic system stack for the undo/redo stacks instead of our own homebrew. system stack also uses an array, so no performance penalty. Also exposes undo count and adds a test assertion for correct undo count after resize --- OpenSim/Framework/UndoStack.cs | 40 +++++++++++++++++++++- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 16 +++++++-- .../Scenes/Tests/SceneObjectResizeTests.cs | 2 ++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/OpenSim/Framework/UndoStack.cs b/OpenSim/Framework/UndoStack.cs index fde63b1..8f8849d 100644 --- a/OpenSim/Framework/UndoStack.cs +++ b/OpenSim/Framework/UndoStack.cs @@ -45,59 +45,96 @@ namespace OpenSim.Framework m_Undos = new T[capacity + 1]; } + /// + /// Is the stack full? + /// public bool IsFull { - get { return m_new == m_old; } + get + { + // If the old and new pointers are in the same place then all stack slots are occupied. + return m_new == m_old; + } } + /// + /// Capacity of the stack. + /// public int Capacity { get { return m_Undos.Length - 1; } } + /// + /// Return the number of undos on the stack. + /// public int Count { get { int count = m_new - m_old - 1; + if (count < 0) count += m_Undos.Length; + return count; } } + /// + /// Push a new undo onto the stack. + /// + /// public void Push(T item) { if (IsFull) { m_old++; + if (m_old >= m_Undos.Length) m_old -= m_Undos.Length; } + if (++m_new >= m_Undos.Length) m_new -= m_Undos.Length; + m_Undos[m_new] = item; } + /// + /// Pop and item from the top of the undo stack. + /// + /// public T Pop() { if (Count > 0) { T deleted = m_Undos[m_new]; m_Undos[m_new--] = default(T); + if (m_new < 0) m_new += m_Undos.Length; + return deleted; } else + { throw new InvalidOperationException("Cannot pop from empty stack"); + } } + /// + /// Peek at the undo on the top of the stack. + /// + /// public T Peek() { return m_Undos[m_new]; } + /// + /// Clear the stack. + /// public void Clear() { if (Count > 0) @@ -106,6 +143,7 @@ namespace OpenSim.Framework { m_Undos[i] = default(T); } + m_new = 1; m_old = 0; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 253326e..a1200ee 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -287,8 +287,8 @@ namespace OpenSim.Region.Framework.Scenes private string m_sitAnimation = "SIT"; private string m_text = String.Empty; private string m_touchName = String.Empty; - private readonly UndoStack m_undo = new UndoStack(5); - private readonly UndoStack m_redo = new UndoStack(5); + private readonly Stack m_undo = new Stack(5); + private readonly Stack m_redo = new Stack(5); private UUID _creatorID; private bool m_passTouches; @@ -3707,6 +3707,18 @@ namespace OpenSim.Region.Framework.Scenes // } } + /// + /// Return number of undos on the stack. Here temporarily pending a refactor. + /// + public int UndoCount + { + get + { + lock (m_undo) + return m_undo.Count; + } + } + public void Undo() { // m_log.DebugFormat("[SCENE OBJECT PART]: Handling undo request for {0} {1}", Name, LocalId); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index 7ec36b8..6dbac3c 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -62,6 +62,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(g1Post.RootPart.Scale.X, Is.EqualTo(2)); Assert.That(g1Post.RootPart.Scale.Y, Is.EqualTo(3)); Assert.That(g1Post.RootPart.Scale.Z, Is.EqualTo(4)); + + Assert.That(g1Post.RootPart.UndoCount, Is.EqualTo(1)); } /// -- cgit v1.1