868 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			868 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C#
		
	
	
| using NUnit.Framework;
 | |
| using FluentAssertions;
 | |
| 
 | |
| using Encompass;
 | |
| 
 | |
| using System;
 | |
| using System.Linq;
 | |
| using System.Collections.Generic;
 | |
| using Encompass.Exceptions;
 | |
| 
 | |
| namespace Tests
 | |
| {
 | |
|     struct MockComponent : IComponent
 | |
|     { 
 | |
|         public int myInt;
 | |
|         public string myString;
 | |
|     }
 | |
| 
 | |
|     public class EngineTest
 | |
|     {
 | |
|         static List<ValueTuple<Guid, MockComponent>> resultComponents;
 | |
|         static MockComponent resultComponent;
 | |
| 
 | |
|         static List<MockMessage> resultMessages;
 | |
| 
 | |
|         [Reads(typeof(MockComponent))]
 | |
|         public class ReadComponentsTestEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 resultComponents = ReadComponents<MockComponent>().ToList();
 | |
|             }
 | |
|         }
 | |
| 
 | |
| 
 | |
|         [Reads(typeof(MockComponent))]
 | |
|         public class ReadComponentTestEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 resultComponent = ReadComponent<MockComponent>().Item2;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void ReadComponents(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new ReadComponentsTestEngine());
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
| 
 | |
|             MockComponent mockComponent;
 | |
|             mockComponent.myInt = 0;
 | |
|             mockComponent.myString = "hello";
 | |
| 
 | |
|             MockComponent mockComponentB;
 | |
|             mockComponentB.myInt = 1;
 | |
|             mockComponentB.myString = "howdy";
 | |
| 
 | |
|             var componentAID = worldBuilder.AddComponent(entity, mockComponent);
 | |
|             var componentBID = worldBuilder.AddComponent(entity, mockComponentB);
 | |
|             var inactiveComponentAID = worldBuilder.AddComponent(entity, mockComponent);
 | |
| 
 | |
|             worldBuilder.DeactivateComponent(inactiveComponentAID);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
|             var resultComponentValues = resultComponents.Select((kv) => kv.Item2);
 | |
|             resultComponentValues.Should().Contain(mockComponent);
 | |
|             resultComponentValues.Should().Contain(mockComponentB);
 | |
|             resultComponents.Should().NotContain((inactiveComponentAID, mockComponent));
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void ReadComponent(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new ReadComponentTestEngine());
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
| 
 | |
|             MockComponent mockComponent;
 | |
|             mockComponent.myInt = 0;
 | |
|             mockComponent.myString = "hello";
 | |
| 
 | |
|             worldBuilder.AddComponent(entity, mockComponent);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01f);
 | |
|             }
 | |
| 
 | |
|             Assert.AreEqual(mockComponent, resultComponent);
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void ReadComponentWhenMultipleComponents(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new ReadComponentTestEngine());
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
| 
 | |
|             MockComponent mockComponent;
 | |
|             mockComponent.myInt = 0;
 | |
|             mockComponent.myString = "hello";
 | |
| 
 | |
|             MockComponent mockComponentB;
 | |
|             mockComponentB.myInt = 1;
 | |
|             mockComponentB.myString = "howdy";
 | |
| 
 | |
|             worldBuilder.AddComponent(entity, mockComponent);
 | |
|             worldBuilder.AddComponent(entity, mockComponentB);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
|             
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 Assert.Throws<InvalidOperationException>(() => world.ParallelUpdate(0.01));
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Assert.Throws<InvalidOperationException>(() => world.Update(0.01f));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [Reads(typeof(MockComponent))]
 | |
|         [Updates(typeof(MockComponent))]
 | |
|         public class UpdateComponentTestEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 (var componentID, var component) = ReadComponent<MockComponent>();
 | |
| 
 | |
|                 component.myInt = 420;
 | |
|                 component.myString = "blaze it";
 | |
|                 UpdateComponent(componentID, component);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // this test needs to be improved...
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void UpdateComponent(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             
 | |
|             worldBuilder.AddEngine(new UpdateComponentTestEngine());
 | |
|             worldBuilder.AddEngine(new ReadComponentTestEngine());
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
| 
 | |
|             MockComponent mockComponent;
 | |
|             mockComponent.myInt = 0;
 | |
|             mockComponent.myString = "hello";
 | |
| 
 | |
|             worldBuilder.AddComponent(entity, mockComponent);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
| 
 | |
|             Assert.AreEqual(420, resultComponent.myInt);
 | |
|             Assert.AreEqual("blaze it", resultComponent.myString);
 | |
|         }
 | |
| 
 | |
|         [Reads(typeof(MockComponent))]
 | |
|         public class UndeclaredUpdateComponentTestEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 (var componentID, var component) = ReadComponent<MockComponent>();
 | |
| 
 | |
|                 component.myInt = 420;
 | |
|                 component.myString = "blaze it";
 | |
|                 UpdateComponent(componentID, component);
 | |
| 
 | |
|                 component = ReadComponent<MockComponent>().Item2;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void UpdateUndeclaredComponent(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new UndeclaredUpdateComponentTestEngine());
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
| 
 | |
|             MockComponent mockComponent;
 | |
|             mockComponent.myInt = 0;
 | |
|             mockComponent.myString = "hello";
 | |
| 
 | |
|             worldBuilder.AddComponent(entity, mockComponent);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 Action updateWorld = () => world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Action updateWorld = () => world.Update(0.01);
 | |
|             }
 | |
| 
 | |
|             var ex = Assert.Throws<IllegalUpdateException>(() => world.Update(0.01f));
 | |
|             Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredUpdateComponentTestEngine tried to update undeclared Component MockComponent"));
 | |
|         }
 | |
| 
 | |
|         struct MockMessage : IMessage
 | |
|         {
 | |
|             public string myString;
 | |
|         }
 | |
| 
 | |
|         [Sends(typeof(MockMessage))]
 | |
|         public class MessageEmitEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 MockMessage message;
 | |
|                 message.myString = "howdy";
 | |
| 
 | |
|                 this.SendMessage(message);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [Receives(typeof(MockMessage))]
 | |
|         public class MessageReadEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 resultMessages = this.ReadMessages<MockMessage>().ToList();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void EmitAndReadMessage(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new MessageEmitEngine());
 | |
|             worldBuilder.AddEngine(new MessageReadEngine());
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01f);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01f);
 | |
|             }
 | |
| 
 | |
|             Assert.AreEqual(resultMessages.First().myString, "howdy");
 | |
|         }
 | |
| 
 | |
|         public class UndeclaredMessageEmitEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 MockMessage message;
 | |
|                 message.myString = "howdy";
 | |
| 
 | |
|                 this.SendMessage(message);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static IEnumerable<MockMessage> emptyReadMessagesResult;
 | |
| 
 | |
|         [Receives(typeof(MockMessage))]
 | |
|         class ReadMessagesWhenNoneExistEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 emptyReadMessagesResult = ReadMessages<MockMessage>();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void ReadMessagesWhenNoneHaveBeenEmitted(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new ReadMessagesWhenNoneExistEngine());
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
| 
 | |
|             emptyReadMessagesResult.Should().BeEmpty();
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void EmitUndeclaredMessage(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new UndeclaredMessageEmitEngine());
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 var ex = Assert.Throws<IllegalSendException>(() => world.ParallelUpdate(0.01));
 | |
|                 Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredMessageEmitEngine tried to send undeclared Message MockMessage"));
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 var ex = Assert.Throws<IllegalSendException>(() => world.Update(0.01f));
 | |
|                 Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredMessageEmitEngine tried to send undeclared Message MockMessage"));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static bool someTest;
 | |
| 
 | |
|         [Sends(typeof(MockMessage))]
 | |
|         class EmitMockMessageEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 MockMessage message;
 | |
|                 message.myString = "howdy";
 | |
| 
 | |
|                 this.SendMessage(message);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [Receives(typeof(MockMessage))]
 | |
|         class SomeMessageTestEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 someTest = this.SomeMessage<MockMessage>();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void SomeMessage(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new EmitMockMessageEngine());
 | |
|             worldBuilder.AddEngine(new SomeMessageTestEngine());
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01f);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01f);
 | |
|             }
 | |
| 
 | |
|             Assert.That(someTest, Is.True);
 | |
|         }
 | |
| 
 | |
|         class UndeclaredSomeMessageEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 someTest = this.SomeMessage<MockMessage>();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void UndeclaredSomeMessage(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new EmitMockMessageEngine());
 | |
|             worldBuilder.AddEngine(new UndeclaredSomeMessageEngine());
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 Assert.Throws<IllegalReadException>(() => world.ParallelUpdate(0.01f));
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Assert.Throws<IllegalReadException>(() => world.Update(0.01f));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         class SomeComponentTestEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 Assert.IsTrue(SomeComponent<MockComponent>());
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void SomeComponent(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
|             worldBuilder.AddComponent(entity, new MockComponent());
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static ValueTuple<Guid, MockComponent> pairA;
 | |
|         static ValueTuple<Guid, MockComponent> pairB;
 | |
| 
 | |
|         [Reads(typeof(MockComponent))]
 | |
|         class SameValueComponentReadEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 var components = ReadComponents<MockComponent>();
 | |
| 
 | |
|                 pairA = components.First();
 | |
|                 pairB = components.Last();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Tests that components with identical values should be distinguishable by ID
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void SameValueComponents(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new SameValueComponentReadEngine());
 | |
| 
 | |
|             MockComponent componentA;
 | |
|             componentA.myInt = 20;
 | |
|             componentA.myString = "hello";
 | |
| 
 | |
|             MockComponent componentB;
 | |
|             componentB.myInt = 20;
 | |
|             componentB.myString = "hello";
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
|             worldBuilder.AddComponent(entity, componentA);
 | |
|             worldBuilder.AddComponent(entity, componentB);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
| 
 | |
|             Assert.That(pairA, Is.Not.EqualTo(pairB));
 | |
|             Assert.That(pairA.Item2, Is.EqualTo(pairB.Item2));
 | |
|         }
 | |
| 
 | |
|         static IEnumerable<ValueTuple<Guid, MockComponent>> emptyComponentReadResult;
 | |
| 
 | |
|         [Reads(typeof(MockComponent))]
 | |
|         class ReadEmptyMockComponentsEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 emptyComponentReadResult = ReadComponents<MockComponent>();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void ReadComponentsOfTypeWhereNoneExist(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new ReadEmptyMockComponentsEngine());
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
| 
 | |
|             Assert.That(emptyComponentReadResult, Is.Empty);
 | |
|         }
 | |
| 
 | |
|         struct DestroyerComponent : IComponent { }
 | |
| 
 | |
|         [Reads(typeof(DestroyerComponent))]
 | |
|         class DestroyerEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 foreach (var componentPair in ReadComponents<DestroyerComponent>())
 | |
|                 {
 | |
|                     var componentID = componentPair.Item1;
 | |
|                     var entityID = GetEntityIDByComponentID(componentID);
 | |
|                     Destroy(entityID);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static IEnumerable<ValueTuple<Guid, MockComponent>> results;
 | |
| 
 | |
|         [Reads(typeof(MockComponent))]
 | |
|         class ReaderEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 results = ReadComponents<MockComponent>();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void DestroyEntity(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new DestroyerEngine());
 | |
|             worldBuilder.AddEngine(new ReaderEngine());
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
|             var entityB = worldBuilder.CreateEntity();
 | |
| 
 | |
|             DestroyerComponent destroyerComponent;
 | |
|             MockComponent mockComponent;
 | |
|             mockComponent.myInt = 2;
 | |
|             mockComponent.myString = "blah";
 | |
| 
 | |
|             worldBuilder.AddComponent(entity, destroyerComponent);
 | |
|             var componentID = worldBuilder.AddComponent(entity, mockComponent);
 | |
| 
 | |
|             worldBuilder.AddComponent(entityB, destroyerComponent);
 | |
|             var componentBID = worldBuilder.AddComponent(entityB, mockComponent);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
| 
 | |
|             Assert.That(results, Does.Not.Contain((componentID, mockComponent)));
 | |
|             Assert.That(results, Does.Not.Contain((componentBID, mockComponent)));
 | |
|         }
 | |
| 
 | |
|         [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(componentID);
 | |
|                     var (id, _) = GetComponent<MockComponent>(entity);
 | |
|                     RemoveComponent(id);
 | |
|                     Destroy(entity.ID);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void DestroyEntityWhileRemovingComponent(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new DestroyAndAddComponentEngine());
 | |
|             worldBuilder.AddEngine(new ReaderEngine());
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
| 
 | |
|             worldBuilder.AddComponent(entity, new DestroyerComponent());
 | |
|             worldBuilder.AddComponent(entity, new MockComponent());
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 Assert.DoesNotThrow(() => world.ParallelUpdate(0.01));
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Assert.DoesNotThrow(() => world.Update(0.01));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static Entity entityFromComponentIDResult;
 | |
| 
 | |
|         [Reads(typeof(MockComponent))]
 | |
|         class GetEntityFromComponentIDEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 var componentID = ReadComponent<MockComponent>().Item1;
 | |
|                 entityFromComponentIDResult = GetEntityByComponentID(componentID);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void GetEntityFromComponentID(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new GetEntityFromComponentIDEngine());
 | |
| 
 | |
|             MockComponent component;
 | |
|             component.myInt = 2;
 | |
|             component.myString = "howdy";
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
|             worldBuilder.AddComponent(entity, component);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
| 
 | |
|             Assert.That(entity, Is.EqualTo(entityFromComponentIDResult));
 | |
|         }
 | |
| 
 | |
|         static MockComponent mockComponentByIDResult;
 | |
| 
 | |
|         [Reads(typeof(MockComponent))]
 | |
|         class GetComponentByIDEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 var componentID = ReadComponent<MockComponent>().Item1;
 | |
|                 mockComponentByIDResult = GetComponentByID<MockComponent>(componentID);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void GetComponentByID(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new GetComponentByIDEngine());
 | |
| 
 | |
|             MockComponent component;
 | |
|             component.myInt = 2;
 | |
|             component.myString = "howdy";
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
|             worldBuilder.AddComponent(entity, component);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
| 
 | |
|             Assert.That(component, Is.EqualTo(mockComponentByIDResult));
 | |
|         }
 | |
| 
 | |
|         struct OtherComponent : IComponent { }
 | |
| 
 | |
|         [Reads(typeof(MockComponent))]
 | |
|         class GetComponentByIDWithTypeMismatchEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 var componentID = ReadComponent<MockComponent>().Item1;
 | |
|                 GetComponentByID<OtherComponent>(componentID);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void GetComponentByIDWithTypeMismatch(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new GetComponentByIDWithTypeMismatchEngine());
 | |
| 
 | |
|             MockComponent component;
 | |
|             component.myInt = 2;
 | |
|             component.myString = "howdy";
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
|             worldBuilder.AddComponent(entity, component);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 Assert.Throws<ComponentTypeMismatchException>(() => world.ParallelUpdate(0.01));
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Assert.Throws<ComponentTypeMismatchException>(() => world.Update(0.01));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         struct EntityIDComponent : IComponent { public Guid entityID;  }
 | |
|         static bool hasEntity;
 | |
| 
 | |
|         [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); }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void EntityExists(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new HasEntityTestEngine());
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
|             var entityTwo = worldBuilder.CreateEntity();
 | |
| 
 | |
|             EntityIDComponent entityIDComponent;
 | |
|             entityIDComponent.entityID = entityTwo.ID;
 | |
| 
 | |
|             worldBuilder.AddComponent(entity, entityIDComponent);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
| 
 | |
|             Assert.IsTrue(hasEntity);
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 world.ParallelUpdate(0.01);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 world.Update(0.01);
 | |
|             }
 | |
| 
 | |
|             Assert.IsFalse(hasEntity);
 | |
|         }
 | |
| 
 | |
|         struct MockComponentUpdateMessage : IMessage
 | |
|         {
 | |
|             public Guid componentID;
 | |
|             public MockComponent mockComponent;
 | |
|         }
 | |
| 
 | |
|         [Receives(typeof(MockComponentUpdateMessage))]
 | |
|         [Updates(typeof(MockComponent))]
 | |
|         class RepeatUpdateEngine : Engine
 | |
|         {
 | |
|             public override void Update(double dt)
 | |
|             {
 | |
|                 foreach (var mockComponentUpdateMessage in ReadMessages<MockComponentUpdateMessage>())
 | |
|                 {
 | |
|                     UpdateComponent(mockComponentUpdateMessage.componentID, mockComponentUpdateMessage.mockComponent);
 | |
|                     UpdateComponent(mockComponentUpdateMessage.componentID, mockComponentUpdateMessage.mockComponent);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [TestCase(true)]
 | |
|         [TestCase(false)]
 | |
|         public void EngineUpdatesComponentMultipleTimes(bool parallelUpdate)
 | |
|         {
 | |
|             var worldBuilder = new WorldBuilder();
 | |
|             worldBuilder.AddEngine(new RepeatUpdateEngine());
 | |
| 
 | |
|             var entity = worldBuilder.CreateEntity();
 | |
| 
 | |
|             MockComponent mockComponent;
 | |
|             mockComponent.myInt = 1;
 | |
|             mockComponent.myString = "5";
 | |
| 
 | |
|             var mockComponentID = worldBuilder.AddComponent(entity, mockComponent);
 | |
| 
 | |
|             MockComponentUpdateMessage mockComponentUpdateMessage;
 | |
|             mockComponentUpdateMessage.componentID = mockComponentID;
 | |
|             mockComponentUpdateMessage.mockComponent = mockComponent;
 | |
|             worldBuilder.SendMessage(mockComponentUpdateMessage);
 | |
| 
 | |
|             var world = worldBuilder.Build();
 | |
| 
 | |
|             if (parallelUpdate)
 | |
|             {
 | |
|                 Assert.Throws<RepeatUpdateComponentException>(() => world.ParallelUpdate(0.01));
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Assert.Throws<RepeatUpdateComponentException>(() => world.Update(0.01));
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |