refactor(lifetime): own render resource prefixes
Give terrain, sky, retained UI, portal preparation, and the update/render frame pair explicit single owners. Make shader, texture, text, bindless, and GL construction prefixes checked and retryable so partial failure cannot lose or replay resource ownership. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
fec0d94148
commit
c87b15303d
41 changed files with 3768 additions and 355 deletions
67
src/AcDream.App/Rendering/GameFrameGraphSlot.cs
Normal file
67
src/AcDream.App/Rendering/GameFrameGraphSlot.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
using AcDream.App.Update;
|
||||
|
||||
namespace AcDream.App.Rendering;
|
||||
|
||||
internal interface IGameUpdateFrameRoot
|
||||
{
|
||||
void Tick(UpdateFrameInput input);
|
||||
}
|
||||
|
||||
internal interface IGameRenderFrameRoot
|
||||
{
|
||||
RenderFrameOutcome Render(RenderFrameInput input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sole atomic publication point for the current update/render frame pair.
|
||||
/// Native callbacks are deliberately inert before publication and after
|
||||
/// withdrawal so a partial load or converging shutdown cannot enter half a
|
||||
/// frame graph.
|
||||
/// </summary>
|
||||
internal sealed class GameFrameGraphSlot
|
||||
{
|
||||
private sealed record FrameGraphPair(
|
||||
IGameUpdateFrameRoot Update,
|
||||
IGameRenderFrameRoot Render);
|
||||
|
||||
private FrameGraphPair? _pair;
|
||||
|
||||
public bool IsPublished => Volatile.Read(ref _pair) is not null;
|
||||
|
||||
public void Publish(IGameUpdateFrameRoot update, IGameRenderFrameRoot render)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(update);
|
||||
ArgumentNullException.ThrowIfNull(render);
|
||||
var pair = new FrameGraphPair(update, render);
|
||||
if (Interlocked.CompareExchange(ref _pair, pair, null) is not null)
|
||||
throw new InvalidOperationException("A game frame graph is already published.");
|
||||
}
|
||||
|
||||
public bool Tick(UpdateFrameInput input)
|
||||
{
|
||||
FrameGraphPair? pair = Volatile.Read(ref _pair);
|
||||
if (pair is null)
|
||||
return false;
|
||||
|
||||
pair.Update.Tick(input);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Render(RenderFrameInput input, out RenderFrameOutcome outcome)
|
||||
{
|
||||
FrameGraphPair? pair = Volatile.Read(ref _pair);
|
||||
if (pair is null)
|
||||
{
|
||||
outcome = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
outcome = pair.Render.Render(input);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Withdraw()
|
||||
{
|
||||
Interlocked.Exchange(ref _pair, null);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue