refactor(render): extract world scene frame owner
Move fallback and PView world drawing, shared alpha, particles, visibility, selection, and diagnostics behind focused frame owners. Make exceptional frames failure-atomic by restoring the shared GL baseline and preserving primary alpha failures through cleanup. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
85239fb373
commit
28e1cf8029
25 changed files with 2679 additions and 844 deletions
|
|
@ -179,6 +179,76 @@ public sealed class RetailAlphaQueueTests
|
|||
log);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AbortFrame_DiscardsPayloadAndAllowsTheNextFrameToRender()
|
||||
{
|
||||
var log = new List<string>();
|
||||
var source = new RecordingSource("alpha", log);
|
||||
var queue = new RetailAlphaQueue();
|
||||
|
||||
queue.BeginFrame();
|
||||
queue.Submit(source, 1, 12f);
|
||||
queue.AbortFrame();
|
||||
|
||||
Assert.False(queue.IsCollecting);
|
||||
Assert.Equal(0, queue.PendingCount);
|
||||
Assert.Empty(log);
|
||||
Assert.Equal(1, source.ResetCount);
|
||||
|
||||
queue.BeginFrame();
|
||||
queue.Submit(source, 2, 12f);
|
||||
queue.EndFrame();
|
||||
|
||||
Assert.Equal(["alpha:2"], log);
|
||||
Assert.Equal(2, source.ResetCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EndFrame_DrawAndResetFailuresPreserveThePrimaryFailureAndClearTheFrame()
|
||||
{
|
||||
var drawSource = new FailureSource("draw failed", "first reset failed");
|
||||
var secondSource = new FailureSource(null, null);
|
||||
var queue = new RetailAlphaQueue();
|
||||
|
||||
queue.BeginFrame();
|
||||
queue.Submit(drawSource, 1, 20f);
|
||||
queue.Submit(secondSource, 2, 10f);
|
||||
|
||||
AggregateException failure = Assert.Throws<AggregateException>(queue.EndFrame);
|
||||
|
||||
Assert.Collection(
|
||||
failure.InnerExceptions,
|
||||
error => Assert.Equal("draw failed", error.Message),
|
||||
error => Assert.Equal("first reset failed", error.Message));
|
||||
Assert.Equal(1, drawSource.ResetCount);
|
||||
Assert.Equal(1, secondSource.ResetCount);
|
||||
Assert.Equal(0, queue.PendingCount);
|
||||
Assert.False(queue.IsCollecting);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EndFrame_MultipleResetFailuresAttemptEverySourceAndClearTheFrame()
|
||||
{
|
||||
var first = new FailureSource(null, "first reset failed");
|
||||
var second = new FailureSource(null, "second reset failed");
|
||||
var queue = new RetailAlphaQueue();
|
||||
|
||||
queue.BeginFrame();
|
||||
queue.Submit(first, 1, 20f);
|
||||
queue.Submit(second, 2, 10f);
|
||||
|
||||
AggregateException failure = Assert.Throws<AggregateException>(queue.EndFrame);
|
||||
|
||||
Assert.Collection(
|
||||
failure.InnerExceptions,
|
||||
error => Assert.Equal("first reset failed", error.Message),
|
||||
error => Assert.Equal("second reset failed", error.Message));
|
||||
Assert.Equal(1, first.ResetCount);
|
||||
Assert.Equal(1, second.ResetCount);
|
||||
Assert.Equal(0, queue.PendingCount);
|
||||
Assert.False(queue.IsCollecting);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ComputeViewerDistance_UsesTransformedGfxSortCenter()
|
||||
{
|
||||
|
|
@ -224,4 +294,28 @@ public sealed class RetailAlphaQueueTests
|
|||
|
||||
public void ResetAlphaSubmissions() => ResetCount++;
|
||||
}
|
||||
|
||||
private sealed class FailureSource(
|
||||
string? drawFailure,
|
||||
string? resetFailure) : IRetailAlphaDrawSource
|
||||
{
|
||||
public int ResetCount { get; private set; }
|
||||
|
||||
public void PrepareAlphaDraws(ReadOnlySpan<int> tokens)
|
||||
{
|
||||
}
|
||||
|
||||
public void DrawPreparedAlphaBatch(int firstPreparedDraw, int drawCount)
|
||||
{
|
||||
if (drawFailure is not null)
|
||||
throw new InvalidOperationException(drawFailure);
|
||||
}
|
||||
|
||||
public void ResetAlphaSubmissions()
|
||||
{
|
||||
ResetCount++;
|
||||
if (resetFailure is not null)
|
||||
throw new InvalidOperationException(resetFailure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue