129 lines
4.8 KiB
C#
129 lines
4.8 KiB
C#
using AcDream.App.Streaming;
|
|
using AcDream.Core.World;
|
|
using DatReaderWriter.DBObjs;
|
|
|
|
namespace AcDream.App.Tests.Streaming;
|
|
|
|
/// <summary>
|
|
/// C4 route 4b-1: focused tests for the graphical host's
|
|
/// <see cref="GraphicalRemotePlacementServiceWindow"/> — the App-side
|
|
/// implementation of <c>IRuntimeRemotePlacementServiceWindow</c> that did not
|
|
/// exist before this route. Verifies the predicate requires the retained
|
|
/// presentation fence and <see cref="GpuWorldState.IsNearTier"/> (not
|
|
/// <see cref="GpuWorldState.IsNearTierOrPending"/>, which is also true for a
|
|
/// merely-queued landblock — see the class's own doc comment) and
|
|
/// canonicalizes a full ACE cell id to the landblock the tier map keys on.
|
|
/// </summary>
|
|
public sealed class GraphicalRemotePlacementServiceWindowTests
|
|
{
|
|
// GpuWorldState's tier map is keyed by the CANONICAL 0xFFFF-ending form
|
|
// (LoadedLandblock.LandblockId/AddLandblock require callers to already
|
|
// pass it that way — see StreamingControllerReadinessTests' own
|
|
// 0x1236FFFFu convention). The window itself is exercised with a full
|
|
// ACE outdoor-cell id (landblock high word + a real cell low word),
|
|
// matching CreateObject.ServerPosition.LandblockId's actual shape, to
|
|
// prove IsWithinServiceWindow canonicalizes it the same way
|
|
// GpuWorldState's own writers do.
|
|
private const uint LandblockHighWord = 0x0A0B0000u;
|
|
private const uint CanonicalLandblock = LandblockHighWord | 0xFFFFu;
|
|
private const uint OutdoorCell = LandblockHighWord | 0x0001u;
|
|
|
|
[Fact]
|
|
public void ConstructorRequiresPresentationFence()
|
|
{
|
|
var state = new GpuWorldState();
|
|
|
|
Assert.Throws<ArgumentNullException>(() =>
|
|
new GraphicalRemotePlacementServiceWindow(state, null!));
|
|
Assert.DoesNotContain(
|
|
typeof(GraphicalRemotePlacementServiceWindow)
|
|
.GetConstructors(
|
|
System.Reflection.BindingFlags.Instance
|
|
| System.Reflection.BindingFlags.Public
|
|
| System.Reflection.BindingFlags.NonPublic),
|
|
constructor => constructor.GetParameters().Length == 1);
|
|
}
|
|
|
|
[Fact]
|
|
public void True_WhenTheLandblockIsNearTier()
|
|
{
|
|
var state = new GpuWorldState();
|
|
state.AddLandblock(new LoadedLandblock(
|
|
CanonicalLandblock,
|
|
new LandBlock(),
|
|
Array.Empty<AcDream.Core.World.WorldEntity>()));
|
|
var window = new GraphicalRemotePlacementServiceWindow(
|
|
state,
|
|
static _ => true);
|
|
|
|
Assert.True(window.IsWithinServiceWindow(OutdoorCell));
|
|
}
|
|
|
|
[Fact]
|
|
public void False_WhenTheLandblockWasNeverPublished()
|
|
{
|
|
var state = new GpuWorldState();
|
|
var window = new GraphicalRemotePlacementServiceWindow(
|
|
state,
|
|
static _ => true);
|
|
|
|
Assert.False(window.IsWithinServiceWindow(OutdoorCell));
|
|
}
|
|
|
|
[Fact]
|
|
public void False_WhenTheLandblockIsOnlyPendingNotYetCollisionPublished()
|
|
{
|
|
var state = new GpuWorldState();
|
|
// A live projection arriving before its landblock loads parks as
|
|
// "pending near tier" — GpuWorldState.IsNearTierOrPending reads true
|
|
// for this, but collision has NOT been published yet.
|
|
Assert.False(
|
|
state.AddEntitiesToExistingLandblock(
|
|
LandblockHighWord, Array.Empty<AcDream.Core.World.WorldEntity>()));
|
|
Assert.True(state.IsNearTierOrPending(CanonicalLandblock));
|
|
var window = new GraphicalRemotePlacementServiceWindow(
|
|
state,
|
|
static _ => true);
|
|
|
|
Assert.False(window.IsWithinServiceWindow(OutdoorCell));
|
|
}
|
|
|
|
[Fact]
|
|
public void False_AfterTheLandblockRetiresViaDetachNearLayer()
|
|
{
|
|
var state = new GpuWorldState();
|
|
state.AddLandblock(new LoadedLandblock(
|
|
CanonicalLandblock,
|
|
new LandBlock(),
|
|
Array.Empty<AcDream.Core.World.WorldEntity>()));
|
|
var window = new GraphicalRemotePlacementServiceWindow(
|
|
state,
|
|
static _ => true);
|
|
Assert.True(window.IsWithinServiceWindow(OutdoorCell));
|
|
|
|
_ = state.DetachNearLayer(LandblockHighWord);
|
|
|
|
Assert.False(window.IsWithinServiceWindow(OutdoorCell));
|
|
}
|
|
|
|
[Fact]
|
|
public void False_WhenExactPresentationPrefixIsIncomplete()
|
|
{
|
|
var state = new GpuWorldState();
|
|
state.AddLandblock(new LoadedLandblock(
|
|
CanonicalLandblock,
|
|
new LandBlock(),
|
|
Array.Empty<AcDream.Core.World.WorldEntity>()));
|
|
uint observed = 0;
|
|
var window = new GraphicalRemotePlacementServiceWindow(
|
|
state,
|
|
id =>
|
|
{
|
|
observed = id;
|
|
return false;
|
|
});
|
|
|
|
Assert.False(window.IsWithinServiceWindow(OutdoorCell));
|
|
Assert.Equal(CanonicalLandblock, observed);
|
|
}
|
|
}
|