using System; using System.Reflection; using System.Collections.Generic; namespace Encompass { public abstract class Engine { public readonly List mutateComponentTypes = new List(); private EntityManager entityManager; private ComponentManager componentManager; public Engine() { var mutatesAttribute = this.GetType().GetCustomAttribute(false); if (mutatesAttribute != null) { mutateComponentTypes = mutatesAttribute.mutateComponentTypes; } } internal void AssignEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } internal void AssignComponentManager(ComponentManager componentManager) { this.componentManager = componentManager; } 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 TComponent ReadComponent() where TComponent : struct, IComponent { return this.componentManager.GetActiveComponentByType(); } internal void UpdateComponentInWorld(TComponent originalComponent, TComponent newComponent) where TComponent : struct, IComponent { if (mutateComponentTypes.Contains(typeof(TComponent))) { this.componentManager.UpdateComponent(originalComponent, newComponent); } else { throw new IllegalComponentMutationException("Engine {0} tried to mutate undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); } } protected void UpdateComponent(TComponent component, Func updateFunction) where TComponent : struct, IComponent { var updatedComponent = updateFunction(component); this.UpdateComponentInWorld(component, updatedComponent); } protected void UpdateComponents(IEnumerable components, Func updateFunction) where TComponent : struct, IComponent { foreach (var component in components) { this.UpdateComponent(component, updateFunction); } } } }