init 2
This commit is contained in:
228
LightlessSync/UI/Services/PairUiService.cs
Normal file
228
LightlessSync/UI/Services/PairUiService.cs
Normal file
@@ -0,0 +1,228 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using LightlessSync.API.Dto.Group;
|
||||
using LightlessSync.PlayerData.Factories;
|
||||
using LightlessSync.PlayerData.Pairs;
|
||||
using LightlessSync.Services.Mediator;
|
||||
using LightlessSync.UI.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace LightlessSync.UI.Services;
|
||||
|
||||
public sealed class PairUiService : DisposableMediatorSubscriberBase
|
||||
{
|
||||
private readonly PairLedger _pairLedger;
|
||||
private readonly PairFactory _pairFactory;
|
||||
private readonly PairManager _pairManager;
|
||||
|
||||
private readonly object _snapshotGate = new();
|
||||
private PairUiSnapshot _snapshot = PairUiSnapshot.Empty;
|
||||
private Pair? _lastAddedPair;
|
||||
private bool _needsRefresh = true;
|
||||
|
||||
public PairUiService(
|
||||
ILogger<PairUiService> logger,
|
||||
LightlessMediator mediator,
|
||||
PairLedger pairLedger,
|
||||
PairFactory pairFactory,
|
||||
PairManager pairManager) : base(logger, mediator)
|
||||
{
|
||||
_pairLedger = pairLedger;
|
||||
_pairFactory = pairFactory;
|
||||
_pairManager = pairManager;
|
||||
|
||||
Mediator.Subscribe<PairDataChangedMessage>(this, _ => MarkDirty());
|
||||
Mediator.Subscribe<GroupCollectionChangedMessage>(this, _ => MarkDirty());
|
||||
Mediator.Subscribe<VisibilityChange>(this, _ => MarkDirty());
|
||||
|
||||
EnsureSnapshot();
|
||||
}
|
||||
|
||||
public PairUiSnapshot GetSnapshot()
|
||||
{
|
||||
EnsureSnapshot();
|
||||
lock (_snapshotGate)
|
||||
{
|
||||
return _snapshot;
|
||||
}
|
||||
}
|
||||
|
||||
public Pair? GetLastAddedPair()
|
||||
{
|
||||
EnsureSnapshot();
|
||||
lock (_snapshotGate)
|
||||
{
|
||||
return _lastAddedPair;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearLastAddedPair()
|
||||
{
|
||||
_pairManager.ClearLastAddedUser();
|
||||
lock (_snapshotGate)
|
||||
{
|
||||
_lastAddedPair = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void MarkDirty()
|
||||
{
|
||||
lock (_snapshotGate)
|
||||
{
|
||||
_needsRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureSnapshot()
|
||||
{
|
||||
bool shouldBuild;
|
||||
lock (_snapshotGate)
|
||||
{
|
||||
shouldBuild = _needsRefresh;
|
||||
if (shouldBuild)
|
||||
{
|
||||
_needsRefresh = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!shouldBuild)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PairUiSnapshot snapshot;
|
||||
Pair? lastAddedPair;
|
||||
try
|
||||
{
|
||||
(snapshot, lastAddedPair) = BuildSnapshot();
|
||||
}
|
||||
catch
|
||||
{
|
||||
lock (_snapshotGate)
|
||||
{
|
||||
_needsRefresh = true;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
lock (_snapshotGate)
|
||||
{
|
||||
_snapshot = snapshot;
|
||||
_lastAddedPair = lastAddedPair;
|
||||
}
|
||||
|
||||
Mediator.Publish(new PairUiUpdatedMessage(snapshot));
|
||||
}
|
||||
|
||||
private (PairUiSnapshot Snapshot, Pair? LastAddedPair) BuildSnapshot()
|
||||
{
|
||||
var entries = _pairLedger.GetAllEntries();
|
||||
var pairByUid = new Dictionary<string, Pair>(StringComparer.Ordinal);
|
||||
|
||||
var directPairsList = new List<Pair>();
|
||||
var groupPairsTemp = new Dictionary<GroupFullInfoDto, List<Pair>>();
|
||||
var pairsWithGroupsTemp = new Dictionary<Pair, List<GroupFullInfoDto>>();
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
var pair = _pairFactory.Create(entry);
|
||||
if (pair is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
pairByUid[entry.Ident.UserId] = pair;
|
||||
|
||||
if (entry.IsDirectlyPaired)
|
||||
{
|
||||
directPairsList.Add(pair);
|
||||
}
|
||||
|
||||
var uniqueGroups = new HashSet<string>(StringComparer.Ordinal);
|
||||
var groupList = new List<GroupFullInfoDto>();
|
||||
foreach (var group in entry.Groups)
|
||||
{
|
||||
if (!uniqueGroups.Add(group.Group.GID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!groupPairsTemp.TryGetValue(group, out var members))
|
||||
{
|
||||
members = new List<Pair>();
|
||||
groupPairsTemp[group] = members;
|
||||
}
|
||||
|
||||
members.Add(pair);
|
||||
groupList.Add(group);
|
||||
}
|
||||
|
||||
pairsWithGroupsTemp[pair] = groupList;
|
||||
}
|
||||
|
||||
var allGroupsList = _pairLedger.GetAllSyncshells()
|
||||
.Values
|
||||
.Select(s => s.GroupFullInfo)
|
||||
.ToList();
|
||||
|
||||
foreach (var group in allGroupsList)
|
||||
{
|
||||
if (!groupPairsTemp.ContainsKey(group))
|
||||
{
|
||||
groupPairsTemp[group] = new List<Pair>();
|
||||
}
|
||||
}
|
||||
|
||||
var directPairs = new ReadOnlyCollection<Pair>(directPairsList);
|
||||
|
||||
var groupPairsFinal = new Dictionary<GroupFullInfoDto, IReadOnlyList<Pair>>();
|
||||
foreach (var (group, members) in groupPairsTemp)
|
||||
{
|
||||
groupPairsFinal[group] = new ReadOnlyCollection<Pair>(members);
|
||||
}
|
||||
|
||||
var pairsWithGroupsFinal = new Dictionary<Pair, IReadOnlyList<GroupFullInfoDto>>();
|
||||
foreach (var (pair, groups) in pairsWithGroupsTemp)
|
||||
{
|
||||
pairsWithGroupsFinal[pair] = new ReadOnlyCollection<GroupFullInfoDto>(groups);
|
||||
}
|
||||
|
||||
var groupsReadOnly = new ReadOnlyCollection<GroupFullInfoDto>(allGroupsList);
|
||||
var pairsByUidReadOnly = new ReadOnlyDictionary<string, Pair>(pairByUid);
|
||||
var groupsByGidReadOnly = new ReadOnlyDictionary<string, GroupFullInfoDto>(allGroupsList.ToDictionary(g => g.Group.GID, g => g, StringComparer.Ordinal));
|
||||
|
||||
Pair? lastAddedPair = null;
|
||||
var lastAdded = _pairManager.GetLastAddedUser();
|
||||
if (lastAdded is not null)
|
||||
{
|
||||
if (!pairByUid.TryGetValue(lastAdded.User.UID, out lastAddedPair))
|
||||
{
|
||||
var groups = lastAdded.Groups.Keys
|
||||
.Select(gid =>
|
||||
{
|
||||
var result = _pairManager.GetGroup(gid);
|
||||
return result.Success ? result.Value.GroupFullInfo : null;
|
||||
})
|
||||
.Where(g => g is not null)
|
||||
.Cast<GroupFullInfoDto>()
|
||||
.ToList();
|
||||
|
||||
var entry = new PairDisplayEntry(new PairUniqueIdentifier(lastAdded.User.UID), lastAdded, groups, null);
|
||||
lastAddedPair = _pairFactory.Create(entry);
|
||||
}
|
||||
}
|
||||
|
||||
var snapshot = new PairUiSnapshot(
|
||||
pairsByUidReadOnly,
|
||||
directPairs,
|
||||
new ReadOnlyDictionary<GroupFullInfoDto, IReadOnlyList<Pair>>(groupPairsFinal),
|
||||
new ReadOnlyDictionary<Pair, IReadOnlyList<GroupFullInfoDto>>(pairsWithGroupsFinal),
|
||||
groupsByGidReadOnly,
|
||||
groupsReadOnly);
|
||||
|
||||
return (snapshot, lastAddedPair);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user