refactor(update): cut over the frame orchestrator

Reduce GameWindow.OnUpdate to one typed orchestration call and remove transitive window callbacks from teardown, liveness, teleport placement, live presentation, auto-entry, and entity packet routing. Preserve the frozen retail object/network order while making the production owner graph explicit and testable.
This commit is contained in:
Erik 2026-07-22 03:31:38 +02:00
parent 947c61d2d7
commit e91f310279
18 changed files with 864 additions and 348 deletions

View file

@ -1,3 +1,4 @@
using AcDream.App.Input;
using AcDream.App.Rendering;
using AcDream.App.Rendering.Vfx;
using AcDream.App.Streaming;
@ -113,7 +114,17 @@ internal sealed class LiveEntityWorldOriginCoordinator : ILiveEntityWorldOriginC
private readonly StreamingController _streaming;
private readonly GpuWorldState _worldState;
private readonly WorldRevealCoordinator _worldReveal;
private readonly Func<uint> _playerGuid;
private sealed class DelegateIdentitySource : ILocalPlayerIdentitySource
{
private readonly Func<uint> _read;
public DelegateIdentitySource(Func<uint> read) =>
_read = read ?? throw new ArgumentNullException(nameof(read));
public uint ServerGuid => _read();
}
private readonly ILocalPlayerIdentitySource _identity;
private readonly ISealedDungeonCellClassifier _sealedDungeonCells;
private readonly Action<string>? _diagnostic;
@ -122,7 +133,7 @@ internal sealed class LiveEntityWorldOriginCoordinator : ILiveEntityWorldOriginC
StreamingController streaming,
GpuWorldState worldState,
WorldRevealCoordinator worldReveal,
Func<uint> playerGuid,
ILocalPlayerIdentitySource identity,
ISealedDungeonCellClassifier sealedDungeonCells,
Action<string>? diagnostic = null)
{
@ -130,18 +141,37 @@ internal sealed class LiveEntityWorldOriginCoordinator : ILiveEntityWorldOriginC
_streaming = streaming ?? throw new ArgumentNullException(nameof(streaming));
_worldState = worldState ?? throw new ArgumentNullException(nameof(worldState));
_worldReveal = worldReveal ?? throw new ArgumentNullException(nameof(worldReveal));
_playerGuid = playerGuid ?? throw new ArgumentNullException(nameof(playerGuid));
_identity = identity ?? throw new ArgumentNullException(nameof(identity));
_sealedDungeonCells = sealedDungeonCells
?? throw new ArgumentNullException(nameof(sealedDungeonCells));
_diagnostic = diagnostic;
}
internal LiveEntityWorldOriginCoordinator(
LiveWorldOriginState origin,
StreamingController streaming,
GpuWorldState worldState,
WorldRevealCoordinator worldReveal,
Func<uint> playerGuid,
ISealedDungeonCellClassifier sealedDungeonCells,
Action<string>? diagnostic = null)
: this(
origin,
streaming,
worldState,
worldReveal,
new DelegateIdentitySource(playerGuid),
sealedDungeonCells,
diagnostic)
{
}
public bool IsKnown => _origin.IsKnown;
public LiveEntityOriginInitialization TryInitialize(
WorldSession.EntitySpawn spawn)
{
if (spawn.Guid != _playerGuid()
if (spawn.Guid != _identity.ServerGuid
|| spawn.Position is not { } position)
{
return new(_origin.IsKnown, Array.Empty<uint>());