108 lines
4.4 KiB
C#
108 lines
4.4 KiB
C#
using NUnit.Framework;
|
|
using ProjectM.Server;
|
|
using ProjectM.Simulation;
|
|
using Unity.Core;
|
|
using Unity.Entities;
|
|
using Unity.NetCode;
|
|
|
|
namespace ProjectM.Tests
|
|
{
|
|
/// <summary>
|
|
/// Plain-Entities EditMode tests for the server-only <see cref="StorageOpReceiveSystem"/> — the RPC handler
|
|
/// that applies deposit/withdraw ops to the shared storage container's replicated <c>StorageEntry</c> buffer.
|
|
/// A bare world with a <c>SharedStorageContainer</c> singleton (carrying the buffer) plus synthetic
|
|
/// <c>StorageOpRequest</c> + <c>ReceiveRpcCommandRequest</c> entities exercises the handler. The system plays
|
|
/// its ECB back immediately (Temp allocator), so the handled request entity is destroyed within the single
|
|
/// group update. Mirrors HealthApplyDamageSystemTests. Locks the deposit/withdraw/drop-row behaviour before
|
|
/// the Stage-C const refactor and any later storage-model changes.
|
|
/// </summary>
|
|
public class StorageOpReceiveSystemTests
|
|
{
|
|
static (World world, SimulationSystemGroup group) MakeWorld(string name)
|
|
{
|
|
var world = new World(name);
|
|
var group = world.GetOrCreateSystemManaged<SimulationSystemGroup>();
|
|
group.AddSystemToUpdateList(world.GetOrCreateSystem<StorageOpReceiveSystem>());
|
|
group.SortSystems();
|
|
world.SetTime(new TimeData(elapsedTime: 0f, deltaTime: 1f / 60f));
|
|
return (world, group);
|
|
}
|
|
|
|
static Entity MakeContainer(EntityManager em, ushort itemId, int count)
|
|
{
|
|
var e = em.CreateEntity(typeof(SharedStorageContainer));
|
|
var buf = em.AddBuffer<StorageEntry>(e);
|
|
if (itemId != 0)
|
|
buf.Add(new StorageEntry { ItemId = itemId, Count = count });
|
|
return e;
|
|
}
|
|
|
|
static void MakeRequest(EntityManager em, byte op, ushort itemId, int count)
|
|
{
|
|
var e = em.CreateEntity();
|
|
em.AddComponentData(e, new StorageOpRequest { Op = op, ItemId = itemId, Count = count });
|
|
em.AddComponentData(e, default(ReceiveRpcCommandRequest));
|
|
}
|
|
|
|
[Test]
|
|
public void Withdraw_Decrements_Existing_Row_And_Destroys_Request()
|
|
{
|
|
var (world, group) = MakeWorld("StorageWithdrawWorld");
|
|
using (world)
|
|
{
|
|
var em = world.EntityManager;
|
|
var container = MakeContainer(em, itemId: 1, count: 100);
|
|
MakeRequest(em, StorageOp.Withdraw, itemId: 1, count: 30);
|
|
|
|
group.Update();
|
|
|
|
var buf = em.GetBuffer<StorageEntry>(container);
|
|
Assert.AreEqual(1, buf.Length, "A partial withdraw keeps the row.");
|
|
Assert.AreEqual(70, buf[0].Count, "100 - 30 = 70 must remain.");
|
|
|
|
using var reqQuery = em.CreateEntityQuery(typeof(StorageOpRequest));
|
|
Assert.AreEqual(0, reqQuery.CalculateEntityCount(),
|
|
"The handled request entity must be destroyed by the system's ECB.");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Deposit_Of_New_Item_Appends_A_Row()
|
|
{
|
|
var (world, group) = MakeWorld("StorageDepositWorld");
|
|
using (world)
|
|
{
|
|
var em = world.EntityManager;
|
|
var container = MakeContainer(em, itemId: 1, count: 100);
|
|
MakeRequest(em, StorageOp.Deposit, itemId: 2, count: 20);
|
|
|
|
group.Update();
|
|
|
|
var buf = em.GetBuffer<StorageEntry>(container);
|
|
Assert.AreEqual(2, buf.Length, "Depositing a previously-absent item appends a second row.");
|
|
int item2 = -1;
|
|
for (int i = 0; i < buf.Length; i++)
|
|
if (buf[i].ItemId == 2) item2 = buf[i].Count;
|
|
Assert.AreEqual(20, item2, "The appended row carries the deposited count.");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Withdraw_Of_Full_Stack_Drops_The_Row()
|
|
{
|
|
var (world, group) = MakeWorld("StorageWithdrawZeroWorld");
|
|
using (world)
|
|
{
|
|
var em = world.EntityManager;
|
|
var container = MakeContainer(em, itemId: 1, count: 30);
|
|
MakeRequest(em, StorageOp.Withdraw, itemId: 1, count: 30);
|
|
|
|
group.Update();
|
|
|
|
var buf = em.GetBuffer<StorageEntry>(container);
|
|
Assert.AreEqual(0, buf.Length, "Withdrawing the whole stack drops the row entirely.");
|
|
}
|
|
}
|
|
}
|
|
}
|