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

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Numerics;
using AcDream.App.Rendering;
using Silk.NET.Input;
@ -48,6 +49,8 @@ public sealed class UiHost : System.IDisposable
public IKeyboard? Keyboard { get; private set; }
private long _startTicks = System.Environment.TickCount64;
private readonly List<System.Action> _inputUnsubscribers = new();
private bool _disposed;
public UiHost(GL gl, string shaderDir, BitmapFont? defaultFont = null)
{
@ -78,22 +81,48 @@ public sealed class UiHost : System.IDisposable
public void WireMouse(IMouse mouse)
{
mouse.MouseDown += (_, b) =>
Root.OnMouseDown(MapButton(b), (int)mouse.Position.X, (int)mouse.Position.Y);
mouse.MouseUp += (_, b) =>
Root.OnMouseUp(MapButton(b), (int)mouse.Position.X, (int)mouse.Position.Y);
mouse.MouseMove += (_, p) =>
Root.OnMouseMove((int)p.X, (int)p.Y);
mouse.Scroll += (_, s) =>
Root.OnScroll((int)s.Y);
System.ObjectDisposedException.ThrowIf(_disposed, this);
System.ArgumentNullException.ThrowIfNull(mouse);
void OnMouseDown(IMouse sender, MouseButton button) =>
Root.OnMouseDown(MapButton(button), (int)sender.Position.X, (int)sender.Position.Y);
void OnMouseUp(IMouse sender, MouseButton button) =>
Root.OnMouseUp(MapButton(button), (int)sender.Position.X, (int)sender.Position.Y);
void OnMouseMove(IMouse sender, Vector2 position) =>
Root.OnMouseMove((int)position.X, (int)position.Y);
void OnScroll(IMouse sender, ScrollWheel scroll) => Root.OnScroll((int)scroll.Y);
mouse.MouseDown += OnMouseDown;
mouse.MouseUp += OnMouseUp;
mouse.MouseMove += OnMouseMove;
mouse.Scroll += OnScroll;
_inputUnsubscribers.Add(() =>
{
mouse.MouseDown -= OnMouseDown;
mouse.MouseUp -= OnMouseUp;
mouse.MouseMove -= OnMouseMove;
mouse.Scroll -= OnScroll;
});
}
public void WireKeyboard(IKeyboard kb)
{
System.ObjectDisposedException.ThrowIf(_disposed, this);
System.ArgumentNullException.ThrowIfNull(kb);
Keyboard = kb; // last wired keyboard wins (one-keyboard desktop)
kb.KeyDown += (_, k, _) => Root.OnKeyDown((int)k);
kb.KeyUp += (_, k, _) => Root.OnKeyUp((int)k);
kb.KeyChar += (_, c) => Root.OnChar(c);
void OnKeyDown(IKeyboard sender, Key key, int scanCode) => Root.OnKeyDown((int)key);
void OnKeyUp(IKeyboard sender, Key key, int scanCode) => Root.OnKeyUp((int)key);
void OnKeyChar(IKeyboard sender, char value) => Root.OnChar(value);
kb.KeyDown += OnKeyDown;
kb.KeyUp += OnKeyUp;
kb.KeyChar += OnKeyChar;
_inputUnsubscribers.Add(() =>
{
kb.KeyDown -= OnKeyDown;
kb.KeyUp -= OnKeyUp;
kb.KeyChar -= OnKeyChar;
});
}
private static UiMouseButton MapButton(MouseButton b) => b switch
@ -133,6 +162,12 @@ public sealed class UiHost : System.IDisposable
public void Dispose()
{
if (_disposed) return;
_disposed = true;
for (int i = _inputUnsubscribers.Count - 1; i >= 0; i--)
_inputUnsubscribers[i]();
_inputUnsubscribers.Clear();
Keyboard = null;
WindowManager.Dispose();
TextRenderer.Dispose();
}