refactor(render): compose render frame orchestrator
Move the accepted draw transaction and failure recovery behind typed frame-phase owners so GameWindow only supplies immutable frame input. Preserve retail draw order, make ImGui/bootstrap shutdown ownership explicit, and restore exact text-render GL state on failures.\n\nCo-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
28e1cf8029
commit
9d7df1bfc5
25 changed files with 1675 additions and 279 deletions
|
|
@ -25,10 +25,19 @@ internal enum DevToolsPanelKind
|
|||
Settings,
|
||||
}
|
||||
|
||||
internal interface IDevToolsFrameLifecycle : IRenderFrameFailureRecovery
|
||||
{
|
||||
void BeginFrame(float deltaSeconds);
|
||||
|
||||
void Render(double deltaSeconds, int viewportWidth, int viewportHeight);
|
||||
}
|
||||
|
||||
internal interface IDevToolsFrameBackend
|
||||
{
|
||||
void BeginFrame(float deltaSeconds);
|
||||
|
||||
void AbortFrame();
|
||||
|
||||
bool BeginMainMenuBar();
|
||||
|
||||
void EndMainMenuBar();
|
||||
|
|
@ -82,10 +91,11 @@ internal interface IDevToolsPanelSet
|
|||
}
|
||||
|
||||
/// <summary>Concrete ImGui backend for the developer presentation owner.</summary>
|
||||
internal sealed class ImGuiDevToolsFrameBackend : IDevToolsFrameBackend
|
||||
internal sealed class ImGuiDevToolsFrameBackend : IDevToolsFrameBackend, IDisposable
|
||||
{
|
||||
private readonly ImGuiBootstrapper _bootstrap;
|
||||
private readonly ImGuiPanelHost _panels;
|
||||
private bool _disposed;
|
||||
|
||||
public ImGuiDevToolsFrameBackend(
|
||||
ImGuiBootstrapper bootstrap,
|
||||
|
|
@ -97,6 +107,8 @@ internal sealed class ImGuiDevToolsFrameBackend : IDevToolsFrameBackend
|
|||
|
||||
public void BeginFrame(float deltaSeconds) => _bootstrap.BeginFrame(deltaSeconds);
|
||||
|
||||
public void AbortFrame() => _bootstrap.AbortFrame();
|
||||
|
||||
public bool BeginMainMenuBar() => ImGuiNET.ImGui.BeginMainMenuBar();
|
||||
|
||||
public void EndMainMenuBar() => ImGuiNET.ImGui.EndMainMenuBar();
|
||||
|
|
@ -130,6 +142,15 @@ internal sealed class ImGuiDevToolsFrameBackend : IDevToolsFrameBackend
|
|||
ImGuiNET.ImGui.SetWindowSize(title, size, imguiCondition);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
_bootstrap.Dispose();
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Mutable late-composition seam for player-mode menu operations.</summary>
|
||||
|
|
@ -229,13 +250,14 @@ internal sealed class DevToolsPanelSet : IDevToolsPanelSet
|
|||
/// reusable default layout. Retained gameplay UI remains a separate earlier
|
||||
/// presentation phase.
|
||||
/// </summary>
|
||||
internal sealed class DevToolsFramePresenter
|
||||
internal sealed class DevToolsFramePresenter : IDevToolsFrameLifecycle
|
||||
{
|
||||
private readonly IDevToolsFrameBackend _backend;
|
||||
private readonly IDevToolsCameraMenuOperations _camera;
|
||||
private readonly IDevToolsCommandBusSource _commands;
|
||||
private readonly IDevToolsPanelSet _panels;
|
||||
private readonly AcDream.App.Diagnostics.FrameProfiler _profiler;
|
||||
private bool _frameOpen;
|
||||
|
||||
public DevToolsFramePresenter(
|
||||
IDevToolsFrameBackend backend,
|
||||
|
|
@ -251,15 +273,47 @@ internal sealed class DevToolsFramePresenter
|
|||
_panels = panels ?? throw new ArgumentNullException(nameof(panels));
|
||||
}
|
||||
|
||||
public void BeginFrame(float deltaSeconds) => _backend.BeginFrame(deltaSeconds);
|
||||
public void BeginFrame(float deltaSeconds)
|
||||
{
|
||||
if (_frameOpen)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"The previous developer-tools frame must render or abort before a new frame begins.");
|
||||
}
|
||||
|
||||
_frameOpen = true;
|
||||
_backend.BeginFrame(deltaSeconds);
|
||||
}
|
||||
|
||||
public void Render(double deltaSeconds, int viewportWidth, int viewportHeight)
|
||||
{
|
||||
if (!_frameOpen)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"BeginFrame must open the developer-tools frame before Render.");
|
||||
}
|
||||
|
||||
var context = new PanelContext((float)deltaSeconds, _commands.Current);
|
||||
DrawMenu(viewportWidth, viewportHeight);
|
||||
_backend.RenderPanels(context);
|
||||
using var stage = _profiler.BeginStage(AcDream.App.Diagnostics.FrameStage.ImGui);
|
||||
_backend.RenderDrawData();
|
||||
_frameOpen = false;
|
||||
}
|
||||
|
||||
public void AbortFrame()
|
||||
{
|
||||
if (!_frameOpen)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
_backend.AbortFrame();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_frameOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleDebugPanel()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue