engines must declare component reads + validation for Reads and Writes arguments
							parent
							
								
									7ab512e522
								
							
						
					
					
						commit
						9b58473ae8
					
				|  | @ -74,38 +74,48 @@ namespace Encompass | |||
| 
 | ||||
|         protected TComponent GetComponentByID<TComponent>(Guid componentID) where TComponent : struct, IComponent | ||||
|         { | ||||
| 
 | ||||
|             if (componentManager.GetComponentTypeByID(componentID) == typeof(TComponent)) | ||||
|             if (!readTypes.Contains(typeof(TComponent)))  | ||||
|             { | ||||
|                 return (TComponent)componentManager.GetComponentByID(componentID); | ||||
|                 throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); | ||||
|             } | ||||
|             else | ||||
| 
 | ||||
|             if (componentManager.GetComponentTypeByID(componentID) != typeof(TComponent)) | ||||
|             { | ||||
|                 throw new ComponentTypeMismatchException("Expected Component to be of type {0} but was actually of type {1}", typeof(TComponent).Name, componentManager.GetComponentTypeByID(componentID).Name); | ||||
|             } | ||||
| 
 | ||||
|             return (TComponent)componentManager.GetComponentByID(componentID); | ||||
|         } | ||||
| 
 | ||||
|         protected IEnumerable<ValueTuple<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent | ||||
|         { | ||||
|             if (!readTypes.Contains(typeof(TComponent)))  | ||||
|             { | ||||
|                 throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); | ||||
|             } | ||||
| 
 | ||||
|             return componentManager.GetActiveComponentsByType<TComponent>(); | ||||
|         } | ||||
| 
 | ||||
|         protected ValueTuple<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent | ||||
|         { | ||||
|             if (!readTypes.Contains(typeof(TComponent)))  | ||||
|             { | ||||
|                 throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); | ||||
|             } | ||||
| 
 | ||||
|             return componentManager.GetActiveComponentByType<TComponent>(); | ||||
|         } | ||||
| 
 | ||||
|         internal void UpdateComponentInWorld<TComponent>(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent | ||||
|         { | ||||
|             if (writeTypes.Contains(typeof(TComponent))) | ||||
|             if (!writeTypes.Contains(typeof(TComponent))) | ||||
|             { | ||||
|                 throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); | ||||
|             } | ||||
| 
 | ||||
|             componentManager.UpdateComponent(componentID, newComponent); | ||||
|         } | ||||
|             else | ||||
|             { | ||||
|                 throw new IllegalComponentMutationException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         protected void UpdateComponent<TComponent>(Guid componentID, TComponent newComponentValue) where TComponent : struct, IComponent | ||||
|         { | ||||
|  | @ -114,39 +124,34 @@ namespace Encompass | |||
| 
 | ||||
|         protected void EmitMessage<TMessage>(TMessage message) where TMessage : struct, IMessage | ||||
|         { | ||||
|             if (writeTypes.Contains(typeof(TMessage))) | ||||
|             if (!writeTypes.Contains(typeof(TMessage))) | ||||
|             { | ||||
|                 throw new IllegalWriteException("Engine {0} tried to emit undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); | ||||
|             } | ||||
| 
 | ||||
|             messageManager.AddMessage(message); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 throw new IllegalMessageEmitException("Engine {0} tried to emit undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage | ||||
|         { | ||||
|             if (readTypes.Contains(typeof(TMessage))) | ||||
|             if (!readTypes.Contains(typeof(TMessage))) | ||||
|             { | ||||
|                 throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); | ||||
|             } | ||||
| 
 | ||||
|             return messageManager.GetMessagesByType<TMessage>(); | ||||
|         } | ||||
|             else | ||||
|             { | ||||
|                 throw new IllegalMessageReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         protected bool Some<TMessage>() where TMessage : struct, IMessage | ||||
|         { | ||||
|             if (readTypes.Contains(typeof(TMessage))) | ||||
|             if (!readTypes.Contains(typeof(TMessage))) | ||||
|             { | ||||
|                 throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); | ||||
|             } | ||||
| 
 | ||||
|             return messageManager.GetMessagesByType<TMessage>().Any(); | ||||
|         } | ||||
|             else | ||||
|             { | ||||
|                 throw new IllegalMessageReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         protected void Destroy(Guid entityID) | ||||
|         { | ||||
|  |  | |||
|  | @ -17,8 +17,8 @@ namespace Encompass | |||
|         private readonly DrawLayerManager drawLayerManager; | ||||
|         private readonly RenderManager renderManager; | ||||
| 
 | ||||
|         private readonly Dictionary<Type, HashSet<Engine>> messageTypeToEmitters = new Dictionary<Type, HashSet<Engine>>(); | ||||
|         private readonly Dictionary<Type, HashSet<Engine>> messageTypeToReaders = new Dictionary<Type, HashSet<Engine>>(); | ||||
|         private readonly Dictionary<Type, HashSet<Engine>> typeToEmitters = new Dictionary<Type, HashSet<Engine>>(); | ||||
|         private readonly Dictionary<Type, HashSet<Engine>> typeToReaders = new Dictionary<Type, HashSet<Engine>>(); | ||||
| 
 | ||||
|         public WorldBuilder() | ||||
|         { | ||||
|  | @ -55,41 +55,61 @@ namespace Encompass | |||
|                 entityManager.RegisterEntityTracker(engine as IEntityTracker); | ||||
|             } | ||||
| 
 | ||||
|             foreach (var emitMessageType in engine.writeTypes) | ||||
|             foreach (var writeType in engine.writeTypes) | ||||
|             { | ||||
|                 if (!messageTypeToEmitters.ContainsKey(emitMessageType)) | ||||
|                 if (!typeToEmitters.ContainsKey(writeType)) | ||||
|                 { | ||||
|                     messageTypeToEmitters.Add(emitMessageType, new HashSet<Engine>()); | ||||
|                     typeToEmitters.Add(writeType, new HashSet<Engine>()); | ||||
|                 } | ||||
| 
 | ||||
|                 messageTypeToEmitters[emitMessageType].Add(engine); | ||||
|                 typeToEmitters[writeType].Add(engine); | ||||
| 
 | ||||
|                 if (messageTypeToReaders.ContainsKey(emitMessageType)) | ||||
|                 if (typeToReaders.ContainsKey(writeType)) | ||||
|                 { | ||||
|                     foreach (var reader in messageTypeToReaders[emitMessageType]) | ||||
|                     foreach (var reader in typeToReaders[writeType]) | ||||
|                     { | ||||
|                         if (engine == reader) | ||||
|                         { | ||||
|                             if (writeType.GetInterfaces().Contains(typeof(IMessage))) | ||||
|                             { | ||||
|                                 throw new EngineMessageSelfCycleException("Engine both reads and writes Message {0}", writeType.Name); | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             engineGraph.AddEdge(engine, reader); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|             foreach (var readMessageType in engine.readTypes) | ||||
|             { | ||||
|                 if (!messageTypeToReaders.ContainsKey(readMessageType)) | ||||
|                 { | ||||
|                     messageTypeToReaders.Add(readMessageType, new HashSet<Engine>()); | ||||
|             } | ||||
| 
 | ||||
|                 messageTypeToReaders[readMessageType].Add(engine); | ||||
| 
 | ||||
|                 if (messageTypeToEmitters.ContainsKey(readMessageType)) | ||||
|             foreach (var readType in engine.readTypes) | ||||
|             { | ||||
|                     foreach (var emitter in messageTypeToEmitters[readMessageType]) | ||||
|                 if (!typeToReaders.ContainsKey(readType)) | ||||
|                 { | ||||
|                     typeToReaders.Add(readType, new HashSet<Engine>()); | ||||
|                 } | ||||
| 
 | ||||
|                 typeToReaders[readType].Add(engine); | ||||
| 
 | ||||
|                 if (typeToEmitters.ContainsKey(readType)) | ||||
|                 { | ||||
|                     foreach (var emitter in typeToEmitters[readType]) | ||||
|                     { | ||||
|                         if (emitter == engine) | ||||
|                         { | ||||
|                             if (readType.GetInterfaces().Contains(typeof(IMessage))) | ||||
|                             { | ||||
|                                 throw new EngineMessageSelfCycleException("Engine both reads and writes Message {0}", readType.Name); | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             engineGraph.AddEdge(emitter, engine); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return engine; | ||||
|         } | ||||
|  | @ -177,7 +197,7 @@ namespace Encompass | |||
|                     string.Join(", ", componentToEngines[componentType].Select((engine) => engine.GetType().Name)); | ||||
|                 } | ||||
| 
 | ||||
|                 throw new EngineMutationConflictException(errorString); | ||||
|                 throw new EngineWriteConflictException(errorString); | ||||
|             } | ||||
| 
 | ||||
|             var engineOrder = new List<Engine>(); | ||||
|  |  | |||
|  | @ -1,16 +0,0 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| namespace Encompass | ||||
| { | ||||
|     [AttributeUsage(AttributeTargets.Class)] | ||||
|     public class Writes : Attribute | ||||
|     { | ||||
|         public readonly List<Type> writeTypes; | ||||
| 
 | ||||
|         public Writes(params Type[] writeTypes) | ||||
|         { | ||||
|             this.writeTypes = new List<Type>(writeTypes); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,5 +1,7 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using Encompass.Exceptions; | ||||
| 
 | ||||
| namespace Encompass | ||||
| { | ||||
|  | @ -8,9 +10,17 @@ namespace Encompass | |||
|     { | ||||
|         public readonly List<Type> readTypes; | ||||
| 
 | ||||
|         public Reads(params Type[] readMessageTypes) | ||||
|         public Reads(params Type[] readTypes) | ||||
|         { | ||||
|             this.readTypes = new List<Type>(readMessageTypes); | ||||
|             foreach (var readType in readTypes) | ||||
|             { | ||||
|                 if (!readType.GetInterfaces().Contains(typeof(IMessage)) && !readType.GetInterfaces().Contains(typeof(IComponent))) | ||||
|                 { | ||||
|                     throw new IllegalReadTypeException("{0} must be a Message or Component", readType.Name); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             this.readTypes = new List<Type>(readTypes); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,26 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using Encompass.Exceptions; | ||||
| 
 | ||||
| namespace Encompass | ||||
| { | ||||
|     [AttributeUsage(AttributeTargets.Class)] | ||||
|     public class Writes : Attribute | ||||
|     { | ||||
|         public readonly List<Type> writeTypes; | ||||
| 
 | ||||
|         public Writes(params Type[] writeTypes) | ||||
|         { | ||||
|             foreach (var writeType in writeTypes) | ||||
|             { | ||||
|                 if (!writeType.GetInterfaces().Contains(typeof(IMessage)) && !writeType.GetInterfaces().Contains(typeof(IComponent))) | ||||
|                 { | ||||
|                     throw new IllegalWriteTypeException("{0} must be a Message or Component", writeType.Name); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             this.writeTypes = new List<Type>(writeTypes); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -2,9 +2,9 @@ using System; | |||
| 
 | ||||
| namespace Encompass.Exceptions | ||||
| { | ||||
|     public class EngineMutationConflictException : Exception | ||||
|     public class EngineMessageSelfCycleException : Exception | ||||
|     { | ||||
|         public EngineMutationConflictException( | ||||
|         public EngineMessageSelfCycleException( | ||||
|             string format, | ||||
|             params object[] args | ||||
|         ) : base(string.Format(format, args)) { } | ||||
|  | @ -2,9 +2,9 @@ using System; | |||
| 
 | ||||
| namespace Encompass.Exceptions | ||||
| { | ||||
|     public class IllegalComponentMutationException : Exception | ||||
|     public class EngineWriteConflictException : Exception | ||||
|     { | ||||
|         public IllegalComponentMutationException( | ||||
|         public EngineWriteConflictException( | ||||
|             string format, | ||||
|             params object[] args | ||||
|         ) : base(string.Format(format, args)) { } | ||||
|  | @ -2,9 +2,9 @@ using System; | |||
| 
 | ||||
| namespace Encompass.Exceptions | ||||
| { | ||||
|     public class IllegalMessageReadException : Exception | ||||
|     public class IllegalReadException : Exception | ||||
|     { | ||||
|         public IllegalMessageReadException( | ||||
|         public IllegalReadException( | ||||
|             string format, | ||||
|             params object[] args | ||||
|         ) : base(string.Format(format, args)) { } | ||||
|  | @ -2,9 +2,9 @@ using System; | |||
| 
 | ||||
| namespace Encompass.Exceptions | ||||
| { | ||||
|     public class IllegalMessageEmitException : Exception | ||||
|     public class IllegalReadTypeException : Exception | ||||
|     { | ||||
|         public IllegalMessageEmitException( | ||||
|         public IllegalReadTypeException( | ||||
|             string format, | ||||
|             params object[] args | ||||
|         ) : base(string.Format(format, args)) { } | ||||
|  | @ -0,0 +1,12 @@ | |||
| using System; | ||||
| 
 | ||||
| namespace Encompass.Exceptions | ||||
| { | ||||
|     public class IllegalWriteException : Exception | ||||
|     { | ||||
|         public IllegalWriteException( | ||||
|             string format, | ||||
|             params object[] args | ||||
|         ) : base(string.Format(format, args)) { } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,12 @@ | |||
| using System; | ||||
| 
 | ||||
| namespace Encompass.Exceptions | ||||
| { | ||||
|     public class IllegalWriteTypeException : Exception | ||||
|     { | ||||
|         public IllegalWriteTypeException( | ||||
|             string format, | ||||
|             params object[] args | ||||
|         ) : base(string.Format(format, args)) { } | ||||
|     } | ||||
| } | ||||
|  | @ -27,7 +27,7 @@ namespace Encompass | |||
|         } | ||||
| 
 | ||||
|         protected List<T> _vertices = new List<T>(); | ||||
|         protected Dictionary<T, List<T>> _neighbors = new Dictionary<T, List<T>>(); | ||||
|         protected Dictionary<T, HashSet<T>> _neighbors = new Dictionary<T, HashSet<T>>(); | ||||
| 
 | ||||
|         public IEnumerable<T> Vertices { get { return _vertices; } } | ||||
| 
 | ||||
|  | @ -40,7 +40,7 @@ namespace Encompass | |||
|             if (!VertexExists(vertex)) | ||||
|             { | ||||
|                 _vertices.Add(vertex); | ||||
|                 _neighbors.Add(vertex, new List<T>()); | ||||
|                 _neighbors.Add(vertex, new HashSet<T>()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ namespace Tests | |||
| 
 | ||||
|         static List<MockMessage> resultMessages; | ||||
| 
 | ||||
|         [Reads(typeof(MockComponent))] | ||||
|         public class ReadComponentsTestEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -25,6 +26,7 @@ namespace Tests | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         [Reads(typeof(MockComponent))] | ||||
|         public class ReadComponentTestEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -110,6 +112,7 @@ namespace Tests | |||
|             Assert.Throws<InvalidOperationException>(() => world.Update(0.01f)); | ||||
|         } | ||||
| 
 | ||||
|         [Reads(typeof(MockComponent))] | ||||
|         [Writes(typeof(MockComponent))] | ||||
|         public class UpdateComponentTestEngine : Engine | ||||
|         { | ||||
|  | @ -147,6 +150,7 @@ namespace Tests | |||
|             Assert.AreEqual("blaze it", resultComponent.myString); | ||||
|         } | ||||
| 
 | ||||
|         [Reads(typeof(MockComponent))] | ||||
|         public class UndeclaredUpdateComponentTestEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -177,7 +181,7 @@ namespace Tests | |||
| 
 | ||||
|             var world = worldBuilder.Build(); | ||||
| 
 | ||||
|             var ex = Assert.Throws<IllegalComponentMutationException>(() => world.Update(0.01f)); | ||||
|             var ex = Assert.Throws<IllegalWriteException>(() => world.Update(0.01f)); | ||||
|             Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredUpdateComponentTestEngine tried to write undeclared Component MockComponent")); | ||||
|         } | ||||
| 
 | ||||
|  | @ -263,7 +267,7 @@ namespace Tests | |||
| 
 | ||||
|             var world = worldBuilder.Build(); | ||||
| 
 | ||||
|             var ex = Assert.Throws<IllegalMessageEmitException>(() => world.Update(0.01f)); | ||||
|             var ex = Assert.Throws<IllegalWriteException>(() => world.Update(0.01f)); | ||||
|             Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredMessageEmitEngine tried to emit undeclared Message MockMessage")); | ||||
|         } | ||||
| 
 | ||||
|  | @ -321,12 +325,13 @@ namespace Tests | |||
| 
 | ||||
|             var world = worldBuilder.Build(); | ||||
| 
 | ||||
|             Assert.Throws<IllegalMessageReadException>(() => world.Update(0.01f)); | ||||
|             Assert.Throws<IllegalReadException>(() => world.Update(0.01f)); | ||||
|         } | ||||
| 
 | ||||
|         static ValueTuple<Guid, MockComponent> pairA; | ||||
|         static ValueTuple<Guid, MockComponent> pairB; | ||||
| 
 | ||||
|         [Reads(typeof(MockComponent))] | ||||
|         class SameValueComponentReadEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -366,6 +371,7 @@ namespace Tests | |||
| 
 | ||||
|         static IEnumerable<ValueTuple<Guid, MockComponent>> emptyComponentReadResult; | ||||
| 
 | ||||
|         [Reads(typeof(MockComponent))] | ||||
|         class ReadEmptyMockComponentsEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -388,6 +394,7 @@ namespace Tests | |||
| 
 | ||||
|         struct DestroyerComponent : IComponent { } | ||||
| 
 | ||||
|         [Reads(typeof(DestroyerComponent))] | ||||
|         class DestroyerEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -402,6 +409,8 @@ namespace Tests | |||
|         } | ||||
| 
 | ||||
|         static IEnumerable<ValueTuple<Guid, MockComponent>> results; | ||||
| 
 | ||||
|         [Reads(typeof(MockComponent))] | ||||
|         class ReaderEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -439,6 +448,7 @@ namespace Tests | |||
|             Assert.That(results, Does.Not.Contain((componentBID, mockComponent))); | ||||
|         } | ||||
| 
 | ||||
|         [Reads(typeof(DestroyerComponent))] | ||||
|         class DestroyAndAddComponentEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -472,6 +482,8 @@ namespace Tests | |||
|         } | ||||
| 
 | ||||
|         static Entity entityFromComponentIDResult; | ||||
| 
 | ||||
|         [Reads(typeof(MockComponent))] | ||||
|         class GetEntityFromComponentIDEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -501,6 +513,8 @@ namespace Tests | |||
|         } | ||||
| 
 | ||||
|         static MockComponent mockComponentByIDResult; | ||||
| 
 | ||||
|         [Reads(typeof(MockComponent))] | ||||
|         class GetComponentByIDEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -530,6 +544,7 @@ namespace Tests | |||
| 
 | ||||
|         struct OtherComponent : IComponent { } | ||||
| 
 | ||||
|         [Reads(typeof(MockComponent), typeof(OtherComponent))] | ||||
|         class GetComponentByIDWithTypeMismatchEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  | @ -559,6 +574,8 @@ namespace Tests | |||
| 
 | ||||
|         struct EntityIDComponent : IComponent { public Guid entityID;  } | ||||
|         static bool hasEntity; | ||||
| 
 | ||||
|         [Reads(typeof(EntityIDComponent))] | ||||
|         class HasEntityTestEngine : Engine | ||||
|         { | ||||
|             public override void Update(double dt) | ||||
|  |  | |||
|  | @ -133,7 +133,74 @@ namespace Tests | |||
|                 worldBuilder.AddEngine(new AEngine()); | ||||
|                 worldBuilder.AddEngine(new BEngine()); | ||||
| 
 | ||||
|                 Assert.Throws<EngineMutationConflictException>(() => worldBuilder.Build()); | ||||
|                 Assert.Throws<EngineWriteConflictException>(() => worldBuilder.Build()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public class EngineMessageSelfCycle | ||||
|         { | ||||
|             struct AMessage : IMessage { } | ||||
| 
 | ||||
|             [Reads(typeof(AMessage))] | ||||
|             [Writes(typeof(AMessage))] | ||||
|             class AEngine : Engine | ||||
|             { | ||||
|                 public override void Update(double dt) | ||||
|                 { | ||||
|                      | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             [Test] | ||||
|             public void ThrowsError() | ||||
|             { | ||||
|                 var worldBuilder = new WorldBuilder(); | ||||
| 
 | ||||
|                 Assert.Throws<EngineMessageSelfCycleException>(() => worldBuilder.AddEngine(new AEngine()), "Engine both reads and writes Message AMessage"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public class IllegalReadType | ||||
|         { | ||||
|             struct ANonMessage { } | ||||
| 
 | ||||
|             [Reads(typeof(ANonMessage))] | ||||
|             class MyEngine : Engine | ||||
|             { | ||||
|                 public override void Update(double dt) | ||||
|                 { | ||||
| 
 | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             [Test] | ||||
|             public void ThrowsError() | ||||
|             { | ||||
|                 var worldBuilder = new WorldBuilder(); | ||||
| 
 | ||||
|                 Assert.Throws<IllegalReadTypeException>(() => worldBuilder.AddEngine(new MyEngine()), "ANonMessage must be a Message or Component"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public class IllegalWriteType | ||||
|         { | ||||
|             struct ANonMessage { } | ||||
| 
 | ||||
|             [Writes(typeof(ANonMessage))] | ||||
|             class MyEngine : Engine | ||||
|             { | ||||
|                 public override void Update(double dt) | ||||
|                 { | ||||
| 
 | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             [Test] | ||||
|             public void ThrowsError() | ||||
|             { | ||||
|                 var worldBuilder = new WorldBuilder(); | ||||
| 
 | ||||
|                 Assert.Throws<IllegalWriteTypeException>(() => worldBuilder.AddEngine(new MyEngine()), "ANonMessage must be a Message or Component"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue