refactor(world): extract live projection mechanics
Move appearance rebinding, collision construction, default-pose resolution, local shadow ownership, and exact leave-world presentation into focused owners. Preserve retail parent ordering with staged validation, committed recovery, recursive attached-subtree withdrawal, and retryable exact teardown across parent, pickup, position, unwield, and pose-loss edges. Co-Authored-By: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
c87bac31a0
commit
69a2ca0c6d
26 changed files with 4172 additions and 430 deletions
|
|
@ -931,6 +931,38 @@ public sealed class LiveEntityRuntime
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exact-incarnation withdrawal used after App leave-world callbacks. A
|
||||
/// callback may accept a newer INSTANCE_TS for the same GUID; that newer
|
||||
/// projection must never be withdrawn by the displaced operation.
|
||||
/// </summary>
|
||||
public bool WithdrawLiveEntityProjection(LiveEntityRecord expectedRecord)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(expectedRecord);
|
||||
return WithdrawLiveEntityProjection(
|
||||
expectedRecord,
|
||||
expectedRecord.PositionAuthorityVersion,
|
||||
expectedRecord.ProjectionMutationVersion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exact-operation withdrawal used across arbitrary App callbacks. Both
|
||||
/// the accepted Position authority and projection mutation token are
|
||||
/// pinned so a same-incarnation re-entry cannot be removed by an older
|
||||
/// parent/pickup/leave-world operation.
|
||||
/// </summary>
|
||||
internal bool WithdrawLiveEntityProjection(
|
||||
LiveEntityRecord expectedRecord,
|
||||
ulong expectedPositionAuthorityVersion,
|
||||
ulong expectedProjectionMutationVersion)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(expectedRecord);
|
||||
return IsCurrentRecord(expectedRecord)
|
||||
&& expectedRecord.PositionAuthorityVersion == expectedPositionAuthorityVersion
|
||||
&& expectedRecord.ProjectionMutationVersion == expectedProjectionMutationVersion
|
||||
&& WithdrawLiveEntityProjection(expectedRecord.ServerGuid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Withdraws a still-live projection whose authoritative rollback frame
|
||||
/// is outside every world cell. Logical owners remain registered.
|
||||
|
|
@ -1515,7 +1547,6 @@ public sealed class LiveEntityRuntime
|
|||
RefreshRecord(update.ChildGuid, accepted);
|
||||
if (_recordsByGuid.TryGetValue(update.ChildGuid, out LiveEntityRecord? record))
|
||||
record.AdvancePositionAuthority();
|
||||
ClearWorldCell(update.ChildGuid);
|
||||
}
|
||||
return applied;
|
||||
}
|
||||
|
|
@ -1528,11 +1559,43 @@ public sealed class LiveEntityRuntime
|
|||
RefreshRecord(update.ChildGuid, accepted);
|
||||
if (_recordsByGuid.TryGetValue(update.ChildGuid, out LiveEntityRecord? record))
|
||||
record.AdvancePositionAuthority();
|
||||
ClearWorldCell(update.ChildGuid);
|
||||
}
|
||||
return applied;
|
||||
}
|
||||
|
||||
internal bool CommitStagedParent(
|
||||
ParentAttachmentRelation relation,
|
||||
out WorldSession.EntitySpawn accepted)
|
||||
{
|
||||
bool committed = _inbound.TryCommitParent(
|
||||
relation.ChildGuid,
|
||||
relation.ParentGuid,
|
||||
relation.ParentLocation,
|
||||
relation.PlacementId,
|
||||
relation.ChildPositionSequence,
|
||||
out accepted);
|
||||
if (committed)
|
||||
RefreshRecord(relation.ChildGuid, accepted);
|
||||
return committed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Commits retail <c>CPhysicsObj::set_parent</c>'s cell-less edge only
|
||||
/// after the parent accepted the child (PartArray + holding-location
|
||||
/// validation). The POSITION_TS is consumed before this step, matching
|
||||
/// retail; invalid parent relationships retain the old world projection.
|
||||
/// </summary>
|
||||
internal bool CommitAcceptedParentCellless(
|
||||
LiveEntityRecord record,
|
||||
ulong positionAuthorityVersion)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(record);
|
||||
if (!IsCurrentPositionAuthority(record, positionAuthorityVersion))
|
||||
return false;
|
||||
ClearWorldCell(record.ServerGuid);
|
||||
return IsCurrentPositionAuthority(record, positionAuthorityVersion);
|
||||
}
|
||||
|
||||
public bool TryApplyMotion(
|
||||
WorldSession.EntityMotionUpdate update,
|
||||
bool retainPayload,
|
||||
|
|
@ -2154,7 +2217,7 @@ public sealed class LiveEntityRuntime
|
|||
RefreshSpatialRuntimeIndexes(record);
|
||||
}
|
||||
|
||||
private bool IsCurrentRecord(LiveEntityRecord record) =>
|
||||
internal bool IsCurrentRecord(LiveEntityRecord record) =>
|
||||
_recordsByGuid.TryGetValue(record.ServerGuid, out LiveEntityRecord? current)
|
||||
&& ReferenceEquals(current, record);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue