encompass-cs/encompass-cs/EntityManager.cs

93 lines
2.5 KiB
C#

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<int> _ids = new HashSet<int>();
private readonly HashSet<int> _entitiesMarkedForDestroy = new HashSet<int>();
private readonly ComponentManager _componentManager;
public IEnumerable<int> 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<Engine> 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);
}
}
}
}
}