Watch sorting - new algorithm that handles separators.

Also moved comparers from fields into a dictionary to make selection more concise.
This commit is contained in:
Zinfidel 2019-11-27 20:52:08 -08:00
parent 92b0505c41
commit b3875e21ae
1 changed files with 39 additions and 115 deletions

View File

@ -30,14 +30,7 @@ namespace BizHawk.Client.Common
public const string DOMAIN = "DomainColumn";
public const string NOTES = "NotesColumn";
private static readonly WatchDomainComparer DomainComparer = new WatchDomainComparer();
private static readonly WatchAddressComparer AddressComparer = new WatchAddressComparer();
private static readonly WatchFullDisplayTypeComparer DisplayTypeComparer = new WatchFullDisplayTypeComparer();
private static readonly WatchValueComparer ValueComparer = new WatchValueComparer();
private static readonly WatchPreviousValueComparer PreviousValueComparer = new WatchPreviousValueComparer();
private static readonly WatchValueDifferenceComparer ValueDifferenceComparer = new WatchValueDifferenceComparer();
private static readonly WatchChangeCountComparer ChangeCountComparer = new WatchChangeCountComparer();
private static readonly WatchNoteComparer NoteComparer = new WatchNoteComparer();
private static readonly Dictionary<string, IComparer<Watch>> WatchComparers;
private readonly List<Watch> _watchList = new List<Watch>(0);
private readonly string _systemId;
@ -47,6 +40,25 @@ namespace BizHawk.Client.Common
#region cTor(s)
/// <summary>
/// Static constructor for the <see cref="WatchList"/> class.
/// </summary>
static WatchList()
{
// Initialize mapping of columns to comparers for sorting.
WatchComparers = new Dictionary<string, IComparer<Watch>>
{
{ ADDRESS, new WatchAddressComparer() },
{ VALUE, new WatchValueComparer() },
{ PREV, new WatchPreviousValueComparer() },
{ CHANGES, new WatchChangeCountComparer() },
{ DIFF, new WatchValueDifferenceComparer() },
{ TYPE, new WatchFullDisplayTypeComparer() },
{ DOMAIN, new WatchDomainComparer() },
{ NOTES, new WatchNoteComparer() }
};
}
/// <summary>
/// Initializes a new instance of the <see cref="WatchList"/> class
/// that will contains a set of <see cref="Watch"/>
@ -213,117 +225,29 @@ namespace BizHawk.Client.Common
}
/// <summary>
/// Sort the current list based on one of the constant
/// Sort the current list based on one of the column constants.
/// </summary>
/// <param name="column">Value that specify sorting base</param>
/// <param name="reverse">Value that define the ordering. Ascending (true) or descending (false)</param>
/// <param name="column">The column to sort by.</param>
/// <param name="reverse">Defines the order of the sort. Ascending (true) or descending (false)</param>
public void OrderWatches(string column, bool reverse)
{
switch (column)
var separatorIndices = _watchList.Select((w, i) => new { watch = w, index = i })
.Where(w => w.watch.IsSeparator)
.Select(w => w.index)
.ToList();
separatorIndices.Add(_watchList.Count);
// Sort "blocks" of addresses between separators.
int startIndex = 0;
foreach (int index in separatorIndices)
{
case ADDRESS:
if (reverse)
{
_watchList.Sort(AddressComparer);
_watchList.Reverse();
}
else
{
_watchList.Sort();
}
break;
case VALUE:
if (reverse)
{
_watchList.Sort(ValueComparer);
_watchList.Reverse();
}
else
{
_watchList.Sort(ValueComparer);
}
break;
case PREV:
if (reverse)
{
_watchList.Sort(PreviousValueComparer);
_watchList.Reverse();
}
else
{
_watchList.Sort(PreviousValueComparer);
}
break;
case DIFF:
if (reverse)
{
_watchList.Sort(ValueDifferenceComparer);
_watchList.Reverse();
}
else
{
_watchList.Sort(ValueDifferenceComparer);
}
break;
case CHANGES:
if (reverse)
{
_watchList.Sort(ChangeCountComparer);
_watchList.Reverse();
}
else
{
_watchList.Sort(ChangeCountComparer);
}
break;
case DOMAIN:
if (reverse)
{
_watchList.Sort(DomainComparer);
_watchList.Reverse();
}
else
{
_watchList.Sort(DomainComparer);
}
break;
case TYPE:
if (reverse)
{
_watchList.Sort(DisplayTypeComparer);
_watchList.Reverse();
}
else
{
_watchList.Sort(DisplayTypeComparer);
}
break;
case NOTES:
if (reverse)
{
_watchList.Sort(NoteComparer);
_watchList.Reverse();
}
else
{
_watchList.Sort(NoteComparer);
}
break;
_watchList.Sort(startIndex, index - startIndex, WatchComparers[column]);
if (reverse)
{
_watchList.Reverse(startIndex, index - startIndex);
}
startIndex = index + 1;
}
}