refactor(app): key live projections by runtime identity
Move materialized live-object sidecars and presentation worksets to exact RuntimeEntityKey ownership. Runtime remains the only GUID/incarnation/local-ID authority while hydration, animation, effects, lights, equipped children, renderer resources, visibility, liveness, and teardown resolve exact projection identities. Preserve synchronous callbacks, local-ID allocation order, and current rendering behavior.
This commit is contained in:
parent
e18df84437
commit
420e5eea70
73 changed files with 2939 additions and 1715 deletions
|
|
@ -11,6 +11,7 @@ using AcDream.Core.Net.Messages;
|
|||
using AcDream.Core.Physics;
|
||||
using AcDream.Core.Plugins;
|
||||
using AcDream.Core.World;
|
||||
using AcDream.Runtime.Entities;
|
||||
using DatReaderWriter;
|
||||
using DatReaderWriter.DBObjs;
|
||||
using DatReaderWriter.Types;
|
||||
|
|
@ -116,13 +117,13 @@ internal sealed class DatLiveEntityProjectionMaterializer
|
|||
}
|
||||
|
||||
public bool TryMaterialize(
|
||||
LiveEntityRecord expectedRecord,
|
||||
RuntimeEntityRecord expectedCanonical,
|
||||
WorldSession.EntitySpawn canonicalSpawn,
|
||||
LiveProjectionPurpose purpose,
|
||||
ulong expectedCreateIntegrationVersion,
|
||||
LiveEntityAppearanceUpdateState? appearanceUpdate = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(expectedRecord);
|
||||
ArgumentNullException.ThrowIfNull(expectedCanonical);
|
||||
if (purpose is LiveProjectionPurpose.AppearanceMutation
|
||||
!= (appearanceUpdate is not null))
|
||||
{
|
||||
|
|
@ -131,13 +132,18 @@ internal sealed class DatLiveEntityProjectionMaterializer
|
|||
nameof(appearanceUpdate));
|
||||
}
|
||||
if (!_runtime.IsCurrentCreateIntegration(
|
||||
expectedRecord,
|
||||
expectedCanonical,
|
||||
expectedCreateIntegrationVersion)
|
||||
|| canonicalSpawn.Guid != expectedRecord.ServerGuid
|
||||
|| canonicalSpawn.InstanceSequence != expectedRecord.Generation)
|
||||
|| canonicalSpawn.Guid != expectedCanonical.ServerGuid
|
||||
|| canonicalSpawn.InstanceSequence != expectedCanonical.Incarnation)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_runtime.TryGetProjection(
|
||||
expectedCanonical,
|
||||
out LiveEntityRecord? expectedRecord);
|
||||
if (appearanceUpdate is not null && expectedRecord is null)
|
||||
return false;
|
||||
|
||||
_received++;
|
||||
bool dumpLiveSpawns = _options.DumpLiveSpawns;
|
||||
|
|
@ -186,7 +192,7 @@ internal sealed class DatLiveEntityProjectionMaterializer
|
|||
return false;
|
||||
}
|
||||
|
||||
expectedRecord.HasPartArray = true;
|
||||
_runtime.SetHasPartArray(expectedCanonical, true);
|
||||
ushort? stanceOverride = canonicalSpawn.MotionState?.Stance;
|
||||
ushort? commandOverride = canonicalSpawn.MotionState?.ForwardCommand;
|
||||
var idleCycle = MotionResolver.GetIdleCycle(
|
||||
|
|
@ -327,7 +333,8 @@ internal sealed class DatLiveEntityProjectionMaterializer
|
|||
|
||||
bool supersessionRecovery =
|
||||
purpose is LiveProjectionPurpose.CreateSupersessionRecovery;
|
||||
if (supersessionRecovery && expectedRecord.WorldEntity is not null)
|
||||
if (supersessionRecovery
|
||||
&& expectedRecord?.WorldEntity is not null)
|
||||
{
|
||||
return LiveEntityCreateSupersessionRecovery.TryApply(
|
||||
_runtime,
|
||||
|
|
@ -380,7 +387,7 @@ internal sealed class DatLiveEntityProjectionMaterializer
|
|||
if (appearanceUpdate is { } visualUpdate)
|
||||
{
|
||||
return ApplyAppearance(
|
||||
expectedRecord,
|
||||
expectedRecord!,
|
||||
canonicalSpawn,
|
||||
visualUpdate,
|
||||
setup,
|
||||
|
|
@ -398,6 +405,7 @@ internal sealed class DatLiveEntityProjectionMaterializer
|
|||
}
|
||||
|
||||
return MaterializeProjection(
|
||||
expectedCanonical,
|
||||
expectedRecord,
|
||||
canonicalSpawn,
|
||||
setup,
|
||||
|
|
@ -670,7 +678,8 @@ internal sealed class DatLiveEntityProjectionMaterializer
|
|||
}
|
||||
|
||||
private bool MaterializeProjection(
|
||||
LiveEntityRecord expectedRecord,
|
||||
RuntimeEntityRecord expectedCanonical,
|
||||
LiveEntityRecord? retainedRecord,
|
||||
WorldSession.EntitySpawn spawn,
|
||||
Setup setup,
|
||||
MotionResolver.IdleCycle? idleCycle,
|
||||
|
|
@ -690,17 +699,18 @@ internal sealed class DatLiveEntityProjectionMaterializer
|
|||
ulong expectedCreateIntegrationVersion,
|
||||
bool synchronizeAnimation)
|
||||
{
|
||||
if (!_runtime.TryGetEffectProfile(spawn.Guid, out _))
|
||||
EntityEffectProfile profile = spawn.Physics is { } physics
|
||||
? EntityEffectProfile.CreateLive(setup, physics)
|
||||
: EntityEffectProfile.CreateDatStatic(setup);
|
||||
if (retainedRecord is not null
|
||||
&& !_runtime.TryGetEffectProfile(spawn.Guid, out _))
|
||||
{
|
||||
EntityEffectProfile profile = spawn.Physics is { } physics
|
||||
? EntityEffectProfile.CreateLive(setup, physics)
|
||||
: EntityEffectProfile.CreateDatStatic(setup);
|
||||
_runtime.SetEffectProfile(spawn.Guid, profile);
|
||||
}
|
||||
|
||||
bool createdProjection = false;
|
||||
WorldEntity? entity = _runtime.MaterializeLiveEntity(
|
||||
spawn.Guid,
|
||||
expectedCanonical,
|
||||
spawn.Position!.Value.LandblockId,
|
||||
localId =>
|
||||
{
|
||||
|
|
@ -721,8 +731,12 @@ internal sealed class DatLiveEntityProjectionMaterializer
|
|||
if (bounds.TryGet(out Vector3 minimum, out Vector3 maximum))
|
||||
created.SetLocalBounds(minimum, maximum);
|
||||
return created;
|
||||
});
|
||||
},
|
||||
LiveEntityProjectionKind.World,
|
||||
initializeProjection: record => record.EffectProfile = profile,
|
||||
out LiveEntityRecord? expectedRecord);
|
||||
if (entity is null
|
||||
|| expectedRecord is null
|
||||
|| !_runtime.IsCurrentCreateIntegration(
|
||||
expectedRecord,
|
||||
expectedCreateIntegrationVersion)
|
||||
|
|
@ -828,7 +842,7 @@ internal sealed class DatLiveEntityProjectionMaterializer
|
|||
if (dumpLiveSpawns && _received % 20 == 0)
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"live: animated={_runtime.AnimationRuntimes.Count} "
|
||||
$"live: animated={_runtime.AnimationRuntimeCount} "
|
||||
+ $"animReject: noCycle={_noCycle} fr0={_zeroFramerate} "
|
||||
+ $"1frame={_singleFrame} partFrames={_missingPartFrames}");
|
||||
Console.WriteLine(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue