fix(portal): synchronize destination presentation state
This commit is contained in:
parent
4b1bceefbb
commit
e95f55f25b
42 changed files with 2815 additions and 288 deletions
|
|
@ -0,0 +1,104 @@
|
|||
using System.Numerics;
|
||||
using AcDream.App.Rendering.Wb;
|
||||
using AcDream.Core.World;
|
||||
using DatReaderWriter.DBObjs;
|
||||
|
||||
namespace AcDream.App.Tests.Rendering.Wb;
|
||||
|
||||
public sealed class LandblockSpawnAdapterReadinessTests
|
||||
{
|
||||
[Fact]
|
||||
public void RenderReady_WaitsForStaticAndEnvCellMeshes()
|
||||
{
|
||||
var meshes = new ReadinessMeshAdapter();
|
||||
var adapter = new LandblockSpawnAdapter(meshes);
|
||||
var entity = new WorldEntity
|
||||
{
|
||||
Id = 1,
|
||||
ServerGuid = 0,
|
||||
SourceGfxObjOrSetupId = 0x01000010u,
|
||||
Position = Vector3.Zero,
|
||||
Rotation = Quaternion.Identity,
|
||||
MeshRefs = [new MeshRef(0x01000010u, Matrix4x4.Identity)],
|
||||
};
|
||||
var landblock = new LoadedLandblock(
|
||||
0x1234FFFFu,
|
||||
new LandBlock(),
|
||||
new[] { entity });
|
||||
const ulong envCellGeometryId = 0x2_0000_1234ul;
|
||||
|
||||
adapter.OnLandblockLoaded(landblock, new[] { envCellGeometryId });
|
||||
|
||||
Assert.False(adapter.IsLandblockRenderReady(landblock.LandblockId));
|
||||
meshes.ReadyIds.Add(0x01000010ul);
|
||||
Assert.False(adapter.IsLandblockRenderReady(landblock.LandblockId));
|
||||
meshes.ReadyIds.Add(envCellGeometryId);
|
||||
Assert.True(adapter.IsLandblockRenderReady(landblock.LandblockId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RenderReady_EmptyPublishedLandblockIsReadyUntilUnload()
|
||||
{
|
||||
var meshes = new ReadinessMeshAdapter();
|
||||
var adapter = new LandblockSpawnAdapter(meshes);
|
||||
var landblock = new LoadedLandblock(
|
||||
0x1234FFFFu,
|
||||
new LandBlock(),
|
||||
Array.Empty<WorldEntity>());
|
||||
|
||||
adapter.OnLandblockLoaded(landblock);
|
||||
|
||||
Assert.True(adapter.IsLandblockRenderReady(landblock.LandblockId));
|
||||
adapter.OnLandblockUnloaded(landblock.LandblockId);
|
||||
Assert.False(adapter.IsLandblockRenderReady(landblock.LandblockId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SharedEnvCellGeometry_IsPinnedPerLandblockAndReleasedSymmetrically()
|
||||
{
|
||||
const ulong sharedGeometryId = 0x2_0000_1234ul;
|
||||
var meshes = new ReadinessMeshAdapter();
|
||||
var adapter = new LandblockSpawnAdapter(meshes);
|
||||
var first = new LoadedLandblock(
|
||||
0x1234FFFFu,
|
||||
new LandBlock(),
|
||||
Array.Empty<WorldEntity>());
|
||||
var second = new LoadedLandblock(
|
||||
0x1235FFFFu,
|
||||
new LandBlock(),
|
||||
Array.Empty<WorldEntity>());
|
||||
|
||||
adapter.OnLandblockLoaded(first, new[] { sharedGeometryId, sharedGeometryId });
|
||||
adapter.OnLandblockLoaded(second, new[] { sharedGeometryId });
|
||||
|
||||
Assert.Equal(2, meshes.ReferenceCounts[sharedGeometryId]);
|
||||
Assert.Equal(2, meshes.PreparedPinCalls.Count);
|
||||
|
||||
adapter.OnLandblockUnloaded(first.LandblockId);
|
||||
Assert.Equal(1, meshes.ReferenceCounts[sharedGeometryId]);
|
||||
|
||||
adapter.OnLandblockUnloaded(second.LandblockId);
|
||||
Assert.DoesNotContain(sharedGeometryId, meshes.ReferenceCounts);
|
||||
}
|
||||
|
||||
private sealed class ReadinessMeshAdapter : IWbMeshAdapter
|
||||
{
|
||||
public HashSet<ulong> ReadyIds { get; } = new();
|
||||
public Dictionary<ulong, int> ReferenceCounts { get; } = new();
|
||||
public List<ulong> PreparedPinCalls { get; } = new();
|
||||
public void IncrementRefCount(ulong id) =>
|
||||
ReferenceCounts[id] = ReferenceCounts.GetValueOrDefault(id) + 1;
|
||||
public void PinPreparedRenderData(ulong id)
|
||||
{
|
||||
PreparedPinCalls.Add(id);
|
||||
IncrementRefCount(id);
|
||||
}
|
||||
public void DecrementRefCount(ulong id)
|
||||
{
|
||||
int count = ReferenceCounts[id] - 1;
|
||||
if (count == 0) ReferenceCounts.Remove(id);
|
||||
else ReferenceCounts[id] = count;
|
||||
}
|
||||
public bool IsRenderDataReady(ulong id) => ReadyIds.Contains(id);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue