encompass-cs/test/EngineTest.cs

1045 lines
32 KiB
C#
Raw Normal View History

2019-06-15 00:51:06 +00:00
using NUnit.Framework;
using FluentAssertions;
2019-06-15 00:51:06 +00:00
using Encompass;
2019-06-15 01:13:24 +00:00
using System;
using System.Linq;
using System.Collections.Generic;
using Encompass.Exceptions;
2019-06-15 00:51:06 +00:00
2019-06-15 19:32:56 +00:00
namespace Tests
{
2019-07-17 18:24:21 +00:00
struct MockComponent : IComponent
{
2019-07-17 18:24:21 +00:00
public int myInt;
public string myString;
}
2019-06-15 00:51:06 +00:00
public class EngineTest
{
static List<ValueTuple<Guid, MockComponent>> resultComponents;
2019-06-15 18:40:42 +00:00
static MockComponent resultComponent;
2019-06-15 00:51:06 +00:00
2019-08-20 02:05:18 +00:00
static List<MockMessage> resultMessages = new List<MockMessage>();
2019-06-16 01:55:35 +00:00
2019-07-18 21:02:57 +00:00
[Reads(typeof(MockComponent))]
2019-06-15 01:13:24 +00:00
public class ReadComponentsTestEngine : Engine
2019-06-15 00:51:06 +00:00
{
public override void Update(double dt)
2019-06-15 00:51:06 +00:00
{
resultComponents = ReadComponents<MockComponent>().ToList();
2019-06-15 00:51:06 +00:00
}
}
2019-07-18 01:53:31 +00:00
2019-07-18 21:02:57 +00:00
[Reads(typeof(MockComponent))]
2019-06-15 01:13:24 +00:00
public class ReadComponentTestEngine : Engine
{
public override void Update(double dt)
2019-06-15 01:13:24 +00:00
{
resultComponent = ReadComponent<MockComponent>().Item2;
2019-06-15 01:13:24 +00:00
}
}
2019-06-15 00:51:06 +00:00
[Test]
public void ReadComponents()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ReadComponentsTestEngine());
2019-06-15 00:51:06 +00:00
var entity = worldBuilder.CreateEntity();
var entityB = worldBuilder.CreateEntity();
2019-06-15 00:51:06 +00:00
MockComponent mockComponent;
mockComponent.myInt = 0;
mockComponent.myString = "hello";
MockComponent mockComponentB;
mockComponentB.myInt = 1;
mockComponentB.myString = "howdy";
var componentAID = worldBuilder.SetComponent(entity, mockComponent);
var componentBID = worldBuilder.SetComponent(entityB, mockComponentB);
2019-06-15 00:51:06 +00:00
var world = worldBuilder.Build();
world.Update(0.01f);
var resultComponentValues = resultComponents.Select((kv) => kv.Item2);
resultComponentValues.Should().Contain(mockComponent);
resultComponentValues.Should().Contain(mockComponentB);
2019-06-15 00:51:06 +00:00
}
2019-06-15 01:13:24 +00:00
[Test]
public void ReadComponent()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ReadComponentTestEngine());
2019-06-15 01:13:24 +00:00
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 0;
mockComponent.myString = "hello";
worldBuilder.SetComponent(entity, mockComponent);
2019-06-15 01:13:24 +00:00
var world = worldBuilder.Build();
world.Update(0.01f);
2019-06-15 18:40:42 +00:00
Assert.AreEqual(mockComponent, resultComponent);
2019-06-15 01:13:24 +00:00
}
[Test]
public void ReadComponentWhenMultipleComponents()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ReadComponentTestEngine());
2019-06-15 01:13:24 +00:00
var entity = worldBuilder.CreateEntity();
var entityB = worldBuilder.CreateEntity();
2019-06-15 01:13:24 +00:00
MockComponent mockComponent;
mockComponent.myInt = 0;
mockComponent.myString = "hello";
MockComponent mockComponentB;
mockComponentB.myInt = 1;
mockComponentB.myString = "howdy";
worldBuilder.SetComponent(entity, mockComponent);
worldBuilder.SetComponent(entityB, mockComponentB);
2019-06-15 01:13:24 +00:00
var world = worldBuilder.Build();
2019-08-01 23:24:57 +00:00
world.Update(0.01);
Assert.That(resultComponent, Is.EqualTo(mockComponent).Or.EqualTo(mockComponentB));
2019-06-15 01:13:24 +00:00
}
2019-06-15 07:39:08 +00:00
2019-07-18 21:02:57 +00:00
[Reads(typeof(MockComponent))]
[Writes(typeof(MockComponent))]
2019-06-15 07:39:08 +00:00
public class UpdateComponentTestEngine : Engine
{
public override void Update(double dt)
2019-06-15 07:39:08 +00:00
{
(var componentID, var component) = ReadComponent<MockComponent>();
component.myInt = 420;
component.myString = "blaze it";
SetComponent(GetEntityByComponentID<MockComponent>(componentID), component);
2019-06-15 07:39:08 +00:00
}
}
2019-07-18 01:53:31 +00:00
// this test needs to be improved...
2019-06-15 07:39:08 +00:00
[Test]
public void UpdateComponent()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new UpdateComponentTestEngine());
2019-07-18 01:53:31 +00:00
worldBuilder.AddEngine(new ReadComponentTestEngine());
2019-06-15 07:39:08 +00:00
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 0;
mockComponent.myString = "hello";
worldBuilder.SetComponent(entity, mockComponent);
2019-06-15 07:39:08 +00:00
var world = worldBuilder.Build();
2019-07-18 01:53:31 +00:00
world.Update(0.01);
world.Update(0.01);
2019-06-15 07:39:08 +00:00
2019-06-15 18:40:42 +00:00
Assert.AreEqual(420, resultComponent.myInt);
Assert.AreEqual("blaze it", resultComponent.myString);
2019-06-15 07:39:08 +00:00
}
2019-07-18 21:02:57 +00:00
[Reads(typeof(MockComponent))]
2019-06-15 07:39:08 +00:00
public class UndeclaredUpdateComponentTestEngine : Engine
{
public override void Update(double dt)
2019-06-15 07:39:08 +00:00
{
2019-07-18 21:02:57 +00:00
(var componentID, var component) = ReadComponent<MockComponent>();
component.myInt = 420;
component.myString = "blaze it";
SetComponent(componentID, component);
component = ReadComponent<MockComponent>().Item2;
2019-06-15 07:39:08 +00:00
}
}
[Test]
public void UpdateUndeclaredComponent()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new UndeclaredUpdateComponentTestEngine());
2019-06-15 07:39:08 +00:00
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 0;
mockComponent.myString = "hello";
worldBuilder.SetComponent(entity, mockComponent);
2019-06-15 07:39:08 +00:00
var world = worldBuilder.Build();
var ex = Assert.Throws<IllegalWriteException>(() => world.Update(0.01f));
2019-07-19 23:15:48 +00:00
Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredUpdateComponentTestEngine tried to update undeclared Component MockComponent"));
2019-06-15 07:39:08 +00:00
}
2019-06-16 01:55:35 +00:00
struct MockMessage : IMessage
{
public string myString;
}
2019-07-19 01:20:38 +00:00
[Sends(typeof(MockMessage))]
2019-06-16 01:55:35 +00:00
public class MessageEmitEngine : Engine
{
public override void Update(double dt)
2019-06-16 01:55:35 +00:00
{
MockMessage message;
message.myString = "howdy";
this.SendMessage(message);
2019-06-16 01:55:35 +00:00
}
}
2019-07-19 19:47:17 +00:00
[Receives(typeof(MockMessage))]
2019-06-16 01:55:35 +00:00
public class MessageReadEngine : Engine
{
public override void Update(double dt)
2019-06-16 01:55:35 +00:00
{
2019-06-17 01:03:57 +00:00
resultMessages = this.ReadMessages<MockMessage>().ToList();
2019-06-16 01:55:35 +00:00
}
}
[Test]
public void EmitAndReadMessage()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new MessageEmitEngine());
worldBuilder.AddEngine(new MessageReadEngine());
2019-06-16 01:55:35 +00:00
var world = worldBuilder.Build();
world.Update(0.01f);
Assert.AreEqual(resultMessages.First().myString, "howdy");
}
public class UndeclaredMessageEmitEngine : Engine
{
public override void Update(double dt)
2019-06-16 01:55:35 +00:00
{
MockMessage message;
message.myString = "howdy";
this.SendMessage(message);
2019-06-16 01:55:35 +00:00
}
}
2019-06-22 00:23:52 +00:00
static IEnumerable<MockMessage> emptyReadMessagesResult;
2019-07-19 19:47:17 +00:00
[Receives(typeof(MockMessage))]
2019-06-22 00:23:52 +00:00
class ReadMessagesWhenNoneExistEngine : Engine
{
2019-06-24 19:40:40 +00:00
public override void Update(double dt)
2019-06-22 00:23:52 +00:00
{
emptyReadMessagesResult = ReadMessages<MockMessage>();
}
}
[Test]
public void ReadMessagesWhenNoneHaveBeenEmitted()
{
var worldBuilder = new WorldBuilder();
2019-06-24 19:40:40 +00:00
worldBuilder.AddEngine(new ReadMessagesWhenNoneExistEngine());
2019-06-22 00:23:52 +00:00
var world = worldBuilder.Build();
world.Update(0.01f);
emptyReadMessagesResult.Should().BeEmpty();
}
2019-06-16 01:55:35 +00:00
[Test]
public void EmitUndeclaredMessage()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new UndeclaredMessageEmitEngine());
2019-06-16 01:55:35 +00:00
var world = worldBuilder.Build();
2019-07-19 19:47:17 +00:00
var ex = Assert.Throws<IllegalSendException>(() => world.Update(0.01f));
2019-07-19 23:15:48 +00:00
Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredMessageEmitEngine tried to send undeclared Message MockMessage"));
2019-06-16 01:55:35 +00:00
}
2019-06-17 01:11:35 +00:00
static bool someTest;
2019-07-19 01:20:38 +00:00
[Sends(typeof(MockMessage))]
2019-06-17 01:11:35 +00:00
class EmitMockMessageEngine : Engine
{
public override void Update(double dt)
2019-06-17 01:11:35 +00:00
{
MockMessage message;
message.myString = "howdy";
this.SendMessage(message);
2019-06-17 01:11:35 +00:00
}
}
2019-07-19 19:47:17 +00:00
[Receives(typeof(MockMessage))]
class SomeMessageTestEngine : Engine
2019-06-17 01:11:35 +00:00
{
public override void Update(double dt)
2019-06-17 01:11:35 +00:00
{
someTest = this.SomeMessage<MockMessage>();
2019-06-17 01:11:35 +00:00
}
}
[Test]
public void SomeMessage()
2019-06-17 01:11:35 +00:00
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new EmitMockMessageEngine());
worldBuilder.AddEngine(new SomeMessageTestEngine());
2019-06-17 01:11:35 +00:00
var world = worldBuilder.Build();
world.Update(0.01f);
Assert.That(someTest, Is.True);
}
2019-06-17 01:16:45 +00:00
class UndeclaredSomeMessageEngine : Engine
2019-06-17 01:16:45 +00:00
{
public override void Update(double dt)
2019-06-17 01:16:45 +00:00
{
someTest = this.SomeMessage<MockMessage>();
2019-06-17 01:16:45 +00:00
}
}
[Test]
public void UndeclaredSomeMessage()
2019-06-17 01:16:45 +00:00
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new EmitMockMessageEngine());
worldBuilder.AddEngine(new UndeclaredSomeMessageEngine());
2019-06-17 01:16:45 +00:00
var world = worldBuilder.Build();
Assert.Throws<IllegalReadException>(() => world.Update(0.01f));
2019-06-17 01:16:45 +00:00
}
2019-06-17 19:12:07 +00:00
class SomeComponentTestEngine : Engine
{
public override void Update(double dt)
{
Assert.IsTrue(SomeComponent<MockComponent>());
}
}
[Test]
public void SomeComponent()
{
var worldBuilder = new WorldBuilder();
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent());
var world = worldBuilder.Build();
world.Update(0.01);
}
static ValueTuple<Guid, MockComponent> pairA;
static ValueTuple<Guid, MockComponent> pairB;
2019-06-17 19:12:07 +00:00
2019-07-18 21:02:57 +00:00
[Reads(typeof(MockComponent))]
2019-06-17 19:12:07 +00:00
class SameValueComponentReadEngine : Engine
{
public override void Update(double dt)
2019-06-17 19:12:07 +00:00
{
var components = ReadComponents<MockComponent>();
2019-06-17 19:12:07 +00:00
pairA = components.First();
pairB = components.Last();
}
}
// Tests that components with identical values should be distinguishable by ID
[Test]
public void SameValueComponents()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new SameValueComponentReadEngine());
2019-06-17 19:12:07 +00:00
MockComponent componentA;
componentA.myInt = 20;
componentA.myString = "hello";
MockComponent componentB;
componentB.myInt = 20;
componentB.myString = "hello";
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, componentA);
var entityB = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entityB, componentB);
2019-06-17 19:12:07 +00:00
var world = worldBuilder.Build();
world.Update(0.01f);
Assert.That(pairA, Is.Not.EqualTo(pairB));
Assert.That(pairA.Item2, Is.EqualTo(pairB.Item2));
2019-06-17 19:12:07 +00:00
}
static IEnumerable<ValueTuple<Guid, MockComponent>> emptyComponentReadResult;
2019-06-17 19:12:07 +00:00
2019-07-18 21:02:57 +00:00
[Reads(typeof(MockComponent))]
2019-06-17 19:12:07 +00:00
class ReadEmptyMockComponentsEngine : Engine
{
public override void Update(double dt)
2019-06-17 19:12:07 +00:00
{
emptyComponentReadResult = ReadComponents<MockComponent>();
2019-06-17 19:12:07 +00:00
}
}
[Test]
public void ReadComponentsOfTypeWhereNoneExist()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ReadEmptyMockComponentsEngine());
2019-06-17 19:12:07 +00:00
var world = worldBuilder.Build();
world.Update(0.01f);
Assert.That(emptyComponentReadResult, Is.Empty);
}
2019-06-20 03:37:46 +00:00
struct DestroyerComponent : IComponent { }
2019-07-18 21:02:57 +00:00
[Reads(typeof(DestroyerComponent))]
2019-06-20 03:37:46 +00:00
class DestroyerEngine : Engine
{
public override void Update(double dt)
2019-06-20 03:37:46 +00:00
{
foreach (var componentPair in ReadComponents<DestroyerComponent>())
2019-06-20 03:37:46 +00:00
{
var componentID = componentPair.Item1;
var entityID = GetEntityIDByComponentID<DestroyerComponent>(componentID);
2019-06-20 03:37:46 +00:00
Destroy(entityID);
}
}
}
static List<(Guid, MockComponent)> results;
2019-07-18 21:02:57 +00:00
[Reads(typeof(MockComponent))]
2019-06-20 03:37:46 +00:00
class ReaderEngine : Engine
{
public override void Update(double dt)
2019-06-20 03:37:46 +00:00
{
results = ReadComponents<MockComponent>().ToList();
2019-06-20 03:37:46 +00:00
}
}
[Test]
public void DestroyEntity()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new DestroyerEngine());
worldBuilder.AddEngine(new ReaderEngine());
2019-06-20 03:37:46 +00:00
var entity = worldBuilder.CreateEntity();
var entityB = worldBuilder.CreateEntity();
var entityC = worldBuilder.CreateEntity();
2019-06-20 03:37:46 +00:00
DestroyerComponent destroyerComponent;
MockComponent mockComponent;
mockComponent.myInt = 2;
mockComponent.myString = "blah";
worldBuilder.SetComponent(entity, destroyerComponent);
var componentID = worldBuilder.SetComponent(entity, mockComponent);
2019-06-20 03:37:46 +00:00
worldBuilder.SetComponent(entityB, destroyerComponent);
var componentBID = worldBuilder.SetComponent(entityB, mockComponent);
2019-06-20 03:37:46 +00:00
var componentCID = worldBuilder.SetComponent(entityC, mockComponent);
2019-06-20 03:37:46 +00:00
var world = worldBuilder.Build();
world.Update(0.01);
world.Update(0.01);
2019-06-20 03:37:46 +00:00
Assert.That(results, Does.Not.Contain((componentID, mockComponent)));
Assert.That(results, Does.Not.Contain((componentBID, mockComponent)));
Assert.That(results, Does.Contain((componentCID, mockComponent)));
}
[Receives(typeof(DestroyComponentMessage))]
class DestroyEntityEngine : Engine
{
public override void Update(double dt)
{
foreach (var message in ReadMessages<DestroyComponentMessage>())
{
Destroy(message.entity);
}
}
}
[Test]
public void DestroyEntityWithoutID()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddComponentEngine());
worldBuilder.AddEngine(new DestroyEntityEngine());
worldBuilder.AddEngine(new ReaderEngine());
var mockComponent = new MockComponent { };
var entity = worldBuilder.CreateEntity();
var componentID = worldBuilder.SetComponent(entity, mockComponent);
worldBuilder.SendMessage(new DestroyComponentMessage { entity = entity });
var world = worldBuilder.Build();
world.Update(0.01);
Assert.DoesNotThrow(() => world.Update(0.01));
Assert.That(results, Does.Not.Contain((componentID, mockComponent)));
}
2019-07-18 21:02:57 +00:00
[Reads(typeof(DestroyerComponent), typeof(MockComponent))]
class DestroyAndAddComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (var componentPair in ReadComponents<DestroyerComponent>())
{
var componentID = componentPair.Item1;
var entity = GetEntityByComponentID<MockComponent>(componentID);
2019-07-17 18:24:21 +00:00
var (id, _) = GetComponent<MockComponent>(entity);
RemoveComponent(id);
Destroy(entity.ID);
}
}
}
[Test]
public void DestroyEntityWhileRemovingComponent()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new DestroyAndAddComponentEngine());
worldBuilder.AddEngine(new ReaderEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new DestroyerComponent());
worldBuilder.SetComponent(entity, new MockComponent());
var world = worldBuilder.Build();
Assert.DoesNotThrow(() => world.Update(0.01));
2019-06-20 03:37:46 +00:00
}
static Entity entityFromComponentIDResult;
2019-07-18 21:02:57 +00:00
[Reads(typeof(MockComponent))]
class GetEntityFromComponentIDEngine : Engine
{
2019-06-24 19:40:40 +00:00
public override void Update(double dt)
{
var componentID = ReadComponent<MockComponent>().Item1;
entityFromComponentIDResult = GetEntityByComponentID<MockComponent>(componentID);
}
}
[Test]
public void GetEntityFromComponentID()
{
var worldBuilder = new WorldBuilder();
2019-06-24 19:40:40 +00:00
worldBuilder.AddEngine(new GetEntityFromComponentIDEngine());
MockComponent component;
component.myInt = 2;
component.myString = "howdy";
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, component);
var world = worldBuilder.Build();
world.Update(0.01);
Assert.That(entity, Is.EqualTo(entityFromComponentIDResult));
}
[Reads(typeof(MockComponent))]
[WritesPending(typeof(MockComponent))]
[Writes(typeof(MockComponent))]
class AddAndRemoveMockComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (var (mockComponentID, mockComponent) in ReadComponents<MockComponent>())
{
var entity = GetEntityByComponentID<MockComponent>(mockComponentID);
RemoveComponent(mockComponentID);
SetComponent(entity, new MockComponent());
}
}
}
[ReadsPending(typeof(MockComponent))]
class GetEntityFromPendingComponentIDEngine : Engine
{
public override void Update(double dt)
{
foreach (var (mockComponentID, mockComponent) in ReadComponents<MockComponent>())
{
entityFromComponentIDResult = GetEntityByComponentID<MockComponent>(mockComponentID);
}
}
}
[Test]
public void GetEntityFromPendingComponentID()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddAndRemoveMockComponentEngine());
worldBuilder.AddEngine(new GetEntityFromPendingComponentIDEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent());
var world = worldBuilder.Build();
Assert.DoesNotThrow(() => world.Update(0.01));
}
[ReadsPending(typeof(MockComponent))]
class GetPendingComponentFromIDEngine : Engine
{
public override void Update(double dt)
{
foreach (var (mockComponentID, mockComponent) in ReadComponents<MockComponent>())
{
GetComponentByID<MockComponent>(mockComponentID);
}
}
}
[Test]
public void GetComponentFromID()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddAndRemoveMockComponentEngine());
worldBuilder.AddEngine(new GetPendingComponentFromIDEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent());
var world = worldBuilder.Build();
Assert.DoesNotThrow(() => world.Update(0.01));
}
static MockComponent mockComponentByIDResult;
2019-07-18 21:02:57 +00:00
[Reads(typeof(MockComponent))]
class GetComponentByIDEngine : Engine
{
2019-06-24 19:40:40 +00:00
public override void Update(double dt)
{
var componentID = ReadComponent<MockComponent>().Item1;
mockComponentByIDResult = GetComponentByID<MockComponent>(componentID);
}
}
[Test]
public void GetComponentByID()
{
var worldBuilder = new WorldBuilder();
2019-06-24 19:40:40 +00:00
worldBuilder.AddEngine(new GetComponentByIDEngine());
MockComponent component;
component.myInt = 2;
component.myString = "howdy";
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, component);
var world = worldBuilder.Build();
world.Update(0.01f);
Assert.That(component, Is.EqualTo(mockComponentByIDResult));
}
struct OtherComponent : IComponent { }
[Reads(typeof(MockComponent), typeof(OtherComponent))]
class GetComponentByIDWithTypeMismatchEngine : Engine
{
2019-06-24 19:40:40 +00:00
public override void Update(double dt)
{
var componentID = ReadComponent<MockComponent>().Item1;
GetComponentByID<OtherComponent>(componentID);
}
}
[Test]
public void GetComponentByIDWithTypeMismatch()
{
var worldBuilder = new WorldBuilder();
2019-06-24 19:40:40 +00:00
worldBuilder.AddEngine(new GetComponentByIDWithTypeMismatchEngine());
MockComponent component;
component.myInt = 2;
component.myString = "howdy";
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, component);
var world = worldBuilder.Build();
Assert.Throws<ComponentTypeMismatchException>(() => world.Update(0.01f));
}
struct EntityIDComponent : IComponent { public Guid entityID; }
static bool hasEntity;
2019-07-18 21:02:57 +00:00
[Reads(typeof(EntityIDComponent))]
class HasEntityTestEngine : Engine
{
public override void Update(double dt)
{
foreach (var (mockComponentID, mockComponent) in ReadComponents<EntityIDComponent>())
{
hasEntity = EntityExists(mockComponent.entityID);
if (hasEntity) { Destroy(mockComponent.entityID); }
}
}
}
[Test]
public void EntityExists()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new HasEntityTestEngine());
var entity = worldBuilder.CreateEntity();
var entityTwo = worldBuilder.CreateEntity();
EntityIDComponent entityIDComponent;
2019-07-17 18:24:21 +00:00
entityIDComponent.entityID = entityTwo.ID;
worldBuilder.SetComponent(entity, entityIDComponent);
var world = worldBuilder.Build();
world.Update(0.01);
Assert.IsTrue(hasEntity);
world.Update(0.01);
Assert.IsFalse(hasEntity);
}
2019-07-18 01:53:31 +00:00
struct MockComponentUpdateMessage : IMessage
{
public Guid componentID;
public MockComponent mockComponent;
}
[Reads(typeof(MockComponent))]
2019-07-19 19:47:17 +00:00
[Receives(typeof(MockComponentUpdateMessage))]
[Writes(typeof(MockComponent))]
class UpdateByComponentIDEngine : Engine
2019-07-18 01:53:31 +00:00
{
public override void Update(double dt)
{
foreach (var mockComponentUpdateMessage in ReadMessages<MockComponentUpdateMessage>())
{
SetComponent(mockComponentUpdateMessage.componentID, mockComponentUpdateMessage.mockComponent);
SetComponent(mockComponentUpdateMessage.componentID, mockComponentUpdateMessage.mockComponent);
2019-07-18 01:53:31 +00:00
}
}
}
[Test]
public void EngineUpdateByComponentID()
2019-07-18 01:53:31 +00:00
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new UpdateByComponentIDEngine());
2019-07-18 01:53:31 +00:00
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 1;
mockComponent.myString = "5";
var mockComponentID = worldBuilder.SetComponent(entity, mockComponent);
2019-07-18 01:53:31 +00:00
MockComponentUpdateMessage mockComponentUpdateMessage;
mockComponentUpdateMessage.componentID = mockComponentID;
mockComponentUpdateMessage.mockComponent = mockComponent;
worldBuilder.SendMessage(mockComponentUpdateMessage);
2019-07-18 01:53:31 +00:00
var world = worldBuilder.Build();
Assert.DoesNotThrow(() => world.Update(0.01));
2019-07-18 01:53:31 +00:00
}
2019-08-20 02:05:18 +00:00
[Reads(typeof(MockComponent))]
class DelayedMessageEngine : Engine
{
public override void Update(double dt)
{
foreach (var (componentID, component) in ReadComponents<MockComponent>())
{
RemoveComponent(componentID);
SendMessageDelayed(new MockMessage { }, 1);
2019-08-20 02:05:18 +00:00
}
}
}
[Test]
public void EngineSendMessageDelayed()
{
resultMessages.Clear();
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new DelayedMessageEngine());
worldBuilder.AddEngine(new MessageReadEngine());
2019-08-20 02:05:18 +00:00
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent { });
2019-08-20 02:05:18 +00:00
var world = worldBuilder.Build();
world.Update(0.01);
resultMessages.Should().BeEmpty();
world.Update(0.5);
resultMessages.Should().BeEmpty();
world.Update(0.5);
resultMessages.Should().NotBeEmpty();
resultMessages.First().Should().BeOfType<MockMessage>();
}
[Receives(typeof(MockMessage))]
[WritesPending(typeof(MockComponent))]
[Writes(typeof(MockComponent))]
class ActivateComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (var message in ReadMessages<MockMessage>())
{
var entity = CreateEntity();
SetComponent(entity, new MockComponent { });
}
}
}
[ReadsPending(typeof(MockComponent))]
class RemoveComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (var (componentID, component) in ReadComponents<MockComponent>())
{
RemoveComponent(componentID);
}
}
}
[Test]
public void EngineAddAndRemoveComponentSameFrame()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ActivateComponentEngine());
worldBuilder.AddEngine(new RemoveComponentEngine());
worldBuilder.SendMessage(new MockMessage { });
var world = worldBuilder.Build();
Assert.DoesNotThrow(() => world.Update(0.01));
}
struct DestroyComponentMessage : IMessage { public Entity entity; }
[Reads(typeof(MockComponent))]
[Writes(typeof(MockComponent))]
class AddComponentEngine : Engine
{
public override void Update(double dt)
{
foreach (var (componentID, component) in ReadComponents<MockComponent>())
{
SetComponent(componentID, new MockComponent { });
}
}
}
[Receives(typeof(DestroyComponentMessage))]
class DestroyEntityByIDEngine : Engine
{
public override void Update(double dt)
{
foreach (var message in ReadMessages<DestroyComponentMessage>())
{
Destroy(message.entity.ID);
}
}
}
[Test]
public void EngineSetComponentAndDestroyEntitySameFrame()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddComponentEngine());
worldBuilder.AddEngine(new DestroyEntityByIDEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent { });
worldBuilder.SendMessage(new DestroyComponentMessage { entity = entity });
var world = worldBuilder.Build();
world.Update(0.01);
Assert.DoesNotThrow(() => world.Update(0.01));
}
static Entity readEntity;
[Reads(typeof(MockComponent))]
class ReadEntityByComponentTypeEngine : Engine
{
public override void Update(double dt)
{
readEntity = ReadEntity<MockComponent>();
}
}
[Test]
public void GetEntityByComponentType()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ReadEntityByComponentTypeEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent { });
var world = worldBuilder.Build();
world.Update(0.01);
entity.Should().BeEquivalentTo(readEntity);
}
static Entity[] readEntities;
[Reads(typeof(MockComponent))]
class ReadEntitiesWithComponentTypeEngine : Engine
{
public override void Update(double dt)
{
readEntities = ReadEntities<MockComponent>().ToArray();
}
}
[Test]
public void ReadEntities()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ReadEntitiesWithComponentTypeEngine());
worldBuilder.AddEngine(new DestroyAllWithEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent { });
var entityB = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entityB, new MockComponent { });
var world = worldBuilder.Build();
world.Update(0.01);
readEntities.Should().Contain(entity);
readEntities.Should().Contain(entityB);
}
[Reads(typeof(MockComponent))]
class DestroyWithEngine : Engine
{
public override void Update(double dt)
{
if (SomeComponent<MockComponent>())
{
DestroyWith<MockComponent>();
}
}
}
[Test]
public void DestroyWith()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ReadEntitiesWithComponentTypeEngine());
worldBuilder.AddEngine(new DestroyWithEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent { });
var world = worldBuilder.Build();
world.Update(0.01);
world.Update(0.01); // update twice so the read happens after destroy
readEntities.Should().BeEmpty();
}
[Reads(typeof(MockComponent))]
class DestroyAllWithEngine : Engine
{
public override void Update(double dt)
{
DestroyAllWith<MockComponent>();
}
}
[Test]
public void DestroyAllWith()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new ReadEntitiesWithComponentTypeEngine());
worldBuilder.AddEngine(new DestroyAllWithEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent { });
var entityB = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entityB, new MockComponent { });
var world = worldBuilder.Build();
world.Update(0.01);
world.Update(0.01); // update twice so the read happens after destroy
readEntities.Should().BeEmpty();
}
2019-06-15 00:51:06 +00:00
}
}