encompass-cs/test/ComponentTest.cs

484 lines
15 KiB
C#
Raw Normal View History

2019-07-17 18:24:21 +00:00
using NUnit.Framework;
using FluentAssertions;
using Encompass;
2020-03-20 22:45:58 +00:00
using System.Runtime.CompilerServices;
2019-07-17 18:24:21 +00:00
namespace Tests
{
public class ComponentTests
{
struct MockComponent
2019-07-17 18:24:21 +00:00
{
public int myInt;
}
struct EntityMessage
2019-07-17 18:24:21 +00:00
{
public Entity entity;
}
2019-11-21 03:01:29 +00:00
static MockComponent gottenMockComponent;
2019-07-17 18:24:21 +00:00
2019-07-19 19:47:17 +00:00
[Receives(typeof(EntityMessage))]
[Reads(typeof(MockComponent))]
2019-07-17 18:24:21 +00:00
class GetMockComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var entityMessage in ReadMessages<EntityMessage>())
2019-07-17 18:24:21 +00:00
{
2019-11-21 03:01:29 +00:00
gottenMockComponent = GetComponent<MockComponent>(entityMessage.entity);
2019-07-17 18:24:21 +00:00
}
}
}
struct AddComponentTestMessage
2019-07-17 18:24:21 +00:00
{
public Entity entity;
public MockComponent mockComponent;
}
2019-07-19 19:47:17 +00:00
[Receives(typeof(AddComponentTestMessage))]
[Reads(typeof(MockComponent))]
2019-07-18 21:02:57 +00:00
class AddComponentTestEngine : Engine
2019-07-17 18:24:21 +00:00
{
public override void Update(double dt)
{
2020-03-22 20:41:55 +00:00
foreach (ref readonly var addComponentTestMessage in ReadMessages<AddComponentTestMessage>())
2019-07-17 18:24:21 +00:00
{
Assert.IsTrue(HasComponent<MockComponent>(addComponentTestMessage.entity));
2020-03-22 19:12:26 +00:00
ref readonly var gottenComponent = ref GetComponent<MockComponent>(addComponentTestMessage.entity);
2020-03-21 01:09:24 +00:00
gottenComponent.Should().BeEquivalentTo(addComponentTestMessage.mockComponent);
2019-07-17 18:24:21 +00:00
}
}
}
[Test]
2020-03-20 22:45:58 +00:00
public unsafe void AddComponent()
2019-07-17 18:24:21 +00:00
{
var worldBuilder = new WorldBuilder();
2019-07-18 21:02:57 +00:00
worldBuilder.AddEngine(new AddComponentTestEngine());
2019-07-17 18:24:21 +00:00
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 3;
worldBuilder.SetComponent(entity, mockComponent);
2019-07-17 18:24:21 +00:00
AddComponentTestMessage addComponentTestMessage;
addComponentTestMessage.entity = entity;
addComponentTestMessage.mockComponent = mockComponent;
worldBuilder.SendMessage(addComponentTestMessage);
2019-07-17 18:24:21 +00:00
var world = worldBuilder.Build();
world.Update(0.01);
2019-12-30 03:08:32 +00:00
world.Update(0.01);
2019-07-17 18:24:21 +00:00
}
[Test]
public void SetMultipleComponentOfSameTypeOnEntity()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ReadMockComponentEngine());
var entity = worldBuilder.CreateEntity();
2020-03-20 22:45:58 +00:00
worldBuilder.SetComponent(entity, new MockComponent { myInt = 20 });
worldBuilder.SetComponent(entity, new MockComponent { myInt = 50 });
worldBuilder.SetComponent(entity, new MockComponent { myInt = 40 });
var world = worldBuilder.Build();
world.Update(0.01);
2019-12-05 22:59:55 +00:00
Assert.That(gottenMockComponent.myInt, Is.EqualTo(40));
}
[Reads(typeof(MockComponent))]
[Writes(typeof(MockComponent))]
class OverwriteEngine : Engine
{
public override void Update(double dt)
{
2020-03-23 02:10:28 +00:00
foreach (ref readonly var entity in ReadEntities<MockComponent>())
{
2020-03-23 02:10:28 +00:00
ref readonly var mockComponent = ref GetComponent<MockComponent>(entity);
SetComponent(entity, new MockComponent { myInt = mockComponent.myInt + 1 });
}
}
}
[Reads(typeof(MockComponent))]
class ReadMockComponentEngine : Engine
{
public override void Update(double dt)
{
2019-11-21 03:01:29 +00:00
gottenMockComponent = ReadComponent<MockComponent>();
}
}
[Test]
public void EngineOverwriteComponent()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new OverwriteEngine());
worldBuilder.AddEngine(new ReadMockComponentEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent { myInt = 420 });
var world = worldBuilder.Build();
world.Update(0.01);
2019-11-21 03:01:29 +00:00
Assert.That(gottenMockComponent.myInt, Is.EqualTo(420));
world.Update(0.01);
Assert.That(gottenMockComponent.myInt, Is.EqualTo(421));
world.Update(0.01);
Assert.That(gottenMockComponent.myInt, Is.EqualTo(422));
}
[Reads(typeof(MockComponent))]
[Writes(typeof(MockComponent))]
class AddAndRemoveComponentEngine : Engine
{
public override void Update(double dt)
{
2020-03-23 02:10:28 +00:00
foreach (ref readonly var entity in ReadEntities<MockComponent>())
{
2020-03-23 02:10:28 +00:00
ref readonly var mockComponent = ref GetComponent<MockComponent>(entity);
SetComponent(entity, mockComponent);
2019-11-21 03:01:29 +00:00
RemoveComponent<MockComponent>(entity);
}
}
}
[Test]
public void AddMultipleComponentSameFrameAsRemove()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddAndRemoveComponentEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent());
var world = worldBuilder.Build();
Assert.DoesNotThrow(() => world.Update(0.01));
}
struct AddMockComponentMessage
2019-07-18 21:02:57 +00:00
{
public Entity entity;
public MockComponent mockComponent;
}
2019-07-19 01:20:38 +00:00
[Sends(typeof(AddMockComponentMessage))]
2019-07-18 21:02:57 +00:00
class EmitMockComponentMessageEngine : Engine
{
private Entity entity;
public EmitMockComponentMessageEngine(Entity entity)
{
this.entity = entity;
}
public override void Update(double dt)
{
MockComponent mockComponent;
mockComponent.myInt = 10;
AddMockComponentMessage addMockComponentMessage;
addMockComponentMessage.entity = entity;
addMockComponentMessage.mockComponent = mockComponent;
SendMessage(addMockComponentMessage);
2019-07-18 21:02:57 +00:00
}
}
2019-12-24 03:04:26 +00:00
[WritesImmediate(typeof(MockComponent))]
2019-07-19 19:47:17 +00:00
[Receives(typeof(AddMockComponentMessage))]
[Writes(typeof(MockComponent))]
2019-07-18 21:02:57 +00:00
class AddMockComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var message in ReadMessages<AddMockComponentMessage>())
2019-07-18 21:02:57 +00:00
{
SetComponent(message.entity, message.mockComponent);
2019-07-18 21:02:57 +00:00
}
}
}
2019-12-24 03:04:26 +00:00
[ReadsImmediate(typeof(MockComponent))]
2019-07-18 21:02:57 +00:00
class HasMockComponentEngine : Engine
{
private Entity entity;
public HasMockComponentEngine(Entity entity)
{
this.entity = entity;
}
public override void Update(double dt)
{
Assert.IsTrue(HasComponent<MockComponent>(entity));
2019-07-18 21:02:57 +00:00
}
}
[Test]
public void AddComponentAndReadSameFrame()
{
var worldBuilder = new WorldBuilder();
var entity = worldBuilder.CreateEntity();
worldBuilder.AddEngine(new EmitMockComponentMessageEngine(entity));
worldBuilder.AddEngine(new AddMockComponentEngine());
worldBuilder.AddEngine(new HasMockComponentEngine(entity));
var world = worldBuilder.Build();
world.Update(0.01);
}
2019-07-17 18:24:21 +00:00
[Test]
public void GetComponent()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new GetMockComponentEngine());
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 3;
2020-03-20 22:45:58 +00:00
worldBuilder.SetComponent(entity, mockComponent);
2019-07-17 18:24:21 +00:00
EntityMessage entityMessage;
entityMessage.entity = entity;
worldBuilder.SendMessage(entityMessage);
2019-07-17 18:24:21 +00:00
var world = worldBuilder.Build();
2019-12-30 03:08:32 +00:00
world.Update(0.01);
2019-07-17 18:24:21 +00:00
world.Update(0.01);
2019-11-21 03:01:29 +00:00
Assert.AreEqual(mockComponent, gottenMockComponent);
2019-07-17 18:24:21 +00:00
}
struct HasComponentTestMessage
2019-07-17 18:24:21 +00:00
{
public Entity entity;
}
2019-07-19 19:47:17 +00:00
[Receives(typeof(HasComponentTestMessage))]
[Reads(typeof(MockComponent))]
2019-07-17 18:24:21 +00:00
class HasComponentTestEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var hasComponentTestEngine in ReadMessages<HasComponentTestMessage>())
2019-07-17 18:24:21 +00:00
{
Assert.IsTrue(HasComponent<MockComponent>(hasComponentTestEngine.entity));
}
}
}
[Test]
public void HasComponent()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new HasComponentTestEngine());
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 3;
worldBuilder.SetComponent(entity, mockComponent);
2019-11-13 21:15:43 +00:00
HasComponentTestMessage hasComponentTestMessage;
hasComponentTestMessage.entity = entity;
worldBuilder.SendMessage(hasComponentTestMessage);
var world = worldBuilder.Build();
world.Update(0.01);
}
static bool hasComponentRuntimeTypeResult;
2019-11-13 21:15:43 +00:00
[Receives(typeof(HasComponentTestMessage))]
[Reads(typeof(MockComponent))]
class HasComponentWithRuntimeTypeEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var hasComponentTestEngine in ReadMessages<HasComponentTestMessage>())
2019-11-13 21:15:43 +00:00
{
hasComponentRuntimeTypeResult = HasComponent(hasComponentTestEngine.entity, typeof(MockComponent));
2019-11-13 21:15:43 +00:00
}
}
}
[Test]
public void HasComponentWithRuntimeType()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new HasComponentWithRuntimeTypeEngine());
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 3;
worldBuilder.SetComponent(entity, mockComponent);
2019-07-17 18:24:21 +00:00
HasComponentTestMessage hasComponentTestMessage;
hasComponentTestMessage.entity = entity;
worldBuilder.SendMessage(hasComponentTestMessage);
2019-07-17 18:24:21 +00:00
var world = worldBuilder.Build();
world.Update(0.01);
Assert.IsTrue(hasComponentRuntimeTypeResult);
}
[Test]
public void HasComponentWithRuntimeTypeFalseWhenNoneHaveBeenCreated()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new HasComponentWithRuntimeTypeEngine());
var entity = worldBuilder.CreateEntity();
HasComponentTestMessage hasComponentTestMessage;
hasComponentTestMessage.entity = entity;
worldBuilder.SendMessage(hasComponentTestMessage);
var world = worldBuilder.Build();
world.Update(0.01);
Assert.IsFalse(hasComponentRuntimeTypeResult);
2019-07-17 18:24:21 +00:00
}
struct RemoveComponentTestMessage
2019-07-17 18:24:21 +00:00
{
public Entity entity;
}
2019-11-21 03:01:29 +00:00
[Reads(typeof(MockComponent))]
2019-07-19 19:47:17 +00:00
[Receives(typeof(RemoveComponentTestMessage))]
[Writes(typeof(MockComponent))]
2019-07-17 18:24:21 +00:00
class RemoveComponentTestEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var removeComponentMessage in ReadMessages<RemoveComponentTestMessage>())
2019-07-17 18:24:21 +00:00
{
2019-11-21 03:01:29 +00:00
RemoveComponent<MockComponent>(removeComponentMessage.entity);
}
}
}
2019-07-19 19:47:17 +00:00
[Receives(typeof(RemoveComponentTestMessage))]
2019-07-19 01:20:38 +00:00
[Sends(typeof(CheckHasMockComponentMessage))]
class DoRemoveCheckEngine : Engine
{
private Entity entity;
2019-07-17 18:24:21 +00:00
public DoRemoveCheckEngine(Entity entity)
{
this.entity = entity;
}
public override void Update(double dt)
{
if (SomeMessage<RemoveComponentTestMessage>())
{
CheckHasMockComponentMessage checkHasMockComponentMessage;
checkHasMockComponentMessage.entity = entity;
checkHasMockComponentMessage.shouldHaveComponent = true;
SendMessage(checkHasMockComponentMessage);
}
else
{
CheckHasMockComponentMessage checkHasMockComponentMessage;
checkHasMockComponentMessage.entity = entity;
checkHasMockComponentMessage.shouldHaveComponent = false;
SendMessage(checkHasMockComponentMessage);
2019-07-17 18:24:21 +00:00
}
}
}
2019-12-06 03:55:17 +00:00
static bool hasComponentResult;
2019-07-20 00:50:13 +00:00
[Receives(typeof(CheckHasMockComponentMessage))]
[Reads(typeof(MockComponent))]
class CheckHasMockComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var checkHasMockComponentMessage in ReadMessages<CheckHasMockComponentMessage>())
2019-07-20 00:50:13 +00:00
{
2019-12-06 03:55:17 +00:00
hasComponentResult = HasComponent<MockComponent>(checkHasMockComponentMessage.entity);
2019-07-20 00:50:13 +00:00
}
}
}
2019-07-17 18:24:21 +00:00
[Test]
2019-12-06 03:55:17 +00:00
public void RemovedComponentShouldStillExistOnSameFrame()
2019-07-17 18:24:21 +00:00
{
var worldBuilder = new WorldBuilder();
var entity = worldBuilder.CreateEntity();
worldBuilder.AddEngine(new RemoveComponentTestEngine());
worldBuilder.AddEngine(new CheckHasMockComponentEngine());
worldBuilder.AddEngine(new DoRemoveCheckEngine(entity));
2019-07-17 18:24:21 +00:00
MockComponent mockComponent;
mockComponent.myInt = 3;
2019-11-21 03:01:29 +00:00
worldBuilder.SetComponent(entity, mockComponent);
2019-07-17 18:24:21 +00:00
RemoveComponentTestMessage removeComponentMessage;
removeComponentMessage.entity = entity;
worldBuilder.SendMessage(removeComponentMessage);
2019-07-17 18:24:21 +00:00
var world = worldBuilder.Build();
world.Update(0.01f);
2019-12-06 03:55:17 +00:00
hasComponentResult.Should().BeTrue();
world.Update(0.01f);
hasComponentResult.Should().BeFalse();
2019-07-17 18:24:21 +00:00
}
struct CheckHasMockComponentMessage
{
public Entity entity;
public bool shouldHaveComponent;
}
2019-07-19 19:47:17 +00:00
[Receives(typeof(CheckHasMockComponentMessage))]
2019-12-24 03:04:26 +00:00
[ReadsImmediate(typeof(MockComponent))]
class CheckHasImmediateMockComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var checkHasMockComponentMessage in ReadMessages<CheckHasMockComponentMessage>())
{
Assert.IsTrue(HasComponent<MockComponent>(checkHasMockComponentMessage.entity));
2019-07-17 18:24:21 +00:00
}
}
}
}
}