Skip to content

Commit

Permalink
CommandBuffer Tests And Fixes (#160)
Browse files Browse the repository at this point in the history
* - Added some more tests covering the `CommandBuffer`. Fixed a bug in `Create` method, sometimes assigning duplicate IDs.
 - Removed all conditional access in `Playback` and `Dispose`, those things are never null.
 - Added ArrayExtensions tests.

* Simplified ID generation
  • Loading branch information
martindevans authored Oct 27, 2023
1 parent 2e37009 commit c7f59a9
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 19 deletions.
110 changes: 110 additions & 0 deletions src/Arch.Tests/CommandBufferTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,116 @@ public void CommandBuffer()
World.Destroy(world);
}

[Test]
public void CommandBufferCreateMultipleEntities()
{
var world = World.Create();

var entities = new List<Entity>();
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<Transform>(entities[0], out _), Is.False);
That(world.TryGet<Rotation>(entities[0], out _), Is.False);
});

// Add to it
using (var commandBuffer = new CommandBuffer.CommandBuffer(world))
{
commandBuffer.Add<Transform>(entities[0]);
commandBuffer.Add<Rotation>(entities[0]);
commandBuffer.Playback();
}

// Check modification added things
Multiple(() =>
{
That(world.TryGet<Transform>(entities[0], out _), Is.True);
That(world.TryGet<Rotation>(entities[0], out _), Is.True);
});

// Remove from it
using (var commandBuffer = new CommandBuffer.CommandBuffer(world))
{
commandBuffer.Remove<Rotation>(entities[0]);
commandBuffer.Playback();
}

// Check modification removed rotation
Multiple(() =>
{
That(world.TryGet<Transform>(entities[0], out _), Is.True);
That(world.TryGet<Rotation>(entities[0], out _), Is.False);
});



World.Destroy(world);
}

[Test]
public void CommandBufferCombined()
{
Expand Down
59 changes: 59 additions & 0 deletions src/Arch.Tests/Extensions/ArrayExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -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<ArgumentOutOfRangeException>(() => arr.Add(-1, 7));
}
}
38 changes: 19 additions & 19 deletions src/Arch/CommandBuffer/CommandBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -433,31 +433,31 @@ 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();
}

/// <summary>
/// Disposes the <see cref="CommandBuffer"/>.
/// </summary>
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);
}
}

0 comments on commit c7f59a9

Please sign in to comment.