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