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}"); } }