refactor(net): cut GameWindow over to session owner

This commit is contained in:
Erik 2026-07-21 12:37:22 +02:00
parent 783ef1d6db
commit 6a5d9e2e6a
5 changed files with 363 additions and 268 deletions

View file

@ -0,0 +1,65 @@
using AcDream.Core.Net;
namespace AcDream.App.Net;
internal sealed record LiveSessionLifecycleBindings(
Func<WorldSession, LiveSessionBinding> Bind,
Action Reset,
Action<string, int, string> Connecting,
Action Connected,
Action<LiveSessionCharacterSelection> Selected,
Action<LiveSessionCharacterSelection> Entered);
/// <summary>
/// Focused adapter between the session lifetime owner and App composition.
/// It tracks only the exact borrowed session attached to the host; domain and
/// presentation state remain behind the supplied lifecycle callbacks.
/// </summary>
internal sealed class LiveSessionLifecycleHost : ILiveSessionLifecycleHost
{
private readonly LiveSessionLifecycleBindings _bindings;
private WorldSession? _boundSession;
public LiveSessionLifecycleHost(LiveSessionLifecycleBindings bindings)
{
_bindings = bindings ?? throw new ArgumentNullException(nameof(bindings));
ArgumentNullException.ThrowIfNull(bindings.Bind);
ArgumentNullException.ThrowIfNull(bindings.Reset);
ArgumentNullException.ThrowIfNull(bindings.Connecting);
ArgumentNullException.ThrowIfNull(bindings.Connected);
ArgumentNullException.ThrowIfNull(bindings.Selected);
ArgumentNullException.ThrowIfNull(bindings.Entered);
}
public LiveSessionBinding BindSession(WorldSession session)
{
ArgumentNullException.ThrowIfNull(session);
if (_boundSession is not null)
throw new InvalidOperationException("A live session is already attached to this host.");
LiveSessionBinding binding = _bindings.Bind(session);
_boundSession = session;
return binding;
}
public void ResetSessionState() => _bindings.Reset();
public void ReportConnecting(string host, int port, string user) =>
_bindings.Connecting(host, port, user);
public void ReportConnected() => _bindings.Connected();
public void ApplySelectedCharacter(LiveSessionCharacterSelection selection) =>
_bindings.Selected(selection);
public void ApplyEnteredWorld(LiveSessionCharacterSelection selection) =>
_bindings.Entered(selection);
public void DetachSession(WorldSession session)
{
if (!ReferenceEquals(_boundSession, session))
throw new InvalidOperationException(
"The live-session controller attempted to detach a session that is not bound.");
_boundSession = null;
}
}