97 lines
1.8 KiB
C#
97 lines
1.8 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace BizHawk.Common
|
|
{
|
|
public class UndoHistory<T>
|
|
{
|
|
private List<List<T>> _history = new List<List<T>>();
|
|
private int _curPos; // 1-based
|
|
|
|
public int MaxUndoLevels { get; set; }
|
|
|
|
public UndoHistory(bool enabled)
|
|
{
|
|
MaxUndoLevels = 5;
|
|
Enabled = enabled;
|
|
}
|
|
|
|
public UndoHistory(IEnumerable<T> newState, bool enabled)
|
|
{
|
|
AddState(newState);
|
|
Enabled = enabled;
|
|
}
|
|
|
|
public bool Enabled { get; private set; }
|
|
|
|
public bool CanUndo
|
|
{
|
|
get { return Enabled && _curPos > 1; }
|
|
}
|
|
|
|
public bool CanRedo
|
|
{
|
|
get { return Enabled && _curPos < _history.Count; }
|
|
}
|
|
|
|
public bool HasHistory
|
|
{
|
|
get { return Enabled && _history.Any(); }
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
_history = new List<List<T>>();
|
|
_curPos = 0;
|
|
}
|
|
|
|
public void AddState(IEnumerable<T> newState)
|
|
{
|
|
if (Enabled)
|
|
{
|
|
if (_curPos < _history.Count)
|
|
{
|
|
for (var i = _curPos + 1; i <= _history.Count; i++)
|
|
{
|
|
_history.Remove(_history[i - 1]);
|
|
}
|
|
}
|
|
|
|
// TODO: don't assume we are one over, since MaxUndoLevels is public, it could be set to a small number after a large list has occured
|
|
if (_history.Count > MaxUndoLevels)
|
|
{
|
|
foreach (var item in _history.Take(_history.Count - MaxUndoLevels))
|
|
{
|
|
_history.Remove(item);
|
|
}
|
|
}
|
|
|
|
_history.Add(newState.ToList());
|
|
_curPos = _history.Count;
|
|
}
|
|
}
|
|
|
|
public IEnumerable<T> Undo()
|
|
{
|
|
if (CanUndo && Enabled)
|
|
{
|
|
_curPos--;
|
|
return _history[_curPos - 1];
|
|
}
|
|
|
|
return Enumerable.Empty<T>();
|
|
}
|
|
|
|
public IEnumerable<T> Redo()
|
|
{
|
|
if (CanRedo && Enabled)
|
|
{
|
|
_curPos++;
|
|
return _history[_curPos - 1];
|
|
}
|
|
|
|
return Enumerable.Empty<T>();
|
|
}
|
|
}
|
|
}
|