test: replace campaign labels with behavior names
This commit is contained in:
parent
e6fab96f12
commit
9c6b143a03
30 changed files with 135 additions and 97 deletions
|
|
@ -1,103 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using AcDream.Core.Physics;
|
||||
using AcDream.Core.Physics.Motion;
|
||||
|
||||
namespace AcDream.Core.Tests.Physics.Motion;
|
||||
|
||||
/// <summary>
|
||||
/// R5 conformance harness — a scriptable <see cref="IPhysicsObjHost"/> fake
|
||||
/// backed by a shared <see cref="World"/> so <see cref="GetObjectA"/> resolves
|
||||
/// OTHER hosts (the cross-entity seam the voyeur round-trip needs). Each host
|
||||
/// lazily owns a <see cref="TargetManager"/> and a <see cref="PositionManager"/>
|
||||
/// (the two R5 managers under test), and records every
|
||||
/// <see cref="HandleUpdateTarget"/> the managers fan out so tests can assert on
|
||||
/// delivery.
|
||||
///
|
||||
/// <para>Position/velocity/radius/contact/max-speed and both clocks are mutable
|
||||
/// fields tests drive directly (retail's <c>CPhysicsObj</c> accessors). The
|
||||
/// <c>set_target</c>/<c>clear_target</c>/<c>add_voyeur</c>/<c>remove_voyeur</c>/
|
||||
/// <c>receive_target_update</c> seams forward to the owned
|
||||
/// <see cref="TargetManager"/> exactly as retail's <c>CPhysicsObj</c> does.</para>
|
||||
/// </summary>
|
||||
internal sealed class R5Host : IPhysicsObjHost
|
||||
{
|
||||
public readonly Dictionary<uint, R5Host> World;
|
||||
|
||||
public R5Host(uint id, Dictionary<uint, R5Host> world)
|
||||
{
|
||||
Id = id;
|
||||
World = world;
|
||||
World[id] = this;
|
||||
}
|
||||
|
||||
// ── scriptable CPhysicsObj state ───────────────────────────────────────
|
||||
public uint Id { get; }
|
||||
public Position Position { get; set; } = new(1u, Vector3.Zero, Quaternion.Identity);
|
||||
public Vector3 Velocity { get; set; } = Vector3.Zero;
|
||||
public float Radius { get; set; } = 0.5f;
|
||||
public bool InContact { get; set; } = true;
|
||||
public float? MinterpMaxSpeed { get; set; } = 1.0f;
|
||||
public double CurTime { get; set; }
|
||||
public double PhysicsTimerTime { get; set; }
|
||||
|
||||
/// <summary>Set to false to simulate a target that isn't currently
|
||||
/// resolvable (out of streaming view) — <see cref="GetObjectA"/> returns
|
||||
/// null for it even while it's in <see cref="World"/>.</summary>
|
||||
public bool Resolvable { get; set; } = true;
|
||||
|
||||
// ── owned R5 managers ──────────────────────────────────────────────────
|
||||
private TargetManager? _targetManager;
|
||||
public TargetManager TargetManager => _targetManager ??= new TargetManager(this);
|
||||
public TargetManager? TargetManagerOrNull => _targetManager;
|
||||
|
||||
private PositionManager? _positionManager;
|
||||
public PositionManager PositionManager => _positionManager ??= new PositionManager(this);
|
||||
|
||||
// ── recorded fan-outs ──────────────────────────────────────────────────
|
||||
public readonly List<TargetInfo> HandleUpdateTargetCalls = new();
|
||||
public int InterruptCurrentMovementCalls;
|
||||
|
||||
// ── IPhysicsObjHost ────────────────────────────────────────────────────
|
||||
public IPhysicsObjHost? GetObjectA(uint id)
|
||||
=> World.TryGetValue(id, out var h) && h.Resolvable ? h : null;
|
||||
|
||||
public IPhysicsObjHost? GetRelationshipTarget(uint objectId) =>
|
||||
_targetManager?.GetRelationshipTarget(objectId);
|
||||
|
||||
public void HandleUpdateTarget(TargetInfo info)
|
||||
{
|
||||
HandleUpdateTargetCalls.Add(info);
|
||||
// Retail CPhysicsObj::HandleUpdateTarget also fans to the position
|
||||
// manager's sticky sub-manager (context 0). Mirror that so sticky tests
|
||||
// that rely on the full CPhysicsObj fan-out see the callback.
|
||||
if (info.ContextId == 0)
|
||||
_positionManager?.HandleUpdateTarget(info);
|
||||
}
|
||||
|
||||
public void InterruptCurrentMovement() => InterruptCurrentMovementCalls++;
|
||||
|
||||
public void SetTarget(uint contextId, uint objectId, float radius, double quantum)
|
||||
=> TargetManager.SetTarget(contextId, objectId, radius, quantum);
|
||||
|
||||
public void ClearTarget() => _targetManager?.ClearTarget();
|
||||
|
||||
public void ReceiveTargetUpdate(TargetInfo info, IPhysicsObjHost sender) =>
|
||||
_targetManager?.ReceiveUpdate(info, sender);
|
||||
|
||||
public void AddVoyeur(IPhysicsObjHost watcher, float radius, double quantum)
|
||||
=> TargetManager.AddVoyeur(watcher, radius, quantum);
|
||||
|
||||
public void RemoveVoyeur(uint watcherId, IPhysicsObjHost expectedWatcher) =>
|
||||
_targetManager?.RemoveVoyeur(watcherId, expectedWatcher);
|
||||
|
||||
// ── test helpers ───────────────────────────────────────────────────────
|
||||
public void SetOrigin(Vector3 origin)
|
||||
=> Position = new Position(Position.ObjCellId, origin, Position.Frame.Orientation);
|
||||
|
||||
public void AdvanceClocks(double seconds)
|
||||
{
|
||||
CurTime += seconds;
|
||||
PhysicsTimerTime += seconds;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue