using System; using System.Reflection; using System.Collections.Generic; using System.Linq; namespace Encompass { public abstract class Engine { private readonly List mutateComponentTypes = new List(); private readonly List emitMessageTypes = new List(); private readonly List readMessageTypes = new List(); private EntityManager entityManager; private ComponentManager componentManager; private MessageManager messageManager; public Engine() { var mutatesAttribute = this.GetType().GetCustomAttribute(false); if (mutatesAttribute != null) { mutateComponentTypes = mutatesAttribute.mutateComponentTypes; } var emitsAttribute = this.GetType().GetCustomAttribute(false); if (emitsAttribute != null) { emitMessageTypes = emitsAttribute.emitMessageTypes; } var readsAttribute = this.GetType().GetCustomAttribute(false); if (readsAttribute != null) { readMessageTypes = readsAttribute.readMessageTypes; } } internal void AssignEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } internal void AssignComponentManager(ComponentManager componentManager) { this.componentManager = componentManager; } internal void AssignMessageManager(MessageManager messageManager) { this.messageManager = messageManager; } public abstract void Update(float dt); protected Entity CreateEntity() { return this.entityManager.CreateEntity(); } protected IEnumerable> ReadComponents() where TComponent : struct, IComponent { return this.componentManager.GetActiveComponentsByType(); } protected KeyValuePair ReadComponent() where TComponent : struct, IComponent { return this.componentManager.GetActiveComponentByType(); } internal void UpdateComponentInWorld(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent { if (mutateComponentTypes.Contains(typeof(TComponent))) { this.componentManager.UpdateComponent(componentID, newComponent); } else { throw new IllegalComponentMutationException("Engine {0} tried to mutate undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); } } protected void UpdateComponent(Guid componentID, TComponent newComponentValue) where TComponent : struct, IComponent { this.UpdateComponentInWorld(componentID, newComponentValue); } protected void EmitMessage(TMessage message) where TMessage : struct, IMessage { if (emitMessageTypes.Contains(typeof(TMessage))) { this.messageManager.AddMessage(message); } else { throw new IllegalMessageEmitException("Engine {0} tried to emit undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); } } protected IEnumerable ReadMessages() where TMessage : struct, IMessage { if (readMessageTypes.Contains(typeof(TMessage))) { return this.messageManager.GetMessagesByType(); } else { throw new IllegalMessageReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); } } protected bool Some() where TMessage : struct, IMessage { if (readMessageTypes.Contains(typeof(TMessage))) { return messageManager.GetMessagesByType().Count() > 0; } else { throw new IllegalMessageReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); } } } }