read new and existing component system
							parent
							
								
									80effc06dc
								
							
						
					
					
						commit
						1845d5f766
					
				| 
						 | 
					@ -19,7 +19,7 @@ namespace Encompass
 | 
				
			||||||
                    throw new IllegalActivateTypeException("{0} must be a Component", activateType.Name);
 | 
					                    throw new IllegalActivateTypeException("{0} must be a Component", activateType.Name);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                this.activateTypes.Add(typeof(ComponentMessage<>).MakeGenericType(activateType));
 | 
					                this.activateTypes.Add(typeof(NewComponentMessage<>).MakeGenericType(activateType));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,22 +14,14 @@ namespace Encompass
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            foreach (var readType in readTypes)
 | 
					            foreach (var readType in readTypes)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var isMessage = readType.GetInterfaces().Contains(typeof(IMessage));
 | 
					 | 
				
			||||||
                var isComponent = readType.GetInterfaces().Contains(typeof(IComponent));
 | 
					                var isComponent = readType.GetInterfaces().Contains(typeof(IComponent));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (!isMessage && !isComponent)
 | 
					                if (!isComponent)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    throw new IllegalReadTypeException("{0} must be a Message or Component", readType.Name);
 | 
					                    throw new IllegalReadTypeException("{0} must be a Component", readType.Name);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (isComponent)
 | 
					                this.readTypes.Add(typeof(ComponentMessage<>).MakeGenericType(readType));
 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    this.readTypes.Add(typeof(ComponentMessage<>).MakeGenericType(readType));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    this.readTypes.Add(readType);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using Encompass.Exceptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Encompass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [AttributeUsage(AttributeTargets.Class)]
 | 
				
			||||||
 | 
					    public class ReadsNew : Attribute
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public readonly HashSet<Type> newComponentReadTypes = new HashSet<Type>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public ReadsNew(params Type[] readTypes)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            foreach (var readType in readTypes)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var isComponent = readType.GetInterfaces().Contains(typeof(IComponent));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!isComponent)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    throw new IllegalReadTypeException("{0} must be a Component", readType.Name);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                this.newComponentReadTypes.Add(typeof(ComponentMessage<>).MakeGenericType(readType));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using Encompass.Exceptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Encompass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [AttributeUsage(AttributeTargets.Class)]
 | 
				
			||||||
 | 
					    public class Receives : Attribute
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public readonly HashSet<Type> receiveTypes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Receives(params Type[] receiveTypes)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            foreach (var receiveType in receiveTypes)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var isMessage = receiveType.GetInterfaces().Contains(typeof(IMessage));
 | 
				
			||||||
 | 
					                if (!isMessage)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    throw new IllegalSendTypeException("{0} must be a Message", receiveType.Name);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.receiveTypes = new HashSet<Type>(receiveTypes);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ namespace Encompass
 | 
				
			||||||
                var isMessage = sendType.GetInterfaces().Contains(typeof(IMessage));
 | 
					                var isMessage = sendType.GetInterfaces().Contains(typeof(IMessage));
 | 
				
			||||||
                if (!isMessage)
 | 
					                if (!isMessage)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    throw new IllegalWriteTypeException("{0} must be a Message", sendType.Name);
 | 
					                    throw new IllegalSendTypeException("{0} must be a Message", sendType.Name);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,8 +9,7 @@ namespace Encompass
 | 
				
			||||||
    public abstract class Engine
 | 
					    public abstract class Engine
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        internal readonly HashSet<Type> sendTypes = new HashSet<Type>();
 | 
					        internal readonly HashSet<Type> sendTypes = new HashSet<Type>();
 | 
				
			||||||
        internal readonly HashSet<Type> readTypes = new HashSet<Type>();
 | 
					        internal readonly HashSet<Type> receiveTypes = new HashSet<Type>();
 | 
				
			||||||
        internal readonly HashSet<Type> activateTypes = new HashSet<Type>();
 | 
					 | 
				
			||||||
        internal readonly HashSet<Type> updateTypes = new HashSet<Type>();
 | 
					        internal readonly HashSet<Type> updateTypes = new HashSet<Type>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private EntityManager entityManager;
 | 
					        private EntityManager entityManager;
 | 
				
			||||||
| 
						 | 
					@ -19,22 +18,34 @@ namespace Encompass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected Engine()
 | 
					        protected Engine()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var writesAttribute = GetType().GetCustomAttribute<Sends>(false);
 | 
					            var sendsAttribute = GetType().GetCustomAttribute<Sends>(false);
 | 
				
			||||||
            if (writesAttribute != null)
 | 
					            if (sendsAttribute != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                sendTypes = writesAttribute.sendTypes;
 | 
					                sendTypes = sendsAttribute.sendTypes;
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var readsAttribute = GetType().GetCustomAttribute<Reads>(false);
 | 
					 | 
				
			||||||
            if (readsAttribute != null)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                readTypes = readsAttribute.readTypes;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var activatesAttribute = GetType().GetCustomAttribute<Activates>(false);
 | 
					            var activatesAttribute = GetType().GetCustomAttribute<Activates>(false);
 | 
				
			||||||
            if (activatesAttribute != null)
 | 
					            if (activatesAttribute != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                activateTypes = activatesAttribute.activateTypes;
 | 
					                sendTypes.UnionWith(activatesAttribute.activateTypes);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var receivesAttribute = GetType().GetCustomAttribute<Receives>(false);
 | 
				
			||||||
 | 
					            if (receivesAttribute != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                receiveTypes = receivesAttribute.receiveTypes;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var readsAttribute = GetType().GetCustomAttribute<Reads>(false);
 | 
				
			||||||
 | 
					            if (readsAttribute != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                receiveTypes.UnionWith(readsAttribute.readTypes);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var readsNewAttribute = GetType().GetCustomAttribute<ReadsNew>(false);
 | 
				
			||||||
 | 
					            if (readsNewAttribute != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                receiveTypes.UnionWith(readsNewAttribute.newComponentReadTypes);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var updatesAttribute = GetType().GetCustomAttribute<Updates>(false);
 | 
					            var updatesAttribute = GetType().GetCustomAttribute<Updates>(false);
 | 
				
			||||||
| 
						 | 
					@ -107,14 +118,14 @@ namespace Encompass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected Guid AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
 | 
					        protected Guid AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!activateTypes.Contains(typeof(ComponentMessage<TComponent>)))
 | 
					            if (!sendTypes.Contains(typeof(NewComponentMessage<TComponent>)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
					                throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var componentID = componentManager.AddComponent(entity.ID, component);
 | 
					            var componentID = componentManager.AddComponent(entity.ID, component);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ComponentMessage<TComponent> componentMessage;
 | 
					            NewComponentMessage<TComponent> componentMessage;
 | 
				
			||||||
            componentMessage.entity = entity;
 | 
					            componentMessage.entity = entity;
 | 
				
			||||||
            componentMessage.componentID = componentID;
 | 
					            componentMessage.componentID = componentID;
 | 
				
			||||||
            componentMessage.component = component;
 | 
					            componentMessage.component = component;
 | 
				
			||||||
| 
						 | 
					@ -125,25 +136,25 @@ namespace Encompass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected Guid AddDrawComponent<TComponent>(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent
 | 
					        protected Guid AddDrawComponent<TComponent>(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!activateTypes.Contains(typeof(ComponentMessage<TComponent>)))
 | 
					            if (!sendTypes.Contains(typeof(NewComponentMessage<TComponent>)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
					                throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var componentID = componentManager.AddDrawComponent(entity.ID, component, layer);
 | 
					            var componentID = componentManager.AddDrawComponent(entity.ID, component, layer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ComponentMessage<TComponent> componentMessage;
 | 
					            NewComponentMessage<TComponent> newComponentMessage;
 | 
				
			||||||
            componentMessage.entity = entity;
 | 
					            newComponentMessage.entity = entity;
 | 
				
			||||||
            componentMessage.componentID = componentID;
 | 
					            newComponentMessage.componentID = componentID;
 | 
				
			||||||
            componentMessage.component = component;
 | 
					            newComponentMessage.component = component;
 | 
				
			||||||
            SendMessage(componentMessage);
 | 
					            SendMessage(newComponentMessage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return componentID;
 | 
					            return componentID;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected void ActivateComponent<TComponent>(Guid componentID) where TComponent : struct, IComponent
 | 
					        protected void ActivateComponent<TComponent>(Guid componentID) where TComponent : struct, IComponent
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!activateTypes.Contains(typeof(ComponentMessage<TComponent>)))
 | 
					            if (!sendTypes.Contains(typeof(NewComponentMessage<TComponent>)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
					                throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -151,13 +162,13 @@ namespace Encompass
 | 
				
			||||||
            var entity = GetEntity(componentManager.GetEntityIDByComponentID(componentID));
 | 
					            var entity = GetEntity(componentManager.GetEntityIDByComponentID(componentID));
 | 
				
			||||||
            var component = GetComponentByID<TComponent>(componentID);
 | 
					            var component = GetComponentByID<TComponent>(componentID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ComponentMessage<TComponent> componentMessage;
 | 
					            NewComponentMessage<TComponent> newComponentMessage;
 | 
				
			||||||
            componentMessage.entity = entity;
 | 
					            newComponentMessage.entity = entity;
 | 
				
			||||||
            componentMessage.componentID = componentID;
 | 
					            newComponentMessage.componentID = componentID;
 | 
				
			||||||
            componentMessage.component = component;
 | 
					            newComponentMessage.component = component;
 | 
				
			||||||
            SendMessage(componentMessage);
 | 
					            SendMessage(newComponentMessage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            componentManager.Activate(componentID);
 | 
					            componentManager.Activate(componentID); // TODO: actually delay this to end of frame, make sure to update after activate
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected void DeactivateComponent(Guid componentID)
 | 
					        protected void DeactivateComponent(Guid componentID)
 | 
				
			||||||
| 
						 | 
					@ -165,9 +176,9 @@ namespace Encompass
 | 
				
			||||||
            componentManager.MarkForDeactivation(componentID);
 | 
					            componentManager.MarkForDeactivation(componentID);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected IEnumerable<ValueTuple<Guid, TComponent>> GetComponents<TComponent>(Entity entity) where TComponent : struct, IComponent
 | 
					        private IEnumerable<ValueTuple<Guid, TComponent>> ExistingComponentsOnEntity<TComponent>(Entity entity) where TComponent : struct, IComponent
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!readTypes.Contains(typeof(ComponentMessage<TComponent>)))
 | 
					            if (!receiveTypes.Contains(typeof(ComponentMessage<TComponent>)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
					                throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -175,6 +186,26 @@ namespace Encompass
 | 
				
			||||||
            return ReadMessages<ComponentMessage<TComponent>>().Where((message) => message.entity == entity).Select((message) => (message.componentID, message.component));
 | 
					            return ReadMessages<ComponentMessage<TComponent>>().Where((message) => message.entity == entity).Select((message) => (message.componentID, message.component));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private IEnumerable<ValueTuple<Guid, TComponent>> NewComponentsOnEntity<TComponent>(Entity entity) where TComponent : struct, IComponent
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!receiveTypes.Contains(typeof(NewComponentMessage<TComponent>)))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new IllegalReadException("Engine {0} tried to read undeclared new Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ReadMessages<NewComponentMessage<TComponent>>().Where((message) => message.entity == entity).Select((message) => (message.componentID, message.component));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected IEnumerable<ValueTuple<Guid, TComponent>> GetComponentsIncludingNew<TComponent>(Entity entity) where TComponent : struct, IComponent
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return ExistingComponentsOnEntity<TComponent>(entity).Union(NewComponentsOnEntity<TComponent>(entity));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected IEnumerable<ValueTuple<Guid, TComponent>> GetComponents<TComponent>(Entity entity) where TComponent : struct, IComponent
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return ExistingComponentsOnEntity<TComponent>(entity);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected ValueTuple<Guid, TComponent> GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
 | 
					        protected ValueTuple<Guid, TComponent> GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return GetComponents<TComponent>(entity).First();
 | 
					            return GetComponents<TComponent>(entity).First();
 | 
				
			||||||
| 
						 | 
					@ -182,19 +213,14 @@ namespace Encompass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
 | 
					        protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!readTypes.Contains(typeof(ComponentMessage<TComponent>)))
 | 
					            return GetComponents<TComponent>(entity).Any();
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return ReadMessages<ComponentMessage<TComponent>>().Where((message) => message.entity == entity).Any();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal void UpdateComponentInWorld<TComponent>(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent
 | 
					        internal void UpdateComponentInWorld<TComponent>(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!updateTypes.Contains(typeof(TComponent)))
 | 
					            if (!updateTypes.Contains(typeof(TComponent)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
 | 
					                throw new IllegalSendException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            componentManager.AddUpdateComponentOperation(componentID, newComponent);
 | 
					            componentManager.AddUpdateComponentOperation(componentID, newComponent);
 | 
				
			||||||
| 
						 | 
					@ -209,7 +235,7 @@ namespace Encompass
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!sendTypes.Contains(typeof(TMessage)))
 | 
					            if (!sendTypes.Contains(typeof(TMessage)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new IllegalWriteException("Engine {0} tried to write undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
 | 
					                throw new IllegalSendException("Engine {0} tried to write undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            messageManager.AddMessage(message);
 | 
					            messageManager.AddMessage(message);
 | 
				
			||||||
| 
						 | 
					@ -217,7 +243,7 @@ namespace Encompass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage
 | 
					        protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!readTypes.Contains(typeof(TMessage)))
 | 
					            if (!receiveTypes.Contains(typeof(TMessage)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
 | 
					                throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -230,9 +256,9 @@ namespace Encompass
 | 
				
			||||||
            return ReadMessages<TMessage>().Single();
 | 
					            return ReadMessages<TMessage>().Single();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected IEnumerable<(Guid, TComponent)> ReadComponents<TComponent>() where TComponent : struct, IComponent
 | 
					        protected IEnumerable<ValueTuple<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!readTypes.Contains(typeof(ComponentMessage<TComponent>)))
 | 
					            if (!receiveTypes.Contains(typeof(ComponentMessage<TComponent>)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
 | 
					                throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -240,14 +266,14 @@ namespace Encompass
 | 
				
			||||||
            return ReadMessages<ComponentMessage<TComponent>>().Select((message) => (message.componentID, message.component));
 | 
					            return ReadMessages<ComponentMessage<TComponent>>().Select((message) => (message.componentID, message.component));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected (Guid, TComponent) ReadComponent<TComponent>() where TComponent : struct, IComponent
 | 
					        protected ValueTuple<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return ReadComponents<TComponent>().Single();
 | 
					            return ReadComponents<TComponent>().Single();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected bool SomeMessage<TMessage>() where TMessage : struct, IMessage
 | 
					        protected bool SomeMessage<TMessage>() where TMessage : struct, IMessage
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!readTypes.Contains(typeof(TMessage)))
 | 
					            if (!receiveTypes.Contains(typeof(TMessage)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", GetType().Name, typeof(TMessage).Name);
 | 
					                throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", GetType().Name, typeof(TMessage).Name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -257,7 +283,7 @@ namespace Encompass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected bool SomeComponent<TComponent>() where TComponent : struct, IComponent
 | 
					        protected bool SomeComponent<TComponent>() where TComponent : struct, IComponent
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!readTypes.Contains(typeof(ComponentMessage<TComponent>)))
 | 
					            if (!receiveTypes.Contains(typeof(ComponentMessage<TComponent>)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
					                throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,12 +6,6 @@ namespace Encompass.Engines
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public ComponentMessageEmitter() : base()
 | 
					        public ComponentMessageEmitter() : base()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var writesAttribute = GetType().GetCustomAttribute<Sends>(false);
 | 
					 | 
				
			||||||
            if (writesAttribute != null)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                writesAttribute.sendTypes.Add(typeof(ComponentMessage<TComponent>));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            sendTypes.Add(typeof(ComponentMessage<TComponent>));
 | 
					            sendTypes.Add(typeof(ComponentMessage<TComponent>));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Encompass.Engines
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    internal class NewComponentMessageEmitter<TComponent> : Engine where TComponent : struct, IComponent
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public NewComponentMessageEmitter() : base()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            sendTypes.Add(typeof(NewComponentMessage<TComponent>));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override void Update(double dt)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            foreach (var (entity, componentID, component) in ReadComponentsFromWorld<TComponent>())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                NewComponentMessage<TComponent> newComponentMessage;
 | 
				
			||||||
 | 
					                newComponentMessage.entity = entity;
 | 
				
			||||||
 | 
					                newComponentMessage.componentID = componentID;
 | 
				
			||||||
 | 
					                newComponentMessage.component = component;
 | 
				
			||||||
 | 
					                SendMessage(newComponentMessage);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ namespace Encompass.Engines
 | 
				
			||||||
                readsAttribute.readTypes.Add(typeof(TMessage));
 | 
					                readsAttribute.readTypes.Add(typeof(TMessage));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            readTypes.Add(typeof(TMessage));
 | 
					            receiveTypes.Add(typeof(TMessage));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public override void Update(double dt)
 | 
					        public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,9 +2,9 @@ using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Encompass.Exceptions
 | 
					namespace Encompass.Exceptions
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public class IllegalWriteException : Exception
 | 
					    public class IllegalSendException : Exception
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public IllegalWriteException(
 | 
					        public IllegalSendException(
 | 
				
			||||||
            string format,
 | 
					            string format,
 | 
				
			||||||
            params object[] args
 | 
					            params object[] args
 | 
				
			||||||
        ) : base(string.Format(format, args)) { }
 | 
					        ) : base(string.Format(format, args)) { }
 | 
				
			||||||
| 
						 | 
					@ -2,9 +2,9 @@ using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Encompass.Exceptions
 | 
					namespace Encompass.Exceptions
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public class IllegalWriteTypeException : Exception
 | 
					    public class IllegalSendTypeException : Exception
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public IllegalWriteTypeException(
 | 
					        public IllegalSendTypeException(
 | 
				
			||||||
            string format,
 | 
					            string format,
 | 
				
			||||||
            params object[] args
 | 
					            params object[] args
 | 
				
			||||||
        ) : base(string.Format(format, args)) { }
 | 
					        ) : base(string.Format(format, args)) { }
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Encompass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public struct NewComponentMessage<TComponent> : IMessage where TComponent : struct, IComponent
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public Entity entity;
 | 
				
			||||||
 | 
					        public Guid componentID;
 | 
				
			||||||
 | 
					        public TComponent component;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@ namespace Encompass
 | 
				
			||||||
        private readonly HashSet<Engine> senders = new HashSet<Engine>();
 | 
					        private readonly HashSet<Engine> senders = new HashSet<Engine>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly HashSet<Type> registeredComponentTypes = new HashSet<Type>();
 | 
					        private readonly HashSet<Type> registeredComponentTypes = new HashSet<Type>();
 | 
				
			||||||
 | 
					        private readonly HashSet<Type> registeredNewComponentTypes = new HashSet<Type>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public WorldBuilder()
 | 
					        public WorldBuilder()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -66,6 +67,12 @@ namespace Encompass
 | 
				
			||||||
            AddEngine((Engine)Activator.CreateInstance(typeof(ComponentMessageEmitter<>).MakeGenericType(componentType)));
 | 
					            AddEngine((Engine)Activator.CreateInstance(typeof(ComponentMessageEmitter<>).MakeGenericType(componentType)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal void RegisterNewComponentEmitter(Type componentType)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            registeredNewComponentTypes.Add(componentType);
 | 
				
			||||||
 | 
					            AddEngine((Engine)Activator.CreateInstance(typeof(NewComponentMessageEmitter<>).MakeGenericType(componentType)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Engine AddEngine<TEngine>(TEngine engine) where TEngine : Engine
 | 
					        public Engine AddEngine<TEngine>(TEngine engine) where TEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            engine.AssignEntityManager(entityManager);
 | 
					            engine.AssignEntityManager(entityManager);
 | 
				
			||||||
| 
						 | 
					@ -75,15 +82,10 @@ namespace Encompass
 | 
				
			||||||
            engines.Add(engine);
 | 
					            engines.Add(engine);
 | 
				
			||||||
            engineGraph.AddVertex(engine);
 | 
					            engineGraph.AddVertex(engine);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var activateType in engine.activateTypes)
 | 
					            var messageReceiveTypes = engine.receiveTypes;
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                engine.sendTypes.Add(activateType);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var messageReadTypes = engine.readTypes;
 | 
					 | 
				
			||||||
            var messageSendTypes = engine.sendTypes;
 | 
					            var messageSendTypes = engine.sendTypes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var messageType in messageReadTypes.Intersect(messageSendTypes))
 | 
					            foreach (var messageType in messageReceiveTypes.Intersect(messageSendTypes))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // ComponentMessages can safely self-cycle
 | 
					                // ComponentMessages can safely self-cycle
 | 
				
			||||||
                // this does introduce a gotcha though: if you AddComponent and then HasComponent or GetComponent you will receive a false negative
 | 
					                // this does introduce a gotcha though: if you AddComponent and then HasComponent or GetComponent you will receive a false negative
 | 
				
			||||||
| 
						 | 
					@ -99,23 +101,43 @@ namespace Encompass
 | 
				
			||||||
                senders.Add(engine);
 | 
					                senders.Add(engine);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var readType in engine.readTypes)
 | 
					            foreach (var receiveType in engine.receiveTypes)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (readType.IsGenericType && readType.GetGenericTypeDefinition() == typeof(ComponentMessage<>))
 | 
					                if (receiveType.IsGenericType)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var componentType = readType.GetGenericArguments().Single();
 | 
					                    var genericTypeDefinition = receiveType.GetGenericTypeDefinition();
 | 
				
			||||||
                    if (!registeredComponentTypes.Contains(componentType))
 | 
					                    if (genericTypeDefinition == typeof(ComponentMessage<>) || genericTypeDefinition == typeof(NewComponentMessage<>))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        RegisterComponent(componentType);
 | 
					                        var componentType = receiveType.GetGenericArguments().Single();
 | 
				
			||||||
 | 
					                        if (!registeredComponentTypes.Contains(componentType))
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            RegisterComponent(componentType);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (!typeToReaders.ContainsKey(readType))
 | 
					                if (!typeToReaders.ContainsKey(receiveType))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    typeToReaders.Add(readType, new HashSet<Engine>());
 | 
					                    typeToReaders.Add(receiveType, new HashSet<Engine>());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                typeToReaders[readType].Add(engine);
 | 
					                typeToReaders[receiveType].Add(engine);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (var sendType in engine.sendTypes)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (sendType.IsGenericType)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var genericTypeDefinition = sendType.GetGenericTypeDefinition();
 | 
				
			||||||
 | 
					                    if (genericTypeDefinition == typeof(ComponentMessage<>) || genericTypeDefinition == typeof(NewComponentMessage<>))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        var componentType = sendType.GetGenericArguments().Single();
 | 
				
			||||||
 | 
					                        if (!registeredNewComponentTypes.Contains(componentType))
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            RegisterNewComponentEmitter(componentType);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return engine;
 | 
					            return engine;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,8 @@ namespace Tests
 | 
				
			||||||
        static IEnumerable<(Guid, MockComponent)> gottenMockComponentIDPairs = Enumerable.Empty<(Guid, MockComponent)>();
 | 
					        static IEnumerable<(Guid, MockComponent)> gottenMockComponentIDPairs = Enumerable.Empty<(Guid, MockComponent)>();
 | 
				
			||||||
        static (Guid, MockComponent) gottenMockComponentIDPair;
 | 
					        static (Guid, MockComponent) gottenMockComponentIDPair;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(EntityMessage), typeof(MockComponent))]
 | 
					        [Receives(typeof(EntityMessage))]
 | 
				
			||||||
 | 
					        [Reads(typeof(MockComponent))]
 | 
				
			||||||
        class GetMockComponentEngine : Engine
 | 
					        class GetMockComponentEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -42,7 +43,8 @@ namespace Tests
 | 
				
			||||||
            public MockComponent mockComponent;
 | 
					            public MockComponent mockComponent;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(AddComponentTestMessage), typeof(MockComponent))]
 | 
					        [Receives(typeof(AddComponentTestMessage))]
 | 
				
			||||||
 | 
					        [Reads(typeof(MockComponent))]
 | 
				
			||||||
        class AddComponentTestEngine : Engine
 | 
					        class AddComponentTestEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -109,7 +111,7 @@ namespace Tests
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Activates(typeof(MockComponent))]
 | 
					        [Activates(typeof(MockComponent))]
 | 
				
			||||||
        [Reads(typeof(AddMockComponentMessage))]
 | 
					        [Receives(typeof(AddMockComponentMessage))]
 | 
				
			||||||
        class AddMockComponentEngine : Engine
 | 
					        class AddMockComponentEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -152,7 +154,8 @@ namespace Tests
 | 
				
			||||||
            world.Update(0.01);
 | 
					            world.Update(0.01);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(EntityMessage), typeof(MockComponent))]
 | 
					        [Receives(typeof(EntityMessage))]
 | 
				
			||||||
 | 
					        [Reads(typeof(MockComponent))]
 | 
				
			||||||
        class GetMockComponentsEngine : Engine
 | 
					        class GetMockComponentsEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            private Entity entity;
 | 
					            private Entity entity;
 | 
				
			||||||
| 
						 | 
					@ -264,7 +267,8 @@ namespace Tests
 | 
				
			||||||
            public Entity entity;
 | 
					            public Entity entity;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(HasComponentTestMessage), typeof(MockComponent))]
 | 
					        [Receives(typeof(HasComponentTestMessage))]
 | 
				
			||||||
 | 
					        [Reads(typeof(MockComponent))]
 | 
				
			||||||
        class HasComponentTestEngine : Engine
 | 
					        class HasComponentTestEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -304,7 +308,8 @@ namespace Tests
 | 
				
			||||||
            public Entity entity;
 | 
					            public Entity entity;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(HasComponentWhenInactiveTestMessage), typeof(MockComponent))]
 | 
					        [Receives(typeof(HasComponentWhenInactiveTestMessage))]
 | 
				
			||||||
 | 
					        [Reads(typeof(MockComponent))]
 | 
				
			||||||
        class HasComponentWhenInactiveTestEngine : Engine
 | 
					        class HasComponentWhenInactiveTestEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -346,7 +351,7 @@ namespace Tests
 | 
				
			||||||
            public Guid componentID;
 | 
					            public Guid componentID;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(RemoveComponentTestMessage))]
 | 
					        [Receives(typeof(RemoveComponentTestMessage))]
 | 
				
			||||||
        class RemoveComponentTestEngine : Engine
 | 
					        class RemoveComponentTestEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -358,7 +363,7 @@ namespace Tests
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(RemoveComponentTestMessage))]
 | 
					        [Receives(typeof(RemoveComponentTestMessage))]
 | 
				
			||||||
        [Sends(typeof(CheckHasMockComponentMessage))]
 | 
					        [Sends(typeof(CheckHasMockComponentMessage))]
 | 
				
			||||||
        class DoRemoveCheckEngine : Engine
 | 
					        class DoRemoveCheckEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -421,7 +426,7 @@ namespace Tests
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Activates(typeof(MockComponent))]
 | 
					        [Activates(typeof(MockComponent))]
 | 
				
			||||||
        [Reads(typeof(ActivateComponentMessage))]
 | 
					        [Receives(typeof(ActivateComponentMessage))]
 | 
				
			||||||
        class ActivateComponentEngine : Engine
 | 
					        class ActivateComponentEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -439,7 +444,7 @@ namespace Tests
 | 
				
			||||||
            public bool shouldHaveComponent;
 | 
					            public bool shouldHaveComponent;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(ActivateComponentMessage))]
 | 
					        [Receives(typeof(ActivateComponentMessage))]
 | 
				
			||||||
        [Sends(typeof(CheckHasMockComponentMessage))]
 | 
					        [Sends(typeof(CheckHasMockComponentMessage))]
 | 
				
			||||||
        class DoActivateCheckEngine : Engine
 | 
					        class DoActivateCheckEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -462,7 +467,8 @@ namespace Tests
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(CheckHasMockComponentMessage), typeof(MockComponent))]
 | 
					        [Receives(typeof(CheckHasMockComponentMessage))]
 | 
				
			||||||
 | 
					        [Reads(typeof(MockComponent))]
 | 
				
			||||||
        class CheckHasMockComponentEngine : Engine
 | 
					        class CheckHasMockComponentEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -508,7 +514,7 @@ namespace Tests
 | 
				
			||||||
            public Guid componentID;
 | 
					            public Guid componentID;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(DeactivateComponentMessage))]
 | 
					        [Receives(typeof(DeactivateComponentMessage))]
 | 
				
			||||||
        class DeactivateComponentEngine : Engine
 | 
					        class DeactivateComponentEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -520,7 +526,7 @@ namespace Tests
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(DeactivateComponentMessage))]
 | 
					        [Receives(typeof(DeactivateComponentMessage))]
 | 
				
			||||||
        [Sends(typeof(CheckHasMockComponentMessage))]
 | 
					        [Sends(typeof(CheckHasMockComponentMessage))]
 | 
				
			||||||
        class DoDeactivateCheckEngine : Engine
 | 
					        class DoDeactivateCheckEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,7 +191,7 @@ namespace Tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var world = worldBuilder.Build();
 | 
					            var world = worldBuilder.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var ex = Assert.Throws<IllegalWriteException>(() => world.Update(0.01f));
 | 
					            var ex = Assert.Throws<IllegalSendException>(() => world.Update(0.01f));
 | 
				
			||||||
            Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredUpdateComponentTestEngine tried to write undeclared Component MockComponent"));
 | 
					            Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredUpdateComponentTestEngine tried to write undeclared Component MockComponent"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -212,7 +212,7 @@ namespace Tests
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(MockMessage))]
 | 
					        [Receives(typeof(MockMessage))]
 | 
				
			||||||
        public class MessageReadEngine : Engine
 | 
					        public class MessageReadEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -248,7 +248,7 @@ namespace Tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static IEnumerable<MockMessage> emptyReadMessagesResult;
 | 
					        static IEnumerable<MockMessage> emptyReadMessagesResult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(MockMessage))]
 | 
					        [Receives(typeof(MockMessage))]
 | 
				
			||||||
        class ReadMessagesWhenNoneExistEngine : Engine
 | 
					        class ReadMessagesWhenNoneExistEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -278,7 +278,7 @@ namespace Tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var world = worldBuilder.Build();
 | 
					            var world = worldBuilder.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var ex = Assert.Throws<IllegalWriteException>(() => world.Update(0.01f));
 | 
					            var ex = Assert.Throws<IllegalSendException>(() => world.Update(0.01f));
 | 
				
			||||||
            Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredMessageEmitEngine tried to write undeclared Message MockMessage"));
 | 
					            Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredMessageEmitEngine tried to write undeclared Message MockMessage"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -296,7 +296,7 @@ namespace Tests
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(MockMessage))]
 | 
					        [Receives(typeof(MockMessage))]
 | 
				
			||||||
        class SomeMessageTestEngine : Engine
 | 
					        class SomeMessageTestEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public override void Update(double dt)
 | 
					            public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					@ -666,7 +666,7 @@ namespace Tests
 | 
				
			||||||
            public MockComponent mockComponent;
 | 
					            public MockComponent mockComponent;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Reads(typeof(MockComponentUpdateMessage))]
 | 
					        [Receives(typeof(MockComponentUpdateMessage))]
 | 
				
			||||||
        [Updates(typeof(MockComponent))]
 | 
					        [Updates(typeof(MockComponent))]
 | 
				
			||||||
        class RepeatUpdateEngine : Engine
 | 
					        class RepeatUpdateEngine : Engine
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@ namespace Tests
 | 
				
			||||||
            struct AMessage : IMessage { }
 | 
					            struct AMessage : IMessage { }
 | 
				
			||||||
            struct BMessage : IMessage { }
 | 
					            struct BMessage : IMessage { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [Reads(typeof(AMessage))]
 | 
					            [Receives(typeof(AMessage))]
 | 
				
			||||||
            [Sends(typeof(BMessage))]
 | 
					            [Sends(typeof(BMessage))]
 | 
				
			||||||
            class AEngine : Engine
 | 
					            class AEngine : Engine
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ namespace Tests
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [Reads(typeof(BMessage))]
 | 
					            [Receives(typeof(BMessage))]
 | 
				
			||||||
            [Sends(typeof(AMessage))]
 | 
					            [Sends(typeof(AMessage))]
 | 
				
			||||||
            class BEngine : Engine
 | 
					            class BEngine : Engine
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -53,7 +53,7 @@ namespace Tests
 | 
				
			||||||
            struct CMessage : IMessage { }
 | 
					            struct CMessage : IMessage { }
 | 
				
			||||||
            struct DMessage : IMessage { }
 | 
					            struct DMessage : IMessage { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [Reads(typeof(AMessage))]
 | 
					            [Receives(typeof(AMessage))]
 | 
				
			||||||
            [Sends(typeof(BMessage))]
 | 
					            [Sends(typeof(BMessage))]
 | 
				
			||||||
            class AEngine : Engine
 | 
					            class AEngine : Engine
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -64,7 +64,7 @@ namespace Tests
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [Reads(typeof(BMessage))]
 | 
					            [Receives(typeof(BMessage))]
 | 
				
			||||||
            [Sends(typeof(CMessage))]
 | 
					            [Sends(typeof(CMessage))]
 | 
				
			||||||
            class BEngine : Engine
 | 
					            class BEngine : Engine
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ namespace Tests
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [Reads(typeof(CMessage))]
 | 
					            [Receives(typeof(CMessage))]
 | 
				
			||||||
            [Sends(typeof(DMessage))]
 | 
					            [Sends(typeof(DMessage))]
 | 
				
			||||||
            class CEngine : Engine
 | 
					            class CEngine : Engine
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -86,7 +86,7 @@ namespace Tests
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [Reads(typeof(DMessage))]
 | 
					            [Receives(typeof(DMessage))]
 | 
				
			||||||
            [Sends(typeof(AMessage))]
 | 
					            [Sends(typeof(AMessage))]
 | 
				
			||||||
            class DEngine : Engine
 | 
					            class DEngine : Engine
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -141,7 +141,7 @@ namespace Tests
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            struct AMessage : IMessage { }
 | 
					            struct AMessage : IMessage { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [Reads(typeof(AMessage))]
 | 
					            [Receives(typeof(AMessage))]
 | 
				
			||||||
            [Sends(typeof(AMessage))]
 | 
					            [Sends(typeof(AMessage))]
 | 
				
			||||||
            class AEngine : Engine
 | 
					            class AEngine : Engine
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -200,7 +200,7 @@ namespace Tests
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var worldBuilder = new WorldBuilder();
 | 
					                var worldBuilder = new WorldBuilder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Assert.Throws<IllegalWriteTypeException>(() => worldBuilder.AddEngine(new MyEngine()), "ANonMessage must be a Message or Component");
 | 
					                Assert.Throws<IllegalSendTypeException>(() => worldBuilder.AddEngine(new MyEngine()), "ANonMessage must be a Message or Component");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -234,7 +234,7 @@ namespace Tests
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [Reads(typeof(AMessage), typeof(BMessage))]
 | 
					            [Receives(typeof(AMessage), typeof(BMessage))]
 | 
				
			||||||
            [Sends(typeof(DMessage))]
 | 
					            [Sends(typeof(DMessage))]
 | 
				
			||||||
            class CEngine : Engine
 | 
					            class CEngine : Engine
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -244,7 +244,7 @@ namespace Tests
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [Reads(typeof(DMessage))]
 | 
					            [Receives(typeof(DMessage))]
 | 
				
			||||||
            class DEngine : Engine
 | 
					            class DEngine : Engine
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                public override void Update(double dt)
 | 
					                public override void Update(double dt)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue