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

@ -2158,6 +2158,7 @@ public sealed class GameWindow : IDisposable
ResizeY = false,
ConstrainDragToParent = true,
ContentClickThrough = false,
Controller = _radarController,
});
Console.WriteLine("[D.6] retail radar/compass from LayoutDesc 0x21000074.");
}
@ -2219,6 +2220,7 @@ public sealed class GameWindow : IDisposable
ResizeX = true,
ResizeY = true,
Opacity = 0.75f,
Controller = chatController,
StateController = chatController,
});
chatController.AttachWindow(chatHandle);
@ -2346,7 +2348,9 @@ public sealed class GameWindow : IDisposable
_selectedObjectController = AcDream.App.UI.Layout.SelectedObjectController.Bind(
toolbarLayout,
subscribeSelectionChanged: h => SelectionChanged += h,
unsubscribeSelectionChanged: h => SelectionChanged -= h,
subscribeHealthChanged: h => Combat.HealthChanged += h,
unsubscribeHealthChanged: h => Combat.HealthChanged -= h,
isHealthTarget: IsHealthBarTarget,
name: g => Objects.Get(g)?.Name,
healthPercent: g => Combat.GetHealthPercent(g),
@ -2380,6 +2384,9 @@ public sealed class GameWindow : IDisposable
| AcDream.App.UI.AnchorEdges.Top
| AcDream.App.UI.AnchorEdges.Right,
ContentClickThrough = true,
Controller = new AcDream.App.UI.RetainedPanelControllerGroup(
_toolbarController,
_selectedObjectController),
});
var toolbarFrame = (AcDream.App.UI.UiCollapsibleFrame)toolbarHandle.OuterFrame;
@ -2578,6 +2585,12 @@ public sealed class GameWindow : IDisposable
datFont: vitalsDatFont,
itemInteraction: _itemInteractionController); // Slice 2: caption the "Slots" toggle button
_uiHost.WindowManager.AttachController(
AcDream.App.UI.WindowNames.Inventory,
new AcDream.App.UI.RetainedPanelControllerGroup(
_inventoryController,
_paperdollController));
// Slice 2: capture the doll viewport widget (Type 0xD, element 0x100001D5) + the inventory
// frame so the per-frame pre-UI hook can render the 3-D doll into the widget's texture only
// when the window is open and in doll-view. The renderer itself is built after the
@ -14024,6 +14037,14 @@ public sealed class GameWindow : IDisposable
private void OnClosing()
{
// Retained controllers subscribe to session-owned object/selection/combat sources.
// Tear their window-manager ownership down first, while every source and GL-backed
// UI resource is still alive. UiHost disposes controllers before its renderer.
_windowLayoutPersistence?.Dispose();
_windowLayoutPersistence = null;
_uiHost?.Dispose();
_uiHost = null;
// Phase A.1: join the streamer worker thread before tearing down GL
// state. The worker may still be processing a load job that references
// _dats; Dispose cancels the token and waits up to 2s for the thread.
@ -14051,9 +14072,6 @@ public sealed class GameWindow : IDisposable
_paperdollViewportRenderer?.Dispose(); // Slice 2: the doll's off-screen FBO + textures
_particleRenderer?.Dispose();
_debugLines?.Dispose();
_windowLayoutPersistence?.Dispose();
_windowLayoutPersistence = null;
_uiHost?.Dispose();
_textRenderer?.Dispose();
_debugFont?.Dispose();
_frameProfiler.Dispose(); // MP0: releases the GpuFrameTimer query ring