Show More
Commit Description:
Add timers for Simulation and various engines...
Commit Description:
Add timers for Simulation and various engines Starting to add additional timers for different stages of the process of updating in order to get more insight into what is slowing it down. The update takes 9ms, which is much longer than it used to. Engine-specific timers are coming later.
Show/Diff file:
Action:
encompass-cs/test/ComponentTest.cs
485 lines | 15.4 KiB | text/x-csharp | CSharpLexer
using NUnit.Framework;
using FluentAssertions;
using Encompass;
using System.Runtime.CompilerServices;
namespace Tests
{
public class ComponentTests
{
struct MockComponent : IComponent
{
public int myInt;
}
struct EntityMessage : IMessage
{
public Entity entity;
}
static MockComponent gottenMockComponent;
[Receives(typeof(EntityMessage))]
[Reads(typeof(MockComponent))]
class GetMockComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var entityMessage in ReadMessages<EntityMessage>())
{
gottenMockComponent = GetComponent<MockComponent>(entityMessage.entity);
}
}
}
struct AddComponentTestMessage : IMessage
{
public Entity entity;
public MockComponent mockComponent;
}
[Receives(typeof(AddComponentTestMessage))]
[Reads(typeof(MockComponent))]
class AddComponentTestEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var addComponentTestMessage in ReadMessages<AddComponentTestMessage>())
{
Assert.IsTrue(HasComponent<MockComponent>(addComponentTestMessage.entity));
ref readonly var gottenComponent = ref GetComponent<MockComponent>(addComponentTestMessage.entity);
gottenComponent.Should().BeEquivalentTo(addComponentTestMessage.mockComponent);
}
}
}
[Test]
public unsafe void AddComponent()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddComponentTestEngine());
var entity = worldBuilder.CreateEntity();
const string MyString = "hello";
MockComponent mockComponent;
mockComponent.myInt = 3;
worldBuilder.SetComponent(entity, mockComponent);
AddComponentTestMessage addComponentTestMessage;
addComponentTestMessage.entity = entity;
addComponentTestMessage.mockComponent = mockComponent;
worldBuilder.SendMessage(addComponentTestMessage);
var world = worldBuilder.Build();
world.Update(0.01);
world.Update(0.01);
}
[Test]
public void SetMultipleComponentOfSameTypeOnEntity()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ReadMockComponentEngine());
var entity = worldBuilder.CreateEntity();
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);
Assert.That(gottenMockComponent.myInt, Is.EqualTo(40));
}
[Reads(typeof(MockComponent))]
[Writes(typeof(MockComponent))]
class OverwriteEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var entity in ReadEntities<MockComponent>())
{
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)
{
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);
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)
{
foreach (ref readonly var entity in ReadEntities<MockComponent>())
{
ref readonly var mockComponent = ref GetComponent<MockComponent>(entity);
SetComponent(entity, mockComponent);
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 : IMessage
{
public Entity entity;
public MockComponent mockComponent;
}
[Sends(typeof(AddMockComponentMessage))]
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);
}
}
[WritesImmediate(typeof(MockComponent))]
[Receives(typeof(AddMockComponentMessage))]
[Writes(typeof(MockComponent))]
class AddMockComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var message in ReadMessages<AddMockComponentMessage>())
{
SetComponent(message.entity, message.mockComponent);
}
}
}
[ReadsImmediate(typeof(MockComponent))]
class HasMockComponentEngine : Engine
{
private Entity entity;
public HasMockComponentEngine(Entity entity)
{
this.entity = entity;
}
public override void Update(double dt)
{
Assert.IsTrue(HasComponent<MockComponent>(entity));
}
}
[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);
}
[Test]
public void GetComponent()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new GetMockComponentEngine());
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 3;
worldBuilder.SetComponent(entity, mockComponent);
EntityMessage entityMessage;
entityMessage.entity = entity;
worldBuilder.SendMessage(entityMessage);
var world = worldBuilder.Build();
world.Update(0.01);
world.Update(0.01);
Assert.AreEqual(mockComponent, gottenMockComponent);
}
struct HasComponentTestMessage : IMessage
{
public Entity entity;
}
[Receives(typeof(HasComponentTestMessage))]
[Reads(typeof(MockComponent))]
class HasComponentTestEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var hasComponentTestEngine in ReadMessages<HasComponentTestMessage>())
{
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);
HasComponentTestMessage hasComponentTestMessage;
hasComponentTestMessage.entity = entity;
worldBuilder.SendMessage(hasComponentTestMessage);
var world = worldBuilder.Build();
world.Update(0.01);
}
static bool hasComponentRuntimeTypeResult;
[Receives(typeof(HasComponentTestMessage))]
[Reads(typeof(MockComponent))]
class HasComponentWithRuntimeTypeEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var hasComponentTestEngine in ReadMessages<HasComponentTestMessage>())
{
hasComponentRuntimeTypeResult = HasComponent(hasComponentTestEngine.entity, typeof(MockComponent));
}
}
}
[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);
HasComponentTestMessage hasComponentTestMessage;
hasComponentTestMessage.entity = entity;
worldBuilder.SendMessage(hasComponentTestMessage);
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);
}
struct RemoveComponentTestMessage : IMessage
{
public Entity entity;
}
[Reads(typeof(MockComponent))]
[Receives(typeof(RemoveComponentTestMessage))]
[Writes(typeof(MockComponent))]
class RemoveComponentTestEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var removeComponentMessage in ReadMessages<RemoveComponentTestMessage>())
{
RemoveComponent<MockComponent>(removeComponentMessage.entity);
}
}
}
[Receives(typeof(RemoveComponentTestMessage))]
[Sends(typeof(CheckHasMockComponentMessage))]
class DoRemoveCheckEngine : Engine
{
private Entity entity;
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);
}
}
}
static bool hasComponentResult;
[Receives(typeof(CheckHasMockComponentMessage))]
[Reads(typeof(MockComponent))]
class CheckHasMockComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (ref readonly var checkHasMockComponentMessage in ReadMessages<CheckHasMockComponentMessage>())
{
hasComponentResult = HasComponent<MockComponent>(checkHasMockComponentMessage.entity);
}
}
}
[Test]
public void RemovedComponentShouldStillExistOnSameFrame()
{
var worldBuilder = new WorldBuilder();
var entity = worldBuilder.CreateEntity();
worldBuilder.AddEngine(new RemoveComponentTestEngine());
worldBuilder.AddEngine(new CheckHasMockComponentEngine());
worldBuilder.AddEngine(new DoRemoveCheckEngine(entity));
MockComponent mockComponent;
mockComponent.myInt = 3;
worldBuilder.SetComponent(entity, mockComponent);
RemoveComponentTestMessage removeComponentMessage;
removeComponentMessage.entity = entity;
worldBuilder.SendMessage(removeComponentMessage);
var world = worldBuilder.Build();
world.Update(0.01f);
hasComponentResult.Should().BeTrue();
world.Update(0.01f);
hasComponentResult.Should().BeFalse();
}
struct CheckHasMockComponentMessage : IMessage
{
public Entity entity;
public bool shouldHaveComponent;
}
[Receives(typeof(CheckHasMockComponentMessage))]
[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));
}
}
}
}
}