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
|
|
@ -79,6 +79,13 @@ public sealed class LandblockPresentationPipeline
|
|||
_state = state;
|
||||
_onLandblockLoaded = onLandblockLoaded;
|
||||
_ensureEnvCellMeshes = ensureEnvCellMeshes;
|
||||
if (retirementCoordinator is not null
|
||||
&& !retirementCoordinator.MatchesState(_state))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"The retirement coordinator must own the pipeline's world state.",
|
||||
nameof(retirementCoordinator));
|
||||
}
|
||||
_retirements = retirementCoordinator
|
||||
?? LandblockRetirementCoordinator.CreateLegacy(
|
||||
state,
|
||||
|
|
@ -96,9 +103,9 @@ public sealed class LandblockPresentationPipeline
|
|||
LandblockPhysicsPublisher physicsPublisher,
|
||||
LandblockStaticPresentationPublisher staticPublisher,
|
||||
GpuWorldState state,
|
||||
LandblockPresentationRetirementOwner retirementOwner,
|
||||
Action<uint>? onLandblockLoaded = null,
|
||||
Action<EnvCellLandblockBuild>? ensureEnvCellMeshes = null,
|
||||
LandblockRetirementCoordinator? retirementCoordinator = null)
|
||||
Action<EnvCellLandblockBuild>? ensureEnvCellMeshes = null)
|
||||
{
|
||||
_renderPublisher = renderPublisher
|
||||
?? throw new ArgumentNullException(nameof(renderPublisher));
|
||||
|
|
@ -107,19 +114,35 @@ public sealed class LandblockPresentationPipeline
|
|||
_staticPublisher = staticPublisher
|
||||
?? throw new ArgumentNullException(nameof(staticPublisher));
|
||||
_state = state ?? throw new ArgumentNullException(nameof(state));
|
||||
if (!_renderPublisher.MatchesState(_state))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"The render publisher must own the pipeline's world state.",
|
||||
nameof(state));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(retirementOwner);
|
||||
if (!retirementOwner.Matches(
|
||||
_renderPublisher,
|
||||
_physicsPublisher,
|
||||
_staticPublisher))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"The retirement owner must reference the pipeline's concrete publishers.",
|
||||
nameof(retirementOwner));
|
||||
}
|
||||
_onLandblockLoaded = onLandblockLoaded;
|
||||
_ensureEnvCellMeshes = ensureEnvCellMeshes;
|
||||
// Until Slice 5F internalizes concrete retirement ownership, a
|
||||
// concrete publication pipeline must share the production coordinator.
|
||||
// A legacy no-op retirement suffix would detach spatial state while
|
||||
// leaking the concrete render/physics/static owners.
|
||||
_retirements = retirementCoordinator
|
||||
?? throw new ArgumentNullException(nameof(retirementCoordinator));
|
||||
_retirements = new LandblockRetirementCoordinator(
|
||||
state,
|
||||
retirementOwner.Advance);
|
||||
}
|
||||
|
||||
public int PendingRetirementCount => _retirements.PendingCount;
|
||||
public int PendingPublicationCount => _publications.Count;
|
||||
|
||||
internal bool MatchesState(GpuWorldState state) =>
|
||||
ReferenceEquals(_state, state);
|
||||
|
||||
public bool IsRetirementPending(uint landblockId) =>
|
||||
_retirements.IsPending(landblockId);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue