refactor(streaming): centralize world reveal lifetime

Compose destination readiness and lifecycle telemetry behind one App-layer coordinator so login and portal begin, preparation, materialization, visibility, completion, and cancellation cannot drift apart in GameWindow wiring.
This commit is contained in:
Erik 2026-07-20 23:33:50 +02:00
parent 68578fa5fa
commit a4ef57885c
4 changed files with 213 additions and 30 deletions

View file

@ -0,0 +1,69 @@
namespace AcDream.App.Streaming;
/// <summary>
/// Owns one login/portal reveal lifetime across readiness and lifecycle
/// diagnostics. This keeps the destination barrier and its observations on a
/// single seam so callers cannot begin, prepare, or evaluate one owner while
/// forgetting the other.
/// </summary>
internal sealed class WorldRevealCoordinator
{
private readonly WorldRevealReadinessBarrier _readiness;
private readonly WorldRevealLifecycleTelemetry _lifecycle;
public WorldRevealCoordinator(
Func<uint, int, bool> isRenderNeighborhoodReady,
Func<uint, bool> isSpawnCellReady,
Func<uint, int, bool> isTerrainNeighborhoodReady,
Func<bool> areCompositeTexturesReady,
Action<uint, int> prepareCompositeTextures,
Action invalidateCompositeTextures,
Func<uint, bool> isSpawnClaimUnhydratable,
Action<string>? log = null)
{
_readiness = new WorldRevealReadinessBarrier(
isRenderNeighborhoodReady,
isSpawnCellReady,
isTerrainNeighborhoodReady,
areCompositeTexturesReady,
prepareCompositeTextures,
invalidateCompositeTextures,
isSpawnClaimUnhydratable);
_lifecycle = new WorldRevealLifecycleTelemetry(log);
}
public WorldRevealLifecycleSnapshot Snapshot => _lifecycle.Snapshot;
public int PortalMaterializationCount => _lifecycle.PortalMaterializationCount;
public long Begin(WorldRevealKind kind)
{
_readiness.Begin();
return _lifecycle.Begin(kind);
}
/// <summary>
/// Advances render-thread preparation and publishes the resulting
/// canonical readiness snapshot to lifecycle diagnostics.
/// </summary>
public WorldRevealReadinessSnapshot PrepareAndEvaluate(uint destinationCell)
{
_readiness.Prepare(destinationCell);
return Evaluate(destinationCell);
}
public WorldRevealReadinessSnapshot Evaluate(uint destinationCell)
{
WorldRevealReadinessSnapshot snapshot = _readiness.Evaluate(destinationCell);
_lifecycle.ObserveReadiness(snapshot);
return snapshot;
}
public void ObserveMaterialized() => _lifecycle.ObserveMaterialized();
public void ObserveWorldViewportVisible() =>
_lifecycle.ObserveWorldViewportVisible();
public void Complete() => _lifecycle.Complete();
public void Cancel() => _lifecycle.Cancel();
}