namespace AcDream.App.Rendering; internal interface IRenderWeatherFramePhase { void Tick(double deltaSeconds); } /// /// Optional per-frame developer-presentation hook. Its one production /// implementation (the ImGui developer-tools frontend) was removed at /// Campaign V slice V11; the interface survives as the seam a follow-up /// re-homing Settings/Debug onto the retained UI will implement, and every /// current caller already treats it as optional (null-conditional). /// internal interface IDevToolsFrameLifecycle : IRenderFrameFailureRecovery { void BeginFrame(float deltaSeconds); void Render(double deltaSeconds, int viewportWidth, int viewportHeight); } /// /// Preserves the accepted pre-world order after the GPU/resource transaction: /// begin optional developer UI, advance render-time weather, then hand the /// completed preparation to the world phase. /// internal sealed class RenderFramePreparationController : IRenderFrameResourcePhase { private readonly IRenderFrameResourcePhase _resources; private readonly IDevToolsFrameLifecycle? _devTools; private readonly IRenderWeatherFramePhase _weather; private readonly IPrivateEntityViewportResourcePreparation? _privateViewports; public RenderFramePreparationController( IRenderFrameResourcePhase resources, IDevToolsFrameLifecycle? devTools, IRenderWeatherFramePhase weather, IPrivateEntityViewportResourcePreparation? privateViewports = null) { _resources = resources ?? throw new ArgumentNullException(nameof(resources)); _devTools = devTools; _weather = weather ?? throw new ArgumentNullException(nameof(weather)); _privateViewports = privateViewports; } public void Prepare(RenderFrameInput input) { _resources.Prepare(input); // The composite upload budget opens with the resource phase. Give the // paperdoll's private object its prewarm slot before the world can // consume the complete per-frame budget (#443 — the doll rendered // only while portal space quiesced the world); presentation samples // the result later, after the world pass has closed. _privateViewports?.PrepareResources(); _devTools?.BeginFrame((float)input.DeltaSeconds); _weather.Tick(input.DeltaSeconds); } }