using System.Globalization;
namespace AcDream.App.Streaming;
internal enum WorldRevealKind
{
Login,
Portal,
}
internal readonly record struct WorldRevealLifecycleSnapshot(
long Generation,
WorldRevealKind Kind,
WorldRevealReadinessSnapshot Readiness,
bool Materialized,
bool Completed,
bool Cancelled,
bool WorldViewportObserved,
int InvariantFailureCount)
{
public bool IsActive => Generation != 0 && !Cancelled;
public bool IsReady => Readiness.IsReady;
}
///
/// Observes logical login/portal reveal generations without owning rendering or
/// changing gameplay state. The owner turns the canonical readiness decision
/// into deterministic lifecycle markers for connected automation and records a
/// hard diagnostic failure if normal world geometry becomes visible early.
///
internal sealed class WorldRevealLifecycleTelemetry
{
private readonly Action _log;
private WorldRevealLifecycleSnapshot _snapshot;
private long _nextGeneration;
private int _portalMaterializationCount;
public WorldRevealLifecycleTelemetry(Action? log = null)
{
_log = log ?? (_ => { });
}
public WorldRevealLifecycleSnapshot Snapshot => _snapshot;
public int PortalMaterializationCount => _portalMaterializationCount;
public long Begin(WorldRevealKind kind)
{
if (_snapshot.Generation != 0
&& !_snapshot.Cancelled
&& !_snapshot.WorldViewportObserved)
{
Log("superseded", _snapshot);
}
long generation = checked(++_nextGeneration);
_snapshot = new WorldRevealLifecycleSnapshot(
generation,
kind,
default,
Materialized: false,
Completed: false,
Cancelled: false,
WorldViewportObserved: false,
InvariantFailureCount: _snapshot.InvariantFailureCount);
Log("begin", _snapshot);
return generation;
}
public void ObserveReadiness(WorldRevealReadinessSnapshot readiness)
{
if (_snapshot.Generation == 0 || _snapshot.Cancelled)
return;
if (_snapshot.Readiness == readiness)
return;
if (_snapshot.Readiness.DestinationCell != 0u
&& readiness.DestinationCell != 0u
&& _snapshot.Readiness.DestinationCell != readiness.DestinationCell)
{
FailInvariant(
"destination-changed",
$"from=0x{_snapshot.Readiness.DestinationCell:X8} to=0x{readiness.DestinationCell:X8}");
}
_snapshot = _snapshot with { Readiness = readiness };
Log("readiness", _snapshot);
}
public void ObserveMaterialized()
{
if (_snapshot.Generation == 0 || _snapshot.Cancelled || _snapshot.Materialized)
return;
_snapshot = _snapshot with { Materialized = true };
if (_snapshot.Kind == WorldRevealKind.Portal)
_portalMaterializationCount++;
Log("materialized", _snapshot);
}
public void ObserveWorldViewportVisible()
{
if (_snapshot.Generation == 0 || _snapshot.Cancelled || _snapshot.WorldViewportObserved)
return;
if (!_snapshot.Readiness.IsReady)
FailInvariant("viewport-before-ready", null);
_snapshot = _snapshot with { WorldViewportObserved = true };
Log("world-visible", _snapshot);
}
public void Complete()
{
if (_snapshot.Generation == 0 || _snapshot.Cancelled || _snapshot.Completed)
return;
_snapshot = _snapshot with { Completed = true };
Log("complete", _snapshot);
}
public void Cancel()
{
if (_snapshot.Generation == 0 || _snapshot.Cancelled)
return;
_snapshot = _snapshot with { Cancelled = true };
Log("cancel", _snapshot);
}
private void FailInvariant(string reason, string? detail)
{
_snapshot = _snapshot with
{
InvariantFailureCount = checked(_snapshot.InvariantFailureCount + 1),
};
string suffix = string.IsNullOrWhiteSpace(detail) ? string.Empty : $" {detail}";
_log($"[world-reveal] event=invariant-failure reason={reason}{suffix} {Describe(_snapshot)}");
}
private void Log(string eventName, WorldRevealLifecycleSnapshot snapshot) =>
_log($"[world-reveal] event={eventName} {Describe(snapshot)}");
private static string Describe(WorldRevealLifecycleSnapshot snapshot)
{
WorldRevealReadinessSnapshot ready = snapshot.Readiness;
return string.Create(
CultureInfo.InvariantCulture,
$"generation={snapshot.Generation} kind={snapshot.Kind} " +
$"cell=0x{ready.DestinationCell:X8} indoor={ready.IsIndoor} " +
$"radius={ready.RequiredRenderRadius} unhydratable={ready.IsUnhydratable} " +
$"render={ready.IsRenderNeighborhoodReady} composites={ready.AreCompositeTexturesReady} " +
$"collision={ready.IsCollisionReady} ready={ready.IsReady} " +
$"materialized={snapshot.Materialized} completed={snapshot.Completed} " +
$"cancelled={snapshot.Cancelled} visible={snapshot.WorldViewportObserved} " +
$"failures={snapshot.InvariantFailureCount}");
}
}