diff --git a/src/Arch.Tests/CommandBufferTest.cs b/src/Arch.Tests/CommandBufferTest.cs index 4bd9ed55..94d7e455 100644 --- a/src/Arch.Tests/CommandBufferTest.cs +++ b/src/Arch.Tests/CommandBufferTest.cs @@ -73,6 +73,116 @@ public void CommandBuffer() World.Destroy(world); } + [Test] + public void CommandBufferCreateMultipleEntities() + { + var world = World.Create(); + + var entities = new List(); + using (var commandBuffer = new CommandBuffer.CommandBuffer(world)) + { + entities.Add(commandBuffer.Create(new ComponentType[] { typeof(Transform) })); + entities.Add(commandBuffer.Create(new ComponentType[] { typeof(Transform) })); + entities.Add(commandBuffer.Create(new ComponentType[] { typeof(Transform) })); + commandBuffer.Playback(); + } + + That(world.Size, Is.EqualTo(entities.Count)); + + World.Destroy(world); + } + + [Test] + public void CommandBufferCreateAndDestroy() + { + var world = World.Create(); + + using (var commandBuffer = new CommandBuffer.CommandBuffer(world)) + { + commandBuffer.Create(new ComponentType[] { typeof(Transform) }); + commandBuffer.Create(new ComponentType[] { typeof(Transform) }); + var e = commandBuffer.Create(new ComponentType[] { typeof(Transform) }); + commandBuffer.Destroy(e); + commandBuffer.Playback(); + } + + That(world.Size, Is.EqualTo(2)); + + var query = new QueryDescription { All = new ComponentType[] { typeof(Transform) } }; + var entities = new Entity[world.CountEntities(query)]; + world.GetEntities(query, entities); + + using (var commandBuffer = new CommandBuffer.CommandBuffer(world)) + { + commandBuffer.Destroy(entities[0]); + commandBuffer.Playback(); + } + + That(world.Size, Is.EqualTo(1)); + + World.Destroy(world); + } + + [Test] + public void CommandBufferModify() + { + var world = World.Create(); + + // Create an entity + using (var commandBuffer = new CommandBuffer.CommandBuffer(world)) + { + commandBuffer.Create(new ComponentType[] { typeof(int) }); + commandBuffer.Playback(); + } + + That(world.Size, Is.EqualTo(1)); + + // Retrieve the entity we just created + var query = new QueryDescription { All = new ComponentType[] { typeof(int) } }; + var entities = new Entity[world.CountEntities(query)]; + world.GetEntities(query, entities); + + // Check that it doesn't yet have anything + Multiple(() => + { + That(world.TryGet(entities[0], out _), Is.False); + That(world.TryGet(entities[0], out _), Is.False); + }); + + // Add to it + using (var commandBuffer = new CommandBuffer.CommandBuffer(world)) + { + commandBuffer.Add(entities[0]); + commandBuffer.Add(entities[0]); + commandBuffer.Playback(); + } + + // Check modification added things + Multiple(() => + { + That(world.TryGet(entities[0], out _), Is.True); + That(world.TryGet(entities[0], out _), Is.True); + }); + + // Remove from it + using (var commandBuffer = new CommandBuffer.CommandBuffer(world)) + { + commandBuffer.Remove(entities[0]); + commandBuffer.Playback(); + } + + // Check modification removed rotation + Multiple(() => + { + That(world.TryGet(entities[0], out _), Is.True); + That(world.TryGet(entities[0], out _), Is.False); + }); + + + + World.Destroy(world); + } + [Test] public void CommandBufferCombined() { diff --git a/src/Arch.Tests/Extensions/ArrayExtensionsTests.cs b/src/Arch.Tests/Extensions/ArrayExtensionsTests.cs new file mode 100644 index 00000000..b1c54a85 --- /dev/null +++ b/src/Arch.Tests/Extensions/ArrayExtensionsTests.cs @@ -0,0 +1,59 @@ +using Arch.Core.Extensions.Internal; + +namespace Arch.Tests.Extensions; + +[TestFixture] +public class ArrayExtensionsTests +{ + [Test] + public void Add_InRange() + { + var arr = new[] { 1, 2, 3 }; + arr.Add(0, 7); + + CollectionAssert.AreEqual(new[] { 7, 2, 3 }, arr); + } + + [Test] + public void Add_OutOfRange() + { + var arr = new[] { 1, 2, 3 }; + arr = arr.Add(3, 7); + + // The array might be any size now. + // All we need to check if that the first 4 elements are correct. + CollectionAssert.AreEqual(new[] { 1, 2, 3, 7 }, arr.Take(4)); + } + + [Test] + public void Add_FarOutOfRange() + { + var arr = new[] { 1, 2, 3 }; + arr = arr.Add(30, 7); + + // The array might be any size now. + // All we need to check if that the first 3 elements are correct and the 30th is 7. + CollectionAssert.AreEqual(new[] { 1, 2, 3 }, arr.Take(3)); + Assert.That(arr[30], Is.EqualTo(7)); + } + + [Test] + public void Add_VeryFarOutOfRange() + { + var arr = new[] { 1, 2, 3 }; + arr = arr.Add(3000, 7); + + // The array might be any size now. + // All we need to check if that the first 3 elements are correct and the 30th is 7. + CollectionAssert.AreEqual(new[] { 1, 2, 3 }, arr.Take(3)); + Assert.That(arr[3000], Is.EqualTo(7)); + } + + [Test] + public void Add_NegativeIndex() + { + var arr = new[] { 1, 2, 3 }; + + Assert.Throws(() => arr.Add(-1, 7)); + } +} diff --git a/src/Arch/CommandBuffer/CommandBuffer.cs b/src/Arch/CommandBuffer/CommandBuffer.cs index 6335bf02..b0e6d6f7 100644 --- a/src/Arch/CommandBuffer/CommandBuffer.cs +++ b/src/Arch/CommandBuffer/CommandBuffer.cs @@ -177,7 +177,7 @@ public Entity Create(ComponentType[] types) { lock (this) { - var entity = new Entity(-Math.Abs(Size - 1), World.Id); + var entity = new Entity(-(Size + 1), World.Id); Register(entity, out _); var command = new CreateCommand(Size - 1, types); @@ -433,15 +433,15 @@ public void Playback() // Reset values. Size = 0; - Entities?.Clear(); - BufferedEntityInfo?.Clear(); - Creates?.Clear(); - Sets?.Clear(); - Adds?.Clear(); - Removes?.Clear(); - Destroys?.Clear(); - _addTypes?.Clear(); - _removeTypes?.Clear(); + Entities.Clear(); + BufferedEntityInfo.Clear(); + Creates.Clear(); + Sets.Clear(); + Adds.Clear(); + Removes.Clear(); + Destroys.Clear(); + _addTypes.Clear(); + _removeTypes.Clear(); } /// @@ -449,15 +449,15 @@ public void Playback() /// public void Dispose() { - Entities?.Dispose(); - BufferedEntityInfo?.Dispose(); - Creates?.Clear(); - Sets?.Clear(); - Adds?.Clear(); - Removes?.Clear(); - Destroys?.Dispose(); - _addTypes?.Dispose(); - _removeTypes?.Dispose(); + Entities.Dispose(); + BufferedEntityInfo.Dispose(); + Creates.Clear(); + Sets.Clear(); + Adds.Clear(); + Removes.Clear(); + Destroys.Dispose(); + _addTypes.Dispose(); + _removeTypes.Dispose(); GC.SuppressFinalize(this); } }