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 resizebulletsim
parent
bdd340b9fc
commit
3f8e571b78
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue