refactor(app): extract focused window lifetime
Move the exact retryable shutdown manifest, typed root snapshot, terminal reporting, and native-window-last release out of GameWindow. Keep session and GPU convergence as hard barriers while reporting persistent physical callback cleanup without stranding dependent owners. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
5a55d08106
commit
31e6e192b3
21 changed files with 1297 additions and 572 deletions
|
|
@ -1,6 +1,21 @@
|
|||
namespace AcDream.App.Rendering;
|
||||
|
||||
internal readonly record struct ResourceShutdownOperation(string Name, Action Execute);
|
||||
internal enum ResourceShutdownOperationPolicy
|
||||
{
|
||||
HardBarrier,
|
||||
ReportAndContinue,
|
||||
}
|
||||
|
||||
internal readonly record struct ResourceShutdownOperation(
|
||||
string Name,
|
||||
Action Execute,
|
||||
ResourceShutdownOperationPolicy Policy =
|
||||
ResourceShutdownOperationPolicy.HardBarrier);
|
||||
|
||||
internal sealed record ResourceShutdownCleanupFailure(
|
||||
string Stage,
|
||||
string Operation,
|
||||
Exception Error);
|
||||
|
||||
internal sealed record ResourceShutdownStage(
|
||||
string Name,
|
||||
|
|
@ -16,6 +31,7 @@ internal sealed class ResourceShutdownTransaction(params ResourceShutdownStage[]
|
|||
private sealed class StageState(int operationCount)
|
||||
{
|
||||
public bool[] Complete { get; } = new bool[operationCount];
|
||||
public int[] Attempts { get; } = new int[operationCount];
|
||||
}
|
||||
|
||||
private const int MaximumConsecutiveStalledPasses = 2;
|
||||
|
|
@ -23,11 +39,15 @@ internal sealed class ResourceShutdownTransaction(params ResourceShutdownStage[]
|
|||
stages ?? throw new ArgumentNullException(nameof(stages));
|
||||
private readonly StageState[] _states =
|
||||
stages.Select(stage => new StageState(stage.Operations.Length)).ToArray();
|
||||
private readonly List<ResourceShutdownCleanupFailure> _cleanupFailures = [];
|
||||
private int _currentStage;
|
||||
private bool _completing;
|
||||
|
||||
public bool IsComplete => _currentStage == _stages.Length;
|
||||
internal int CurrentStage => _currentStage;
|
||||
internal string? CurrentStageName => IsComplete ? null : _stages[_currentStage].Name;
|
||||
internal IReadOnlyList<ResourceShutdownCleanupFailure> CleanupFailures =>
|
||||
_cleanupFailures.ToArray();
|
||||
|
||||
public void CompleteOrThrow()
|
||||
{
|
||||
|
|
@ -87,9 +107,25 @@ internal sealed class ResourceShutdownTransaction(params ResourceShutdownStage[]
|
|||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
(failures ??= []).Add(new InvalidOperationException(
|
||||
var wrapped = new InvalidOperationException(
|
||||
$"Shutdown operation '{operation.Name}' failed in stage '{stage.Name}'.",
|
||||
error));
|
||||
error);
|
||||
state.Attempts[i]++;
|
||||
if (operation.Policy ==
|
||||
ResourceShutdownOperationPolicy.ReportAndContinue
|
||||
&& state.Attempts[i] >= MaximumConsecutiveStalledPasses)
|
||||
{
|
||||
state.Complete[i] = true;
|
||||
progressed = true;
|
||||
_cleanupFailures.Add(new ResourceShutdownCleanupFailure(
|
||||
stage.Name,
|
||||
operation.Name,
|
||||
error));
|
||||
}
|
||||
else
|
||||
{
|
||||
(failures ??= []).Add(wrapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue