using AcDream.Runtime.Entities;
namespace AcDream.Runtime.Physics;
///
/// Public host boundary for Runtime-owned SetPosition projection receipts.
/// The channel owns no placement state: observation, retry, and exact-token
/// acknowledgement delegate to the canonical entity lifetime's event stream
/// and SetPosition owner.
///
public sealed class RuntimePlacementProjectionChannel
{
private readonly RuntimeEntityObjectEventStream _events;
private readonly RuntimeSetPositionState _setPosition;
private readonly RuntimeInitialCreateContinuationExecutor _initialCreateExecution;
private Func _generation = static () => default;
private bool _generationBound;
internal RuntimePlacementProjectionChannel(
RuntimeEntityObjectEventStream events,
RuntimeSetPositionState setPosition,
RuntimeInitialCreateContinuationExecutor initialCreateExecution)
{
_events = events ?? throw new ArgumentNullException(nameof(events));
_setPosition = setPosition
?? throw new ArgumentNullException(nameof(setPosition));
_initialCreateExecution = initialCreateExecution
?? throw new ArgumentNullException(nameof(initialCreateExecution));
}
///
/// Observes ordered immutable projection receipts on the Runtime commit
/// thread. A host must acknowledge only after its projection succeeds.
///
public IDisposable Subscribe(IRuntimePlacementObserver observer) =>
_events.SubscribePlacement(observer);
internal void BindGeneration(Func generation)
{
ArgumentNullException.ThrowIfNull(generation);
if (_generationBound)
{
throw new InvalidOperationException(
"The Runtime placement generation source is already bound.");
}
_generation = generation;
_generationBound = true;
}
///
/// Acknowledges only the exact oldest outstanding receipt. Stale,
/// reordered, superseded, or already acknowledged tokens are rejected.
///
public bool Acknowledge(
RuntimeGenerationToken expectedGeneration,
in RuntimePlacementProjectionToken token) =>
IsCurrent(expectedGeneration)
&& _setPosition.AcknowledgeProjection(token);
///
/// Republishes every still-pending immutable receipt in canonical order.
/// Runtime authority is never replayed or recommitted by a retry.
///
public bool RetryPending(RuntimeGenerationToken expectedGeneration)
{
if (!IsCurrent(expectedGeneration))
return false;
_setPosition.RetryPendingProjections();
return true;
}
///
/// Returns the exact oldest outstanding receipt without consuming it.
///
public bool TryPeek(
RuntimeGenerationToken expectedGeneration,
out RuntimePlacementProjectionSnapshot projection)
{
if (IsCurrent(expectedGeneration))
return _setPosition.TryPeekProjection(out projection);
projection = default;
return false;
}
public int PendingCount => _setPosition.PendingProjectionCount;
///
/// C3-1: the public host consumption shape for an initial-Create
/// continuation-executor drain's completion. Reached with the exact
/// carried by a
/// receipt
/// observed through - the same correlation
/// identity (Entity/Sequence) every other placement Kind uses. Exposes
/// exactly the facts a cutover host needs to bind presentation off an
/// initial placement (the teleport-hook phase, the drained Position
/// continuations' route facts for constrain/interpolation binding, and
/// the replayed-deferred-child count) without widening any internal
/// Runtime type's accessibility. Returns false for a generation
/// mismatch or a stale/superseded/unknown token, mirroring every other
/// generation-gated method on this channel.
///
public bool TryGetInitialCreateCompletion(
RuntimeGenerationToken expectedGeneration,
in RuntimePlacementProjectionToken token,
out RuntimeInitialCreatePlacementCompletion completion)
{
if (IsCurrent(expectedGeneration))
return _initialCreateExecution.TryGetCompletion(token, out completion);
completion = default;
return false;
}
private bool IsCurrent(RuntimeGenerationToken expectedGeneration) =>
_generationBound
&& expectedGeneration.Value != 0UL
&& expectedGeneration == _generation();
}