refactor(world): extract live appearance and parenting
Move ObjDesc, Parent, Pickup, child-ready, and retained projection recovery into LiveEntityHydrationController while preserving retail timestamp and leave-world semantics. Pin ready publication to exact projection authority and restore attached descendant chains synchronously.
This commit is contained in:
parent
40352d5a7a
commit
fe5514967c
9 changed files with 1098 additions and 199 deletions
|
|
@ -201,6 +201,7 @@ public sealed class LiveEntityRecord
|
|||
? 0UL
|
||||
: 1UL;
|
||||
MovementAuthorityVersion = 1UL;
|
||||
ObjDescAuthorityVersion = 1UL;
|
||||
FinalPhysicsState = RetailPhysicsStateTransitions.ConstructorState;
|
||||
ApplyRawPhysicsState(RawPhysicsState);
|
||||
}
|
||||
|
|
@ -258,6 +259,7 @@ public sealed class LiveEntityRecord
|
|||
internal ulong VectorAuthorityVersion { get; private set; }
|
||||
internal ulong VelocityAuthorityVersion { get; private set; }
|
||||
internal ulong MovementAuthorityVersion { get; private set; }
|
||||
internal ulong ObjDescAuthorityVersion { get; private set; }
|
||||
/// <summary>
|
||||
/// Advances for every accepted CreateObject affecting this incarnation,
|
||||
/// including a fresher same-INSTANCE_TS retransmit. App integration uses
|
||||
|
|
@ -284,6 +286,15 @@ public sealed class LiveEntityRecord
|
|||
internal bool ProjectionHydrationInProgress { get; set; }
|
||||
internal ulong ProjectionHydrationCreateVersion { get; set; }
|
||||
internal bool ProjectionHydrationRetryRequested { get; set; }
|
||||
/// <summary>
|
||||
/// A renderer mesh transaction can be re-entered by a newer accepted
|
||||
/// ObjDesc. Keep that independent projection obligation on the exact
|
||||
/// incarnation until the newest visual description publishes.
|
||||
/// </summary>
|
||||
internal bool AppearanceProjectionSynchronizationPending { get; set; }
|
||||
internal bool AppearanceHydrationInProgress { get; set; }
|
||||
internal ulong AppearanceHydrationVersion { get; set; }
|
||||
internal bool AppearanceHydrationRetryRequested { get; set; }
|
||||
public LiveEntityProjectionKind ProjectionKind { get; internal set; }
|
||||
internal bool RuntimeComponentsTeardownCompleted { get; set; }
|
||||
internal LiveEntityTeardownPlan? RuntimeComponentTeardownPlan { get; set; }
|
||||
|
|
@ -338,6 +349,14 @@ public sealed class LiveEntityRecord
|
|||
VelocityAuthorityVersion++;
|
||||
}
|
||||
|
||||
internal void AdvanceObjDescAuthority()
|
||||
{
|
||||
ObjDescAuthorityVersion++;
|
||||
AppearanceProjectionSynchronizationPending = true;
|
||||
if (AppearanceHydrationInProgress)
|
||||
AppearanceHydrationRetryRequested = true;
|
||||
}
|
||||
|
||||
internal void AdvanceCreateAuthority()
|
||||
{
|
||||
PositionAuthorityVersion++;
|
||||
|
|
@ -345,6 +364,7 @@ public sealed class LiveEntityRecord
|
|||
VectorAuthorityVersion++;
|
||||
VelocityAuthorityVersion++;
|
||||
MovementAuthorityVersion++;
|
||||
ObjDescAuthorityVersion++;
|
||||
CreateIntegrationVersion++;
|
||||
}
|
||||
|
||||
|
|
@ -1547,7 +1567,12 @@ public sealed class LiveEntityRuntime
|
|||
public bool TryApplyObjDesc(ObjDescEvent.Parsed update, out WorldSession.EntitySpawn accepted)
|
||||
{
|
||||
bool applied = _inbound.TryApplyObjDesc(update, out accepted);
|
||||
if (applied) RefreshRecord(update.Guid, accepted);
|
||||
if (applied)
|
||||
{
|
||||
RefreshRecord(update.Guid, accepted);
|
||||
if (_recordsByGuid.TryGetValue(update.Guid, out LiveEntityRecord? record))
|
||||
record.AdvanceObjDescAuthority();
|
||||
}
|
||||
return applied;
|
||||
}
|
||||
|
||||
|
|
@ -1805,6 +1830,13 @@ public sealed class LiveEntityRuntime
|
|||
&& ReferenceEquals(current, record)
|
||||
&& current.MovementAuthorityVersion == authorityVersion;
|
||||
|
||||
internal bool IsCurrentObjDescAuthority(
|
||||
LiveEntityRecord record,
|
||||
ulong authorityVersion) =>
|
||||
_recordsByGuid.TryGetValue(record.ServerGuid, out LiveEntityRecord? current)
|
||||
&& ReferenceEquals(current, record)
|
||||
&& current.ObjDescAuthorityVersion == authorityVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Copies the canonical loaded root-object workset used by retail
|
||||
/// <c>CPhysics::UseTime</c>. The record reference is the incarnation token;
|
||||
|
|
@ -2156,6 +2188,63 @@ public sealed class LiveEntityRuntime
|
|||
return retry;
|
||||
}
|
||||
|
||||
internal bool TryBeginAppearanceHydration(
|
||||
LiveEntityRecord expectedRecord,
|
||||
ulong expectedObjDescAuthorityVersion)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(expectedRecord);
|
||||
if (!expectedRecord.AppearanceProjectionSynchronizationPending
|
||||
|| !IsCurrentObjDescAuthority(
|
||||
expectedRecord,
|
||||
expectedObjDescAuthorityVersion))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
expectedRecord.AppearanceProjectionSynchronizationPending = true;
|
||||
if (expectedRecord.AppearanceHydrationInProgress)
|
||||
{
|
||||
expectedRecord.AppearanceHydrationRetryRequested = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
expectedRecord.AppearanceHydrationInProgress = true;
|
||||
expectedRecord.AppearanceHydrationVersion =
|
||||
expectedObjDescAuthorityVersion;
|
||||
expectedRecord.AppearanceHydrationRetryRequested = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool EndAppearanceHydration(LiveEntityRecord expectedRecord)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(expectedRecord);
|
||||
bool retry = IsCurrentRecord(expectedRecord)
|
||||
&& (expectedRecord.AppearanceHydrationRetryRequested
|
||||
|| expectedRecord.ObjDescAuthorityVersion
|
||||
!= expectedRecord.AppearanceHydrationVersion);
|
||||
expectedRecord.AppearanceHydrationInProgress = false;
|
||||
expectedRecord.AppearanceHydrationVersion = 0UL;
|
||||
expectedRecord.AppearanceHydrationRetryRequested = false;
|
||||
return retry;
|
||||
}
|
||||
|
||||
internal bool TryCompleteAppearanceProjectionSynchronization(
|
||||
LiveEntityRecord expectedRecord,
|
||||
ulong expectedObjDescAuthorityVersion)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(expectedRecord);
|
||||
if (!expectedRecord.AppearanceProjectionSynchronizationPending
|
||||
|| !IsCurrentObjDescAuthority(
|
||||
expectedRecord,
|
||||
expectedObjDescAuthorityVersion))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
expectedRecord.AppearanceProjectionSynchronizationPending = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool IsCurrentCreateIntegration(
|
||||
LiveEntityRecord expectedRecord,
|
||||
ulong expectedCreateIntegrationVersion) =>
|
||||
|
|
@ -2722,6 +2811,10 @@ public sealed class LiveEntityRuntime
|
|||
record.ProjectionHydrationInProgress = false;
|
||||
record.ProjectionHydrationCreateVersion = 0UL;
|
||||
record.ProjectionHydrationRetryRequested = false;
|
||||
record.AppearanceProjectionSynchronizationPending = false;
|
||||
record.AppearanceHydrationInProgress = false;
|
||||
record.AppearanceHydrationVersion = 0UL;
|
||||
record.AppearanceHydrationRetryRequested = false;
|
||||
record.WorldEntity = null;
|
||||
}
|
||||
finally
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue