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) { _componentManager = componentManager; _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); } } } } }