encompass-cs/encompass-cs/EntityManager.cs

157 lines
5.4 KiB
C#
Raw Normal View History

2019-07-29 02:54:15 +00:00
using System.Collections.Concurrent;
using System;
using System.Collections.Generic;
2019-06-16 01:05:56 +00:00
namespace Encompass
{
internal class EntityManager
{
2019-07-29 02:54:15 +00:00
private readonly ConcurrentDictionary<Guid, Entity> IDToEntity = new ConcurrentDictionary<Guid, Entity>();
private readonly HashSet<Guid> entitiesMarkedForDestroy = new HashSet<Guid>();
2019-06-19 23:13:02 +00:00
2019-06-20 17:46:15 +00:00
private readonly Dictionary<Type, HashSet<IEntityTracker>> componentTypeToEntityTrackers = new Dictionary<Type, HashSet<IEntityTracker>>();
private readonly Dictionary<Guid, HashSet<IEntityTracker>> entityToEntityTrackers = new Dictionary<Guid, HashSet<IEntityTracker>>();
2019-06-19 23:13:02 +00:00
2019-07-29 02:54:15 +00:00
private readonly ConcurrentDictionary<Guid, byte> entitiesWithAddedComponents;
private readonly ConcurrentDictionary<Guid, byte> entitiesWithRemovedComponents;
2019-06-20 17:46:15 +00:00
private readonly ComponentManager componentManager;
public EntityManager(
2019-06-19 23:13:02 +00:00
ComponentManager componentManager,
2019-07-29 02:54:15 +00:00
ConcurrentDictionary<Guid, byte> entitiesWithAddedComponents,
ConcurrentDictionary<Guid, byte> entitiesWithRemovedComponents
2019-06-16 01:05:56 +00:00
)
{
this.componentManager = componentManager;
2019-06-19 23:13:02 +00:00
this.entitiesWithAddedComponents = entitiesWithAddedComponents;
this.entitiesWithRemovedComponents = entitiesWithRemovedComponents;
}
2019-06-16 01:05:56 +00:00
public Entity CreateEntity()
{
2019-06-19 23:13:02 +00:00
var id = NextID();
2019-07-17 18:24:21 +00:00
var entity = new Entity(id);
2019-06-19 23:13:02 +00:00
IDToEntity[id] = entity;
componentManager.RegisterEntity(id);
2019-06-19 23:13:02 +00:00
return entity;
}
public bool EntityExists(Guid id)
{
return IDToEntity.ContainsKey(id);
}
public Entity GetEntity(Guid id)
2019-06-16 01:05:56 +00:00
{
2019-06-19 21:14:44 +00:00
return IDToEntity[id];
}
2019-06-19 23:13:02 +00:00
public void MarkForDestroy(Guid entityID)
2019-06-16 01:05:56 +00:00
{
2019-06-19 23:13:02 +00:00
entitiesMarkedForDestroy.Add(entityID);
}
2019-06-19 23:13:02 +00:00
public void DestroyMarkedEntities()
2019-06-16 01:05:56 +00:00
{
2019-06-19 23:13:02 +00:00
foreach (var entityID in entitiesMarkedForDestroy)
2019-06-16 01:05:56 +00:00
{
componentManager.MarkAllComponentsOnEntityForRemoval(entityID);
2019-07-29 02:54:15 +00:00
IDToEntity.TryRemove(entityID, out _);
2019-06-19 23:13:02 +00:00
entityToEntityTrackers.Remove(entityID);
2019-06-20 03:37:46 +00:00
componentManager.RegisterDestroyedEntity(entityID);
}
2019-06-19 23:13:02 +00:00
entitiesMarkedForDestroy.Clear();
}
private Guid NextID()
2019-06-16 01:05:56 +00:00
{
return Guid.NewGuid();
}
2019-06-19 23:13:02 +00:00
public void RegisterEntityTracker(IEntityTracker entityTracker)
{
foreach (var componentType in entityTracker.ComponentTypes)
{
if (!componentTypeToEntityTrackers.ContainsKey(componentType))
{
componentTypeToEntityTrackers.Add(componentType, new HashSet<IEntityTracker>());
}
componentTypeToEntityTrackers[componentType].Add(entityTracker);
}
if (entityTracker is EntityRenderer)
{
var entityRenderer = entityTracker as EntityRenderer;
if (!componentTypeToEntityTrackers.ContainsKey(entityRenderer.DrawComponentType))
{
componentTypeToEntityTrackers.Add(entityRenderer.DrawComponentType, new HashSet<IEntityTracker>());
}
componentTypeToEntityTrackers[entityRenderer.DrawComponentType].Add(entityRenderer);
}
}
public void RegisterDirtyEntityWithAddedComponents(Guid entityID)
{
2019-07-29 02:54:15 +00:00
entitiesWithAddedComponents.TryAdd(entityID, 0);
2019-06-19 23:13:02 +00:00
}
public void RegisterDirtyEntityWithRemovedComponents(Guid entityID)
{
2019-07-29 02:54:15 +00:00
entitiesWithRemovedComponents.TryAdd(entityID, 0);
2019-06-19 23:13:02 +00:00
}
public void CheckEntitiesWithAddedComponents()
{
2019-07-29 02:54:15 +00:00
foreach (var entityID in entitiesWithAddedComponents.Keys)
2019-06-19 23:13:02 +00:00
{
CheckAndRegisterEntity(entityID);
}
entitiesWithAddedComponents.Clear();
}
public void CheckEntitiesWithRemovedComponents()
{
2019-07-29 02:54:15 +00:00
foreach (var entityID in entitiesWithRemovedComponents.Keys)
2019-06-19 23:13:02 +00:00
{
if (entityToEntityTrackers.ContainsKey(entityID))
{
foreach (var engine in entityToEntityTrackers[entityID])
{
engine.CheckAndUntrackEntity(entityID);
}
}
}
entitiesWithRemovedComponents.Clear();
}
private void CheckAndRegisterEntity(Guid entityID)
{
var componentTypes = componentManager.GetAllComponentTypesOfEntity(entityID);
foreach (var componentType in componentTypes)
{
if (componentTypeToEntityTrackers.ContainsKey(componentType))
{
foreach (var entityTracker in componentTypeToEntityTrackers[componentType])
{
if (entityTracker.CheckAndTrackEntity(entityID))
{
if (!entityToEntityTrackers.ContainsKey(entityID))
{
entityToEntityTrackers.Add(entityID, new HashSet<IEntityTracker>());
}
entityToEntityTrackers[entityID].Add(entityTracker);
}
}
}
}
}
}
}