refactor(runtime): own world environment state

This commit is contained in:
Erik 2026-07-26 16:45:04 +02:00
parent b972f539f7
commit 902076c0a4
27 changed files with 886 additions and 295 deletions

View file

@ -372,7 +372,9 @@ public sealed class WorldTimeService
{
private SkyStateProvider _sky;
private double _lastSyncedTicks;
private DateTime _lastSyncedWallClockUtc = DateTime.UtcNow;
private DateTimeOffset _lastSyncedWallClockUtc;
private readonly TimeProvider _timeProvider;
private readonly Action<string>? _synchronizationDiagnostic;
private float? _debugDayFractionOverride;
@ -384,10 +386,25 @@ public sealed class WorldTimeService
public double TickSize { get; set; } = 1.0;
public WorldTimeService(SkyStateProvider sky)
: this(sky, new DerethCalendar(), TimeProvider.System)
{
}
public WorldTimeService(
SkyStateProvider sky,
DerethCalendar calendar,
TimeProvider? timeProvider = null,
Action<string>? synchronizationDiagnostic = null)
{
_sky = sky ?? throw new ArgumentNullException(nameof(sky));
Calendar = calendar ?? throw new ArgumentNullException(nameof(calendar));
_timeProvider = timeProvider ?? TimeProvider.System;
_synchronizationDiagnostic = synchronizationDiagnostic;
_lastSyncedWallClockUtc = _timeProvider.GetUtcNow();
}
public DerethCalendar Calendar { get; }
/// <summary>
/// Hot-swap the keyframe source — typically called once at world-load
/// time after the Region dat has been parsed by <see cref="SkyDescLoader"/>.
@ -404,14 +421,14 @@ public sealed class WorldTimeService
public void SyncFromServer(double serverTicks)
{
_lastSyncedTicks = serverTicks;
_lastSyncedWallClockUtc = System.DateTime.UtcNow;
_lastSyncedWallClockUtc = _timeProvider.GetUtcNow();
_debugDayFractionOverride = null;
if (System.Environment.GetEnvironmentVariable("ACDREAM_DUMP_SKY") == "1")
if (_synchronizationDiagnostic is not null)
{
var df = DerethDateTime.DayFraction(serverTicks);
var cal = DerethDateTime.ToCalendar(serverTicks);
System.Console.WriteLine(
var df = Calendar.DayFraction(serverTicks);
var cal = Calendar.ToCalendar(serverTicks);
_synchronizationDiagnostic(
$"[sky-dump] SyncFromServer: ticks={serverTicks:F1} dayFraction={df:F4} " +
$"calendar=PY{cal.Year} {cal.Month} {cal.Day} {cal.Hour}");
}
@ -430,14 +447,17 @@ public sealed class WorldTimeService
public void ClearDebugTime() => _debugDayFractionOverride = null;
/// <summary>
/// Current ticks at <see cref="DateTime.UtcNow"/>, advanced from the
/// last sync by real-time elapsed seconds times <see cref="TickSize"/>.
/// Current ticks at the injected <see cref="TimeProvider"/>'s UTC time,
/// advanced from the last sync by real-time elapsed seconds times
/// <see cref="TickSize"/>.
/// </summary>
public double NowTicks
{
get
{
double elapsed = (DateTime.UtcNow - _lastSyncedWallClockUtc).TotalSeconds;
double elapsed =
(_timeProvider.GetUtcNow() - _lastSyncedWallClockUtc)
.TotalSeconds;
return _lastSyncedTicks + elapsed * TickSize;
}
}
@ -449,7 +469,7 @@ public sealed class WorldTimeService
{
if (_debugDayFractionOverride.HasValue)
return _debugDayFractionOverride.Value;
return DerethDateTime.DayFraction(NowTicks);
return Calendar.DayFraction(NowTicks);
}
}
@ -461,7 +481,7 @@ public sealed class WorldTimeService
SkyStateProvider.SunDirectionFromKeyframe(CurrentSky);
public DerethDateTime.Calendar CurrentCalendar =>
DerethDateTime.ToCalendar(NowTicks);
Calendar.ToCalendar(NowTicks);
public bool IsDaytime => DerethDateTime.IsDaytime(NowTicks);
public bool IsDaytime => Calendar.IsDaytime(NowTicks);
}