using System.Collections.Generic; using Encompass.Exceptions; namespace Encompass { internal class EntityManager { private readonly int entityCapacity; private readonly IDManager idManager = new IDManager(); private readonly HashSet IDs = new HashSet(); private readonly HashSet entitiesMarkedForDestroy = new HashSet(); private readonly ComponentManager componentManager; public IEnumerable EntityIDs { get { return IDs; } } public EntityManager(ComponentManager componentManager, int entityCapacity) { this.componentManager = componentManager; this.entityCapacity = entityCapacity; } private int NextID() { return idManager.NextID(); } public Entity CreateEntity() { if (IDs.Count < entityCapacity) { var id = NextID(); var entity = new Entity(id); IDs.Add(id); return entity; } else { throw new EntityOverflowException("The number of entities has exceeded the entity capacity of {0}", entityCapacity); } } public bool EntityExists(int id) { return IDs.Contains(id); } public Entity GetEntity(int id) { if (!EntityExists(id)) { throw new Encompass.Exceptions.EntityNotFoundException("Entity with id {0} does not exist.", id); } return new Entity(id); } public void MarkForDestroy(int entityID) { entitiesMarkedForDestroy.Add(entityID); } public void DestroyMarkedEntities(IEnumerable engines) { foreach (var entityID in entitiesMarkedForDestroy) { foreach (var engine in engines) { engine.RegisterDestroyedEntity(entityID); } componentManager.MarkAllComponentsOnEntityForRemoval(entityID); IDs.Remove(entityID); idManager.Free(entityID); } entitiesMarkedForDestroy.Clear(); } // NOTE: this is very suboptimal public void PruneEmptyEntities() { foreach (var id in EntityIDs) { if (componentManager.UpToDateEntityIsEmpty(id)) { MarkForDestroy(id); } } } } }