Improve Criminal Records Computer usability (#30292)

* Avoid destroying and recreating record list on every update message

* Add early-out on nullptr input

* Remove sussy null suppress

---------

Co-authored-by: Eoin Mcloughlin <helloworld@eoinrul.es>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
eoineoineoin
2024-08-09 08:41:29 +01:00
committed by GitHub
parent 0b2fa941a7
commit d0a2187a9b

View File

@@ -7,10 +7,12 @@ using Content.Shared.Security;
using Content.Shared.StationRecords;
using Robust.Client.AutoGenerated;
using Robust.Client.Player;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;
using System.Linq;
namespace Content.Client.CriminalRecords;
@@ -36,7 +38,6 @@ public sealed partial class CriminalRecordsConsoleWindow : FancyWindow
public Action<SecurityStatus, string>? OnDialogConfirmed;
private uint _maxLength;
private bool _isPopulating;
private bool _access;
private uint? _selectedKey;
private CriminalRecord? _selectedRecord;
@@ -74,7 +75,7 @@ public sealed partial class CriminalRecordsConsoleWindow : FancyWindow
RecordListing.OnItemSelected += args =>
{
if (_isPopulating || RecordListing[args.ItemIndex].Metadata is not uint cast)
if (RecordListing[args.ItemIndex].Metadata is not uint cast)
return;
OnKeySelected?.Invoke(cast);
@@ -82,8 +83,7 @@ public sealed partial class CriminalRecordsConsoleWindow : FancyWindow
RecordListing.OnItemDeselected += _ =>
{
if (!_isPopulating)
OnKeySelected?.Invoke(null);
OnKeySelected?.Invoke(null);
};
FilterType.OnItemSelected += eventArgs =>
@@ -133,13 +133,8 @@ public sealed partial class CriminalRecordsConsoleWindow : FancyWindow
FilterType.SelectId((int)_currentFilterType);
// set up the records listing panel
RecordListing.Clear();
var hasRecords = state.RecordListing != null && state.RecordListing.Count > 0;
NoRecords.Visible = !hasRecords;
if (hasRecords)
PopulateRecordListing(state.RecordListing!);
NoRecords.Visible = state.RecordListing == null || state.RecordListing.Count == 0;
PopulateRecordListing(state.RecordListing);
// set up the selected person's record
var selected = _selectedKey != null;
@@ -167,19 +162,59 @@ public sealed partial class CriminalRecordsConsoleWindow : FancyWindow
}
}
private void PopulateRecordListing(Dictionary<uint, string> listing)
private void PopulateRecordListing(Dictionary<uint, string>? listing)
{
_isPopulating = true;
foreach (var (key, name) in listing)
if (listing == null)
{
var item = RecordListing.AddItem(name);
item.Metadata = key;
item.Selected = key == _selectedKey;
RecordListing.Clear();
return;
}
_isPopulating = false;
RecordListing.SortItemsByText();
var entries = listing.ToList();
entries.Sort((a, b) => string.Compare(a.Value, b.Value, StringComparison.Ordinal));
// `entries` now contains the definitive list of items which should be in
// our list of records and is in the order we want to present those items.
// Walk through the existing items in RecordListing and in the updated listing
// in parallel to synchronize the items in RecordListing with `entries`.
int i = RecordListing.Count - 1;
int j = entries.Count - 1;
while(i >= 0 && j >= 0)
{
var strcmp = string.Compare(RecordListing[i].Text, entries[j].Value, StringComparison.Ordinal);
if (strcmp == 0)
{
// This item exists in both RecordListing and `entries`. Nothing to do.
i--;
j--;
}
else if (strcmp > 0)
{
// Item exists in RecordListing, but not in `entries`. Remove it.
RecordListing.RemoveAt(i);
i--;
}
else if (strcmp < 0)
{
// A new entry which doesn't exist in RecordListing. Create it.
RecordListing.Insert(i + 1, new ItemList.Item(RecordListing){Text = entries[j].Value, Metadata = entries[j].Key});
j--;
}
}
// Any remaining items in RecordListing don't exist in `entries`, so remove them
while (i >= 0)
{
RecordListing.RemoveAt(i);
i--;
}
// And finally, any remaining items in `entries`, don't exist in RecordListing. Create them.
while (j >= 0)
{
RecordListing.Insert(0, new ItemList.Item(RecordListing){Text = entries[j].Value, Metadata = entries[j].Key});
j--;
}
}
private void PopulateRecordContainer(GeneralStationRecord stationRecord, CriminalRecord criminalRecord)
@@ -211,10 +246,7 @@ public sealed partial class CriminalRecordsConsoleWindow : FancyWindow
private void FilterListingOfRecords(string text = "")
{
if (!_isPopulating)
{
OnFiltersChanged?.Invoke(_currentFilterType, text);
}
OnFiltersChanged?.Invoke(_currentFilterType, text);
}
private void SetStatus(SecurityStatus status)