refactor(streaming): own presentation retirement in pipeline
Move full and near-tier presentation retirement out of GameWindow and into a concrete pipeline-owned stage mapper. Harden the retry ledger against reentrancy and committed visibility observer failures, enforce a single state/resource ownership graph, and split concrete versus legacy controller construction so callbacks cannot be silently ignored. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
dc39772bf9
commit
ea7ffbc186
10 changed files with 860 additions and 140 deletions
|
|
@ -115,6 +115,7 @@ public sealed class StreamingController
|
|||
// deferred-LOAD backlog. A non-zero value during/after a teleport is the
|
||||
// GPU-upload tail draining at MaxCompletionsPerFrame. Removable probe surface.
|
||||
public int DeferredApplyBacklog => _deferredApply.Count;
|
||||
public int PendingRetirementCount => _presentation.PendingRetirementCount;
|
||||
|
||||
/// <summary>
|
||||
/// True once every in-bounds landblock in the requested Chebyshev ring has
|
||||
|
|
@ -174,8 +175,40 @@ public sealed class StreamingController
|
|||
Action? clearPendingLoads = null,
|
||||
Action<uint>? onLandblockLoaded = null,
|
||||
Action<EnvCellLandblockBuild>? ensureEnvCellMeshes = null,
|
||||
LandblockRetirementCoordinator? retirementCoordinator = null,
|
||||
LandblockPresentationPipeline? presentationPipeline = null)
|
||||
LandblockRetirementCoordinator? retirementCoordinator = null)
|
||||
: this(
|
||||
enqueueLoad,
|
||||
enqueueUnload,
|
||||
drainCompletions,
|
||||
state,
|
||||
nearRadius,
|
||||
farRadius,
|
||||
new LandblockPresentationPipeline(
|
||||
applyTerrain,
|
||||
state,
|
||||
onLandblockLoaded,
|
||||
ensureEnvCellMeshes,
|
||||
retirementCoordinator,
|
||||
removeTerrain,
|
||||
demoteNearLayer),
|
||||
clearPendingLoads)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Concrete presentation path. Its pipeline is the sole presentation and
|
||||
/// retirement owner, so no legacy publication delegate can be supplied or
|
||||
/// silently ignored.
|
||||
/// </summary>
|
||||
public StreamingController(
|
||||
Action<uint, LandblockStreamJobKind, ulong> enqueueLoad,
|
||||
Action<uint, ulong> enqueueUnload,
|
||||
Func<int, IReadOnlyList<LandblockStreamResult>> drainCompletions,
|
||||
GpuWorldState state,
|
||||
int nearRadius,
|
||||
int farRadius,
|
||||
LandblockPresentationPipeline presentationPipeline,
|
||||
Action? clearPendingLoads = null)
|
||||
{
|
||||
_enqueueLoad = enqueueLoad;
|
||||
_enqueueUnload = enqueueUnload;
|
||||
|
|
@ -183,14 +216,13 @@ public sealed class StreamingController
|
|||
_clearPendingLoads = clearPendingLoads;
|
||||
_state = state;
|
||||
_presentation = presentationPipeline
|
||||
?? new LandblockPresentationPipeline(
|
||||
applyTerrain,
|
||||
state,
|
||||
onLandblockLoaded,
|
||||
ensureEnvCellMeshes,
|
||||
retirementCoordinator,
|
||||
removeTerrain,
|
||||
demoteNearLayer);
|
||||
?? throw new ArgumentNullException(nameof(presentationPipeline));
|
||||
if (!_presentation.MatchesState(_state))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"The presentation pipeline must own the controller's world state.",
|
||||
nameof(presentationPipeline));
|
||||
}
|
||||
NearRadius = nearRadius;
|
||||
FarRadius = farRadius;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue