feat(runtime): own initial create residence transaction
This commit is contained in:
parent
74103f75b5
commit
38fd4b8dc9
10 changed files with 3031 additions and 17 deletions
|
|
@ -250,6 +250,8 @@ internal readonly record struct RuntimeSetPositionOwnershipSnapshot(
|
|||
int UnboundDeferredCellOrderCount,
|
||||
int PreparedMoverCount,
|
||||
int MoverPreparationAuthorityCount,
|
||||
int PlacementCompletionWatchCount,
|
||||
int AcknowledgedPlacementCompletionCount,
|
||||
int CollisionPrefixQuiescenceCount,
|
||||
int PendingQuiescenceProjectionCount)
|
||||
{
|
||||
|
|
@ -276,6 +278,8 @@ internal readonly record struct RuntimeSetPositionOwnershipSnapshot(
|
|||
&& UnboundDeferredCellOrderCount == 0
|
||||
&& PreparedMoverCount == 0
|
||||
&& MoverPreparationAuthorityCount == 0
|
||||
&& PlacementCompletionWatchCount == 0
|
||||
&& AcknowledgedPlacementCompletionCount == 0
|
||||
&& CollisionPrefixQuiescenceCount == 0
|
||||
&& PendingQuiescenceProjectionCount == 0;
|
||||
}
|
||||
|
|
@ -414,6 +418,10 @@ internal sealed class RuntimeSetPositionState : IDisposable
|
|||
_preparedMovers = [];
|
||||
private readonly Dictionary<RuntimeEntityKey, MoverPreparationAuthority>
|
||||
_moverPreparationAuthorities = [];
|
||||
private readonly HashSet<RuntimeEntityPlacementToken>
|
||||
_placementCompletionWatches = [];
|
||||
private readonly Dictionary<RuntimeEntityPlacementToken,
|
||||
RuntimePlacementProjectionToken> _acknowledgedPlacementCompletions = [];
|
||||
private readonly Dictionary<uint, CollisionPrefixQuiescence>
|
||||
_collisionPrefixQuiescence = [];
|
||||
private readonly LinkedList<RuntimeEntityKey> _expiredLostCells = [];
|
||||
|
|
@ -477,11 +485,15 @@ internal sealed class RuntimeSetPositionState : IDisposable
|
|||
_unboundDeferredCellOrder.Count,
|
||||
_preparedMovers.Count,
|
||||
_moverPreparationAuthorities.Count,
|
||||
_placementCompletionWatches.Count,
|
||||
_acknowledgedPlacementCompletions.Count,
|
||||
_collisionPrefixQuiescence.Count,
|
||||
pendingQuiescenceProjections);
|
||||
}
|
||||
|
||||
internal int PendingProjectionCount => _pendingProjection.Count;
|
||||
internal bool CanBeginAuthoredPlacementSequence =>
|
||||
_nextOperationId != ulong.MaxValue;
|
||||
|
||||
internal bool IsCollisionPrefixQuiescing(uint landblockId) =>
|
||||
_collisionPrefixQuiescence.ContainsKey(
|
||||
|
|
@ -812,6 +824,111 @@ internal sealed class RuntimeSetPositionState : IDisposable
|
|||
portal,
|
||||
captureMoverPreparationAuthority: true);
|
||||
|
||||
internal bool IsPlacementCurrent(
|
||||
in RuntimeEntityPlacementToken token)
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
return token.IsValid
|
||||
&& _operations.TryGetValue(token.Entity, out Operation? operation)
|
||||
&& operation.Token == token
|
||||
&& IsCurrent(operation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reserves the exact acknowledgement edge for a higher-level Runtime
|
||||
/// transaction. Ordinary SetPosition operations retain no completion
|
||||
/// history; only explicitly watched tokens survive operation retirement.
|
||||
/// </summary>
|
||||
internal bool WatchPlacementCompletion(
|
||||
in RuntimeEntityPlacementToken token)
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
return IsPlacementCurrent(token)
|
||||
&& _placementCompletionWatches.Add(token);
|
||||
}
|
||||
|
||||
internal bool IsPlacementCompletionTracked(
|
||||
in RuntimeEntityPlacementToken token)
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
return token.IsValid
|
||||
&& (IsPlacementCurrent(token)
|
||||
&& _placementCompletionWatches.Contains(token)
|
||||
|| _acknowledgedPlacementCompletions.ContainsKey(token));
|
||||
}
|
||||
|
||||
internal bool TryPeekAcknowledgedPlacement(
|
||||
in RuntimeEntityPlacementToken token,
|
||||
out RuntimePlacementProjectionToken projection)
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
if (token.IsValid
|
||||
&& _acknowledgedPlacementCompletions.TryGetValue(
|
||||
token,
|
||||
out projection))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
projection = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
internal bool ConsumeAcknowledgedPlacement(
|
||||
in RuntimeEntityPlacementToken token,
|
||||
in RuntimePlacementProjectionToken expected)
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
return token.IsValid
|
||||
&& _acknowledgedPlacementCompletions.TryGetValue(
|
||||
token,
|
||||
out RuntimePlacementProjectionToken current)
|
||||
&& current == expected
|
||||
&& _acknowledgedPlacementCompletions.Remove(token);
|
||||
}
|
||||
|
||||
internal void ForgetPlacementCompletion(
|
||||
in RuntimeEntityPlacementToken token)
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
ForgetPlacementCompletionCore(token);
|
||||
}
|
||||
|
||||
internal RuntimePlacementCancellationReceipt ForgetExactPlacement(
|
||||
in RuntimeEntityPlacementToken token)
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
ForgetPlacementCompletionCore(token);
|
||||
if (!token.IsValid
|
||||
|| !_operations.TryGetValue(token.Entity, out Operation? operation)
|
||||
|| operation.Token != token)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
return CancelCore(operation);
|
||||
}
|
||||
|
||||
internal RuntimeEntityPlacementToken TryBeginExclusiveAuthoredPlacement(
|
||||
RuntimeEntityRecord record,
|
||||
ulong expectedPositionAuthorityVersion,
|
||||
RuntimeSetPositionOperationKind kind,
|
||||
RuntimePortalPlacementAuthority portal = default)
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
ArgumentNullException.ThrowIfNull(record);
|
||||
if (record.Key is not { } key
|
||||
|| _operations.ContainsKey(key)
|
||||
|| HasRetainedCompletion(key))
|
||||
{
|
||||
return default;
|
||||
}
|
||||
return BeginAcceptedPlacementCore(
|
||||
record,
|
||||
expectedPositionAuthorityVersion,
|
||||
kind,
|
||||
portal,
|
||||
captureMoverPreparationAuthority: true);
|
||||
}
|
||||
|
||||
internal void PrepareDormantLocalActivationOwnership(
|
||||
RuntimeEntityRecord record,
|
||||
PhysicsBody body,
|
||||
|
|
@ -853,6 +970,7 @@ internal sealed class RuntimeSetPositionState : IDisposable
|
|||
record.Snapshot.Physics?.Position ?? record.Snapshot.Position;
|
||||
if (record.Key is not { } key
|
||||
|| !_entities.IsCurrent(record)
|
||||
|| HasRetainedCompletion(key)
|
||||
|| record.PositionAuthorityVersion
|
||||
!= expectedPositionAuthorityVersion
|
||||
|| (captureMoverPreparationAuthority
|
||||
|
|
@ -947,6 +1065,17 @@ internal sealed class RuntimeSetPositionState : IDisposable
|
|||
return IsCurrent(replacement) ? token : default;
|
||||
}
|
||||
|
||||
private bool HasRetainedCompletion(RuntimeEntityKey key)
|
||||
{
|
||||
foreach (RuntimeEntityPlacementToken token
|
||||
in _acknowledgedPlacementCompletions.Keys)
|
||||
{
|
||||
if (token.Entity == key)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal RuntimeSetPositionMoverPreparationStatus PrepareMover(
|
||||
in RuntimeEntityPlacementToken token,
|
||||
in RuntimeSetPositionMoverPreparation preparation,
|
||||
|
|
@ -2206,6 +2335,12 @@ internal sealed class RuntimeSetPositionState : IDisposable
|
|||
operation.ProjectionSequence = 0UL;
|
||||
if (pending.Kind is RuntimePlacementProjectionKind.Place)
|
||||
{
|
||||
if (_placementCompletionWatches.Remove(operation.Token))
|
||||
{
|
||||
_acknowledgedPlacementCompletions.Add(
|
||||
operation.Token,
|
||||
pending.Token);
|
||||
}
|
||||
operation.Stage = RuntimeEntityPlacementStage.AwaitingCommitAcknowledgement;
|
||||
_moverPreparationAuthorities.Remove(operation.Key);
|
||||
return _operations.Remove(operation.Key);
|
||||
|
|
@ -3041,6 +3176,8 @@ internal sealed class RuntimeSetPositionState : IDisposable
|
|||
_lostDeadlineNodeIndex.Clear();
|
||||
_preparedMovers.Clear();
|
||||
_moverPreparationAuthorities.Clear();
|
||||
_placementCompletionWatches.Clear();
|
||||
_acknowledgedPlacementCompletions.Clear();
|
||||
_collisionPrefixQuiescence.Clear();
|
||||
_pendingProjection.Clear();
|
||||
_expiredLostCells.Clear();
|
||||
|
|
@ -3859,6 +3996,7 @@ internal sealed class RuntimeSetPositionState : IDisposable
|
|||
CancelExactLostKey(key);
|
||||
if (!_operations.Remove(key, out Operation? operation))
|
||||
return false;
|
||||
ForgetPlacementCompletionCore(operation.Token);
|
||||
_moverPreparationAuthorities.Remove(key);
|
||||
UnindexDeferred(operation);
|
||||
if (!preserveLostFamily && cancelLostFamily)
|
||||
|
|
@ -3929,6 +4067,15 @@ internal sealed class RuntimeSetPositionState : IDisposable
|
|||
: default;
|
||||
}
|
||||
|
||||
private void ForgetPlacementCompletionCore(
|
||||
in RuntimeEntityPlacementToken token)
|
||||
{
|
||||
if (!token.IsValid)
|
||||
return;
|
||||
_placementCompletionWatches.Remove(token);
|
||||
_acknowledgedPlacementCompletions.Remove(token);
|
||||
}
|
||||
|
||||
private void IndexDeferred(Operation operation)
|
||||
{
|
||||
if (operation.ExactCellId == 0u
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue