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:
parent
947c61d2d7
commit
e91f310279
18 changed files with 864 additions and 348 deletions
78
src/AcDream.App/Update/UpdateFrameRuntimeAdapters.cs
Normal file
78
src/AcDream.App/Update/UpdateFrameRuntimeAdapters.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
using AcDream.App.Input;
|
||||
using AcDream.App.World;
|
||||
using AcDream.Core.Vfx;
|
||||
|
||||
namespace AcDream.App.Update;
|
||||
|
||||
/// <summary>Bridges canonical live-entity teardown into the host frame.</summary>
|
||||
internal sealed class LiveEntityTeardownFramePhase : IUpdateFrameTeardownPhase
|
||||
{
|
||||
private readonly LiveEntityRuntime _runtime;
|
||||
|
||||
public LiveEntityTeardownFramePhase(LiveEntityRuntime runtime) =>
|
||||
_runtime = runtime ?? throw new ArgumentNullException(nameof(runtime));
|
||||
|
||||
public void RetryPendingTeardowns() => _runtime.RetryPendingTeardowns();
|
||||
}
|
||||
|
||||
internal sealed class ConsoleUpdateFrameFailureSink : IUpdateFrameFailureSink
|
||||
{
|
||||
public void ReportTeardownFailure(AggregateException error) =>
|
||||
Console.Error.WriteLine($"[live-entity-teardown] {error}");
|
||||
}
|
||||
|
||||
/// <summary>Publishes the frame clock to the retail PhysicsScript owner.</summary>
|
||||
internal sealed class PhysicsScriptClockPublisher : IUpdateFrameScriptClockPublisher
|
||||
{
|
||||
private readonly PhysicsScriptRunner _runner;
|
||||
|
||||
public PhysicsScriptClockPublisher(PhysicsScriptRunner runner) =>
|
||||
_runner = runner ?? throw new ArgumentNullException(nameof(runner));
|
||||
|
||||
public void PublishTime(double scriptTime) => _runner.PublishTime(scriptTime);
|
||||
}
|
||||
|
||||
internal interface IClientMonotonicTimeSource
|
||||
{
|
||||
double Now { get; }
|
||||
}
|
||||
|
||||
internal sealed class StopwatchClientMonotonicTimeSource
|
||||
: IClientMonotonicTimeSource
|
||||
{
|
||||
public double Now =>
|
||||
System.Diagnostics.Stopwatch.GetTimestamp()
|
||||
/ (double)System.Diagnostics.Stopwatch.Frequency;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supplies the absolute client timer to liveness independently of the
|
||||
/// normalized simulation delta.
|
||||
/// </summary>
|
||||
internal sealed class LiveEntityLivenessFramePhase
|
||||
: ILiveEntityLivenessFramePhase
|
||||
{
|
||||
private readonly LiveEntityLivenessController _liveness;
|
||||
private readonly IClientMonotonicTimeSource _clock;
|
||||
|
||||
public LiveEntityLivenessFramePhase(
|
||||
LiveEntityLivenessController liveness,
|
||||
IClientMonotonicTimeSource clock)
|
||||
{
|
||||
_liveness = liveness ?? throw new ArgumentNullException(nameof(liveness));
|
||||
_clock = clock ?? throw new ArgumentNullException(nameof(clock));
|
||||
}
|
||||
|
||||
public void Tick() => _liveness.Tick(_clock.Now);
|
||||
}
|
||||
|
||||
internal sealed class PlayerModeAutoEntryFramePhase
|
||||
: IPlayerModeAutoEntryFramePhase
|
||||
{
|
||||
private readonly PlayerModeAutoEntry _autoEntry;
|
||||
|
||||
public PlayerModeAutoEntryFramePhase(PlayerModeAutoEntry autoEntry) =>
|
||||
_autoEntry = autoEntry ?? throw new ArgumentNullException(nameof(autoEntry));
|
||||
|
||||
public void TryEnter() => _autoEntry.TryEnter();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue