refactor(app): compose world rendering startup

Move Region/environment, mandatory modern rendering, terrain, WB, texture, and sampler construction behind the typed Phase-4 composition boundary. Give every fallible GL constructor prefix retryable ownership so partial startup failure cannot leak or replay resource deletion while preserving the accepted render path and DAT inputs.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-22 16:46:05 +02:00
parent cd7b519f78
commit 6a2fe98cc4
22 changed files with 1983 additions and 634 deletions

View file

@ -1,5 +1,7 @@
namespace AcDream.App.Rendering;
using System.Runtime.ExceptionServices;
/// <summary>
/// Reverse-order, all-attempted cleanup owner used while a composite resource
/// is still under construction and after it becomes the aggregate owner.
@ -25,6 +27,15 @@ internal sealed class ResourceCleanupGroup : IRetryableResourceCleanup
_entries.Add(new Entry(name, release));
}
public void TransferAll()
{
if (_running)
throw new InvalidOperationException(
"The resource cleanup group is currently releasing resources.");
foreach (Entry entry in _entries)
entry.Complete = true;
}
public void RetryCleanup()
{
if (_running || IsCleanupComplete)
@ -60,4 +71,26 @@ internal sealed class ResourceCleanupGroup : IRetryableResourceCleanup
if (failures is not null)
throw new AggregateException("Composite resource cleanup remains incomplete.", failures);
}
public void RollbackConstructionAndThrow(
string message,
Exception constructionFailure)
{
ArgumentException.ThrowIfNullOrWhiteSpace(message);
ArgumentNullException.ThrowIfNull(constructionFailure);
try
{
RetryCleanup();
}
catch (Exception cleanupFailure)
{
throw new GlResourceConstructionException(
message,
this,
[constructionFailure, cleanupFailure]);
}
ExceptionDispatchInfo.Capture(constructionFailure).Throw();
throw new InvalidOperationException("Unreachable construction rollback path.");
}
}