refactor(net): converge live session state reset

This commit is contained in:
Erik 2026-07-21 12:00:48 +02:00
parent 78a9223b65
commit 4f31a5085f
35 changed files with 1460 additions and 83 deletions

View file

@ -26,6 +26,7 @@ public sealed class RetailDialogFactory : IDisposable
private readonly Dictionary<uint, LinkedList<DialogInfo>> _pending = new();
private readonly List<DialogInfo> _openOrder = new();
private uint _globalContext;
private bool _resetting;
private bool _disposed;
public RetailDialogFactory(
@ -192,18 +193,46 @@ public sealed class RetailDialogFactory : IDisposable
/// </summary>
public void Reset()
{
DialogInfo[] infos = _activeNonQueued.Values
.Concat(_activeQueued.Values)
.Concat(_pending.Values.SelectMany(static queue => queue))
.Distinct()
.ToArray();
if (_resetting)
return;
_activeNonQueued.Clear();
_activeQueued.Clear();
_pending.Clear();
foreach (DialogInfo info in infos)
DialogDone(info);
RefreshModal();
_resetting = true;
List<Exception>? failures = null;
try
{
while (true)
{
DialogInfo[] infos = _activeNonQueued.Values
.Concat(_activeQueued.Values)
.Concat(_pending.Values.SelectMany(static queue => queue))
.Distinct()
.ToArray();
if (infos.Length == 0)
break;
// Callbacks may synchronously create another dialog. Retire
// this exact snapshot, then loop until those reentrant infos
// have also completed through DialogDone.
_activeNonQueued.Clear();
_activeQueued.Clear();
_pending.Clear();
foreach (DialogInfo info in infos)
{
try { DialogDone(info); }
catch (Exception error) { (failures ??= []).Add(error); }
}
}
}
finally
{
_resetting = false;
RefreshModal();
}
if (failures is not null)
throw new AggregateException(
"One or more dialogs failed while the factory reset.",
failures);
}
public void Dispose()
@ -283,10 +312,10 @@ public sealed class RetailDialogFactory : IDisposable
{
if (info.View is { } view)
{
info.View = null;
view.DetachHandlers();
_openOrder.Remove(info);
_host.RemoveChild(view.Root);
info.View = null;
_openOrder.Remove(info);
}
RefreshModal();
}