Preserve prepublication local motion completion, require the PartArray enter-world lifecycle port, and balance deferred Use busy ownership across dispatch and cancellation. Reconcile the completed GameWindow connected gates and add regression coverage. Co-authored-by: Codex <codex@openai.com>
57 lines
1.8 KiB
C#
57 lines
1.8 KiB
C#
using AcDream.App.Input;
|
|
using AcDream.Core.Physics;
|
|
|
|
namespace AcDream.App.Tests.Input;
|
|
|
|
public sealed class LocalPlayerControllerSlotTests
|
|
{
|
|
[Fact]
|
|
public void MotionPreparation_RoutesCompletionWithoutPublishingController()
|
|
{
|
|
var slot = new LocalPlayerControllerSlot();
|
|
ILocalPlayerMotionSource source = slot;
|
|
var controller = new PlayerMovementController(new PhysicsEngine());
|
|
controller.Motion.AddToQueue(0, MotionCommand.Ready, 0);
|
|
|
|
using (slot.BeginMotionPreparation(controller))
|
|
{
|
|
Assert.Null(slot.Controller);
|
|
MotionInterpreter? owner = source.Motion;
|
|
Assert.Same(controller.Motion, owner);
|
|
|
|
owner!.MotionDone(MotionCommand.Ready, success: true);
|
|
Assert.False(controller.Motion.MotionsPending());
|
|
}
|
|
|
|
Assert.Null(source.Motion);
|
|
}
|
|
|
|
[Fact]
|
|
public void MotionPreparation_HandsOffToCommittedControllerOnDispose()
|
|
{
|
|
var slot = new LocalPlayerControllerSlot();
|
|
ILocalPlayerMotionSource source = slot;
|
|
var controller = new PlayerMovementController(new PhysicsEngine());
|
|
|
|
using (slot.BeginMotionPreparation(controller))
|
|
{
|
|
slot.Controller = controller;
|
|
Assert.Same(controller.Motion, source.Motion);
|
|
}
|
|
|
|
Assert.Same(controller.Motion, source.Motion);
|
|
}
|
|
|
|
[Fact]
|
|
public void MotionPreparation_RejectsConcurrentCandidate()
|
|
{
|
|
var slot = new LocalPlayerControllerSlot();
|
|
var first = new PlayerMovementController(new PhysicsEngine());
|
|
var second = new PlayerMovementController(new PhysicsEngine());
|
|
|
|
using IDisposable preparation = slot.BeginMotionPreparation(first);
|
|
|
|
Assert.Throws<InvalidOperationException>(
|
|
() => slot.BeginMotionPreparation(second));
|
|
}
|
|
}
|