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
bulletsim
Justin Clark-Casey (justincc) 2011-07-18 02:01:12 +01:00
parent bdd340b9fc
commit 3f8e571b78
3 changed files with 55 additions and 3 deletions

View File

@ -45,59 +45,96 @@ namespace OpenSim.Framework
m_Undos = new T[capacity + 1];
}
/// <summary>
/// Is the stack full?
/// </summary>
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;
}
}
/// <summary>
/// Capacity of the stack.
/// </summary>
public int Capacity
{
get { return m_Undos.Length - 1; }
}
/// <summary>
/// Return the number of undos on the stack.
/// </summary>
public int Count
{
get
{
int count = m_new - m_old - 1;
if (count < 0)
count += m_Undos.Length;
return count;
}
}
/// <summary>
/// Push a new undo onto the stack.
/// </summary>
/// <param name="item"></param>
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;
}
/// <summary>
/// Pop and item from the top of the undo stack.
/// </summary>
/// <returns></returns>
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");
}
}
/// <summary>
/// Peek at the undo on the top of the stack.
/// </summary>
/// <returns></returns>
public T Peek()
{
return m_Undos[m_new];
}
/// <summary>
/// Clear the stack.
/// </summary>
public void Clear()
{
if (Count > 0)
@ -106,6 +143,7 @@ namespace OpenSim.Framework
{
m_Undos[i] = default(T);
}
m_new = 1;
m_old = 0;
}

View File

@ -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<UndoState> m_undo = new UndoStack<UndoState>(5);
private readonly UndoStack<UndoState> m_redo = new UndoStack<UndoState>(5);
private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5);
private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5);
private UUID _creatorID;
private bool m_passTouches;
@ -3707,6 +3707,18 @@ namespace OpenSim.Region.Framework.Scenes
// }
}
/// <summary>
/// Return number of undos on the stack. Here temporarily pending a refactor.
/// </summary>
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);

View File

@ -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));
}
/// <summary>