Make character UI retries transactional

This commit is contained in:
Erik 2026-08-14 21:14:08 +02:00
parent aeac874dab
commit 1dd5706e15
6 changed files with 352 additions and 42 deletions

View file

@ -116,6 +116,36 @@ internal sealed class CharacterManagementUiController : IDisposable
RetailDialogFactory dialogs,
CharacterSelectionRuntimeBindings bindings,
DialogStrings strings)
{
CharacterManagementUiController? controller = CreateDetached(
host,
layout,
templateResolver,
dialogs,
bindings,
strings);
if (controller is null)
return null;
try
{
controller.AttachAndTick();
return controller;
}
catch
{
controller.Dispose();
throw;
}
}
internal static CharacterManagementUiController? CreateDetached(
UiRoot host,
ImportedLayout layout,
Func<uint, uint, UiElement?> templateResolver,
RetailDialogFactory dialogs,
CharacterSelectionRuntimeBindings bindings,
DialogStrings strings)
{
ArgumentNullException.ThrowIfNull(host);
ArgumentNullException.ThrowIfNull(layout);
@ -144,20 +174,37 @@ internal sealed class CharacterManagementUiController : IDisposable
}
list.TemplateResolver = templateResolver;
var controller = new CharacterManagementUiController(
host,
layout,
list,
create,
enter,
delete,
restore,
dialogs,
bindings,
strings);
host.AddChild(controller.Root);
controller.Tick();
return controller;
try
{
return new CharacterManagementUiController(
host,
layout,
list,
create,
enter,
delete,
restore,
dialogs,
bindings,
strings);
}
catch
{
list.TemplateResolver = null;
create.OnClick = null;
enter.OnClick = null;
delete.OnClick = null;
restore.OnClick = null;
throw;
}
}
internal void AttachAndTick()
{
ObjectDisposedException.ThrowIf(_disposed, this);
if (Root.Parent is null)
_host.AddChild(Root);
Tick();
}
private static bool ContainsViewport(UiElement element)
@ -247,20 +294,26 @@ internal sealed class CharacterManagementUiController : IDisposable
if (_disposed)
return;
_disposed = true;
CloseAllDialogs(suppressCallbacks: true);
_enter.OnClick = null;
_delete.OnClick = null;
_restore.OnClick = null;
foreach (UiButton row in _rows)
try
{
row.OnClick = null;
row.OnDoubleClick = null;
CloseAllDialogs(suppressCallbacks: true);
}
finally
{
_enter.OnClick = null;
_delete.OnClick = null;
_restore.OnClick = null;
foreach (UiButton row in _rows)
{
row.OnClick = null;
row.OnDoubleClick = null;
}
_rows.Clear();
_rowIds.Clear();
_list.Flush();
_list.TemplateResolver = null;
_host.RemoveChild(Root);
}
_rows.Clear();
_rowIds.Clear();
_list.Flush();
_list.TemplateResolver = null;
_host.RemoveChild(Root);
}
private static bool TryCaptureRoster(