demo2
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
#nullable enable
|
||||
|
||||
using System.Diagnostics;
|
||||
using Demo2.Domain;
|
||||
using Demo2.ECS;
|
||||
using Demo2.Runtime;
|
||||
using NUnit.Framework;
|
||||
using Unity.Collections;
|
||||
using Unity.Entities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Demo2.Tests
|
||||
{
|
||||
public sealed class Demo2EcsTests
|
||||
{
|
||||
[Test]
|
||||
public void SameSeedAndCommands_RemainIdenticalForTenThousandTicks()
|
||||
{
|
||||
using var left = new Demo2EcsWorld(20260817, Demo2BuiltInContent.BuildRules());
|
||||
using var right = new Demo2EcsWorld(20260817, Demo2BuiltInContent.BuildRules());
|
||||
left.SetPhase(Demo2Phase.Production);
|
||||
right.SetPhase(Demo2Phase.Production);
|
||||
|
||||
for (var tick = 0; tick < 10_000; tick++)
|
||||
{
|
||||
left.Tick();
|
||||
right.Tick();
|
||||
}
|
||||
|
||||
var leftState = left.EntityManager.GetComponentData<Demo2SimulationState>(left.Singleton);
|
||||
var rightState = right.EntityManager.GetComponentData<Demo2SimulationState>(right.Singleton);
|
||||
Assert.That(leftState.Tick, Is.EqualTo(10_000));
|
||||
Assert.That(leftState.StateHash, Is.EqualTo(rightState.StateHash));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SnapshotRestore_ContinuesWithTheSameHash()
|
||||
{
|
||||
using var source = new Demo2EcsWorld(42, Demo2BuiltInContent.BuildRules());
|
||||
source.SetPhase(Demo2Phase.Production);
|
||||
for (var tick = 0; tick < 500; tick++) source.Tick();
|
||||
var snapshot = source.CaptureSnapshot(new[] { "production.dense-ammo" });
|
||||
|
||||
using var restored = new Demo2EcsWorld(999, Demo2BuiltInContent.BuildRules());
|
||||
restored.RestoreSnapshot(snapshot);
|
||||
for (var tick = 0; tick < 200; tick++)
|
||||
{
|
||||
source.Tick();
|
||||
restored.Tick();
|
||||
}
|
||||
|
||||
var sourceState = source.EntityManager.GetComponentData<Demo2SimulationState>(source.Singleton);
|
||||
var restoredState = restored.EntityManager.GetComponentData<Demo2SimulationState>(restored.Singleton);
|
||||
Assert.That(restoredState.StateHash, Is.EqualTo(sourceState.StateHash));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildCommands_AreIdempotentAndRemovalRefundsBeforeEntityDestruction()
|
||||
{
|
||||
using var service = new Demo2GameService();
|
||||
service.StartNewGame(17);
|
||||
var command = new Demo2BuildCommand
|
||||
{
|
||||
Sequence = 1,
|
||||
IdempotencyToken = "test-place",
|
||||
PlayerId = "test",
|
||||
Kind = Demo2MachineKind.Conveyor,
|
||||
X = 1,
|
||||
Y = 1
|
||||
};
|
||||
|
||||
var accepted = service.SubmitBuild(command);
|
||||
var duplicate = service.SubmitBuild(command);
|
||||
var removed = service.BuildLocal(Demo2MachineKind.Conveyor, 1, 1, remove: true);
|
||||
|
||||
Assert.That(accepted.Accepted, Is.True);
|
||||
Assert.That(duplicate.Accepted && duplicate.Duplicate, Is.True);
|
||||
Assert.That(removed.Accepted, Is.True);
|
||||
Assert.That(removed.Refund, Is.EqualTo(5));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MultipleTurrets_LoadWithoutSingletonExceptions()
|
||||
{
|
||||
using var world = new Demo2EcsWorld(31);
|
||||
var manager = world.EntityManager;
|
||||
var state = manager.GetComponentData<Demo2SimulationState>(world.Singleton);
|
||||
var turret = Demo2EcsFactory.CreateMachine(manager, ++state.NextStableId, Demo2MachineKind.Turret, 22, 10, 0, 0);
|
||||
manager.AddComponentData(turret, new Demo2TurretAmmo());
|
||||
Demo2EcsFactory.CreateMaterial(manager, ++state.NextStableId, Demo2MaterialKind.Ammo, 0, 19, 0, 9);
|
||||
manager.SetComponentData(world.Singleton, state);
|
||||
world.SetPhase(Demo2Phase.Production);
|
||||
|
||||
world.Tick();
|
||||
|
||||
var query = manager.CreateEntityQuery(typeof(Demo2TurretAmmo));
|
||||
using var ammo = query.ToComponentDataArray<Demo2TurretAmmo>(Allocator.Temp);
|
||||
long total = 0;
|
||||
for (var i = 0; i < ammo.Length; i++) total += ammo[i].Value;
|
||||
Assert.That(total, Is.EqualTo(9));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Category("Demo2Performance")]
|
||||
public void StressTick_HandlesTenThousandItemsAndOneThousandMachines()
|
||||
{
|
||||
using var world = new Demo2EcsWorld(77);
|
||||
var manager = world.EntityManager;
|
||||
var state = manager.GetComponentData<Demo2SimulationState>(world.Singleton);
|
||||
for (var i = 0; i < 1_000; i++)
|
||||
Demo2EcsFactory.CreateMachine(manager, ++state.NextStableId, Demo2MachineKind.Conveyor, i % Demo2Protocol.GridWidth, (i / Demo2Protocol.GridWidth) % 10, 0, 0);
|
||||
for (var i = 0; i < 10_000; i++)
|
||||
Demo2EcsFactory.CreateMaterial(manager, ++state.NextStableId, Demo2MaterialKind.IronOre, i % Demo2Protocol.GridWidth, 19, 0, 1);
|
||||
manager.SetComponentData(world.Singleton, state);
|
||||
world.SetPhase(Demo2Phase.Production);
|
||||
var before = System.GC.GetAllocatedBytesForCurrentThread();
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
|
||||
world.Tick();
|
||||
|
||||
stopwatch.Stop();
|
||||
var allocated = System.GC.GetAllocatedBytesForCurrentThread() - before;
|
||||
using var entities = manager.GetAllEntities(Allocator.Temp);
|
||||
UnityEngine.Debug.Log($"[Demo2 Benchmark] entities={entities.Length} tickMs={stopwatch.Elapsed.TotalMilliseconds:0.00} managedBytes={allocated}");
|
||||
Assert.That(entities.Length, Is.GreaterThanOrEqualTo(11_000));
|
||||
Assert.That(stopwatch.ElapsedMilliseconds, Is.LessThan(10_000));
|
||||
Assert.That(allocated, Is.LessThanOrEqualTo(4096));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user