refactor(ui): own retained controller lifetimes

This commit is contained in:
Erik 2026-07-10 23:35:26 +02:00
parent 921c388e2c
commit 5d9e98c118
21 changed files with 373 additions and 35 deletions

View file

@ -0,0 +1,52 @@
using System;
namespace AcDream.App.UI;
/// <summary>
/// Gives one retained window a single lifecycle owner when its imported subtree
/// is bound by multiple focused controllers (for example toolbar+selection or
/// inventory+paperdoll). Teardown runs in reverse construction order and is
/// idempotent.
/// </summary>
public sealed class RetainedPanelControllerGroup : IRetainedPanelController
{
private readonly IRetainedPanelController[] _controllers;
private bool _disposed;
public RetainedPanelControllerGroup(params IRetainedPanelController[] controllers)
{
ArgumentNullException.ThrowIfNull(controllers);
_controllers = (IRetainedPanelController[])controllers.Clone();
for (int i = 0; i < _controllers.Length; i++)
ArgumentNullException.ThrowIfNull(_controllers[i]);
}
public void OnShown()
{
if (_disposed) return;
for (int i = 0; i < _controllers.Length; i++)
_controllers[i].OnShown();
}
public void OnHidden()
{
if (_disposed) return;
for (int i = _controllers.Length - 1; i >= 0; i--)
_controllers[i].OnHidden();
}
public void OnDescendantFocusChanged(UiElement? focusedDescendant)
{
if (_disposed) return;
for (int i = 0; i < _controllers.Length; i++)
_controllers[i].OnDescendantFocusChanged(focusedDescendant);
}
public void Dispose()
{
if (_disposed) return;
_disposed = true;
for (int i = _controllers.Length - 1; i >= 0; i--)
_controllers[i].Dispose();
}
}