feat(entity): added SetAll()
which takes a params list
- added unit test to verify - minor code clean up to get the tests running closes #1
This commit is contained in:
parent
e4c9e82b99
commit
fb0a03e963
9 changed files with 93 additions and 22 deletions
|
@ -10,6 +10,17 @@ namespace MfGames.Gallium;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record Entity
|
public record Entity
|
||||||
{
|
{
|
||||||
|
public Entity()
|
||||||
|
: this(Interlocked.Increment(ref nextId))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private Entity(int id)
|
||||||
|
{
|
||||||
|
this.Id = id;
|
||||||
|
this.Components = ImmutableDictionary.Create<Type, object>();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual bool Equals(Entity? other)
|
public virtual bool Equals(Entity? other)
|
||||||
{
|
{
|
||||||
|
@ -29,10 +40,10 @@ public record Entity
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return this.Id;
|
return this.Id.GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImmutableDictionary<Type, object> Components { get; set; }
|
private ImmutableDictionary<Type, object> Components { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The internal ID to ensure the entities are unique. Since we are not
|
/// The internal ID to ensure the entities are unique. Since we are not
|
||||||
|
@ -42,17 +53,6 @@ public record Entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static int nextId;
|
private static int nextId;
|
||||||
|
|
||||||
public Entity()
|
|
||||||
: this(Interlocked.Increment(ref nextId))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entity(int id)
|
|
||||||
{
|
|
||||||
this.Id = id;
|
|
||||||
this.Components = ImmutableDictionary.Create<Type, object>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether the entity has a specific type of
|
/// Gets a value indicating whether the entity has a specific type of
|
||||||
/// component registered.
|
/// component registered.
|
||||||
|
@ -354,7 +354,43 @@ public record Entity
|
||||||
|
|
||||||
return this with
|
return this with
|
||||||
{
|
{
|
||||||
Components = this.Components.SetItem(typeof(T1), component)
|
Components = this.Components.SetItem(typeof(T1), component),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets zero or more components into an entity in a single call. This does
|
||||||
|
/// not allow for specifying the data type; each item will be added with
|
||||||
|
/// the result of `component.GetType()`.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="components">
|
||||||
|
/// The components to add to the entity. Any null objects
|
||||||
|
/// will be ignored.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// A new Entity with the modified component collection if there is at
|
||||||
|
/// least one component to set, otherwise the same entity.
|
||||||
|
/// </returns>
|
||||||
|
public Entity SetAll(params object?[] components)
|
||||||
|
{
|
||||||
|
if (components.Length == 0)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImmutableDictionary<Type, object> collection = this.Components;
|
||||||
|
|
||||||
|
foreach (object? component in components)
|
||||||
|
{
|
||||||
|
if (component != null)
|
||||||
|
{
|
||||||
|
collection = collection.SetItem(component.GetType(), component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this with
|
||||||
|
{
|
||||||
|
Components = collection,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ using MfGames.Gallium;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
namespace Gallium.Tests;
|
namespace MfGames.Gallium.Tests;
|
||||||
|
|
||||||
public class EntityTests : GalliumTestsBase
|
public class EntityTests : GalliumTestsBase
|
||||||
{
|
{
|
||||||
|
@ -151,6 +151,41 @@ public class EntityTests : GalliumTestsBase
|
||||||
Assert.Equal(0, entity2.Count);
|
Assert.Equal(0, entity2.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SetAllSkipsNull()
|
||||||
|
{
|
||||||
|
var component1 = new TestComponent1();
|
||||||
|
var component2 = new TestComponent2();
|
||||||
|
Entity entity1 = new Entity().SetAll(component1, null);
|
||||||
|
|
||||||
|
Assert.Equal(1, entity1.Count);
|
||||||
|
Assert.True(entity1.Has<TestComponent1>());
|
||||||
|
Assert.False(entity1.Has<TestComponent2>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SetAllWithNothingWorks()
|
||||||
|
{
|
||||||
|
Entity entity1 = new Entity().SetAll();
|
||||||
|
|
||||||
|
Assert.Equal(0, entity1.Count);
|
||||||
|
Assert.False(entity1.Has<TestComponent1>());
|
||||||
|
Assert.False(entity1.Has<TestComponent2>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SetAllWorks()
|
||||||
|
{
|
||||||
|
var component1 = new TestComponent1();
|
||||||
|
var component2 = new TestComponent2();
|
||||||
|
Entity entity1 = new Entity().SetAll(component1, component2);
|
||||||
|
|
||||||
|
Assert.Equal(2, entity1.Count);
|
||||||
|
Assert.True(entity1.Has<TestComponent1>());
|
||||||
|
Assert.True(entity1.Has<TestComponent2>());
|
||||||
|
Assert.False(entity1.Has<TestComponent3a>());
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void SettingComponentsWorks()
|
public void SettingComponentsWorks()
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,7 @@ using MfGames.Gallium;
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Gallium.Tests;
|
namespace MfGames.Gallium.Tests;
|
||||||
|
|
||||||
public class EnumerableEntityTests
|
public class EnumerableEntityTests
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@ using Serilog.Core;
|
||||||
|
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
namespace Gallium.Tests;
|
namespace MfGames.Gallium.Tests;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Common initialization logic for Gallium-based tests including setting
|
/// Common initialization logic for Gallium-based tests including setting
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Gallium.Tests;
|
namespace MfGames.Gallium.Tests;
|
||||||
|
|
||||||
public interface ITestComponent3
|
public interface ITestComponent3
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Gallium.Tests;
|
namespace MfGames.Gallium.Tests;
|
||||||
|
|
||||||
public class TestComponent1
|
public class TestComponent1
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Gallium.Tests;
|
namespace MfGames.Gallium.Tests;
|
||||||
|
|
||||||
public class TestComponent2
|
public class TestComponent2
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Gallium.Tests;
|
namespace MfGames.Gallium.Tests;
|
||||||
|
|
||||||
public class TestComponent3a : ITestComponent3
|
public class TestComponent3a : ITestComponent3
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Gallium.Tests;
|
namespace MfGames.Gallium.Tests;
|
||||||
|
|
||||||
public class TestComponent3b : ITestComponent3
|
public class TestComponent3b : ITestComponent3
|
||||||
{
|
{
|
||||||
|
|
Reference in a new issue