started rewriting managers to not reference interfaces

pull/5/head
Evan Hemsley 2019-12-04 20:50:08 -08:00
parent 2a7e97463e
commit 506aee8c37
10 changed files with 131 additions and 197 deletions

View File

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
namespace Encompass
{
internal class ComponentStore
{
private readonly Dictionary<Type, object> Stores = new Dictionary<Type, object>();
private readonly Dictionary<Type, Action> ClearMethods = new Dictionary<Type, Action>();
private Dictionary<Guid, TComponent> Lookup<TComponent>() where TComponent : struct, IComponent
{
if (!Stores.ContainsKey(typeof(TComponent)))
{
var dictionary = new Dictionary<Guid, TComponent>();
Stores.Add(typeof(TComponent), dictionary);
ClearMethods.Add(typeof(TComponent), dictionary.Clear);
}
return Stores[typeof(TComponent)] as Dictionary<Guid, TComponent>;
}
public bool Has<TComponent>(Guid id) where TComponent : struct, IComponent
{
return Lookup<TComponent>().ContainsKey(id);
}
public TComponent Get<TComponent>(Guid id) where TComponent : struct, IComponent
{
return Lookup<TComponent>()[id];
}
public void Set(Type type, Guid id, IComponent component)
{
(Stores[type] as Dictionary<Guid, IComponent>)[id] = component;
}
public void Set<TComponent>(Guid id, TComponent component) where TComponent : struct, IComponent
{
Lookup<TComponent>()[id] = component;
}
public void Remove<TComponent>(Guid id) where TComponent : struct, IComponent
{
Lookup<TComponent>().Remove(id);
}
public void Clear<TComponent>() where TComponent : struct, IComponent
{
Lookup<TComponent>().Clear();
}
public void ClearAll()
{
foreach (var type in Stores.Keys)
{
ClearMethods[type]();
}
}
}
}

View File

@ -11,7 +11,7 @@ namespace Encompass
private readonly DrawLayerManager drawLayerManager; private readonly DrawLayerManager drawLayerManager;
private readonly Dictionary<Guid, Type> componentIDToType = new Dictionary<Guid, Type>(); private readonly Dictionary<Guid, Type> componentIDToType = new Dictionary<Guid, Type>();
private readonly Dictionary<Guid, IComponent> IDToComponent = new Dictionary<Guid, IComponent>(); private readonly ComponentStore IDToComponent = new ComponentStore();
private readonly Dictionary<Guid, PooledSet<Guid>> entityIDToComponentIDs = new Dictionary<Guid, PooledSet<Guid>>(); private readonly Dictionary<Guid, PooledSet<Guid>> entityIDToComponentIDs = new Dictionary<Guid, PooledSet<Guid>>();
private readonly Dictionary<Guid, Guid> componentIDToEntityID = new Dictionary<Guid, Guid>(); private readonly Dictionary<Guid, Guid> componentIDToEntityID = new Dictionary<Guid, Guid>();
@ -79,7 +79,7 @@ namespace Encompass
internal void AddComponent(Entity entity, Type type, Guid componentID, IComponent component) internal void AddComponent(Entity entity, Type type, Guid componentID, IComponent component)
{ {
IDToComponent[componentID] = component; IDToComponent.Set(type, componentID, component);
componentIDToEntityID[componentID] = entity.ID; componentIDToEntityID[componentID] = entity.ID;
componentIDToType[componentID] = type; componentIDToType[componentID] = type;
entityIDToComponentTypeToComponentID[entity.ID][type] = componentID; entityIDToComponentTypeToComponentID[entity.ID][type] = componentID;
@ -133,7 +133,7 @@ namespace Encompass
{ {
if (typeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet)) if (typeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
{ {
return idSet.Select(id => (id, (TComponent)IDToComponent[id])); return idSet.Select(id => (id, IDToComponent.Get<TComponent>(id)));
} }
return Enumerable.Empty<(Guid, TComponent)>(); return Enumerable.Empty<(Guid, TComponent)>();
} }
@ -142,7 +142,7 @@ namespace Encompass
{ {
if (entityIDToComponentTypeToComponentID.ContainsKey(entity.ID) && entityIDToComponentTypeToComponentID[entity.ID].TryGetValue(typeof(TComponent), out Guid id)) if (entityIDToComponentTypeToComponentID.ContainsKey(entity.ID) && entityIDToComponentTypeToComponentID[entity.ID].TryGetValue(typeof(TComponent), out Guid id))
{ {
return (id, (TComponent)IDToComponent[id]); return (id, IDToComponent.Get<TComponent>(id));
} }
throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", typeof(TComponent).Name, entity.ID); throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", typeof(TComponent).Name, entity.ID);
@ -165,7 +165,7 @@ namespace Encompass
internal IComponent GetComponentByID(Guid componentID) internal IComponent GetComponentByID(Guid componentID)
{ {
if (IDToComponent.ContainsKey(componentID)) if (IDToComponent.Has<TComponent>(componentID))
{ {
return IDToComponent[componentID]; return IDToComponent[componentID];
} }
@ -230,7 +230,7 @@ namespace Encompass
componentsMarkedForRemoval.Clear(); componentsMarkedForRemoval.Clear();
} }
private void Remove(Guid componentID) private void Remove<TComponent>(Guid componentID) where TComponent : struct, IComponent
{ {
var type = componentIDToType[componentID]; var type = componentIDToType[componentID];
@ -245,7 +245,7 @@ namespace Encompass
entityIDToComponentTypeToComponentID[entityID].Remove(type); entityIDToComponentTypeToComponentID[entityID].Remove(type);
} }
IDToComponent.Remove(componentID); IDToComponent.Remove<TComponent>(componentID);
componentIDToType.Remove(componentID); componentIDToType.Remove(componentID);
componentIDToEntityID.Remove(componentID); componentIDToEntityID.Remove(componentID);
typeToComponentIDs[type].Remove(componentID); typeToComponentIDs[type].Remove(componentID);

View File

@ -1,14 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Collections.Pooled;
using Encompass.Exceptions; using Encompass.Exceptions;
namespace Encompass namespace Encompass
{ {
class ComponentMessageManager class ComponentMessageManager
{ {
private readonly Dictionary<Guid, IComponent> componentIDToComponent = new Dictionary<Guid, IComponent>(); private readonly ComponentStore componentIDToComponent = new ComponentStore();
private readonly Dictionary<Guid, Type> componentIDToType = new Dictionary<Guid, Type>(); private readonly Dictionary<Guid, Type> componentIDToType = new Dictionary<Guid, Type>();
private readonly Dictionary<Guid, Guid> componentIDToEntityID = new Dictionary<Guid, Guid>(); private readonly Dictionary<Guid, Guid> componentIDToEntityID = new Dictionary<Guid, Guid>();
@ -17,38 +16,15 @@ namespace Encompass
private readonly Dictionary<Type, HashSet<Guid>> componentMessageTypeToPendingComponentIDs = new Dictionary<Type, HashSet<Guid>>(); private readonly Dictionary<Type, HashSet<Guid>> componentMessageTypeToPendingComponentIDs = new Dictionary<Type, HashSet<Guid>>();
private readonly Dictionary<Type, HashSet<Guid>> componentMessageTypeToComponentIDs = new Dictionary<Type, HashSet<Guid>>(); private readonly Dictionary<Type, HashSet<Guid>> componentMessageTypeToComponentIDs = new Dictionary<Type, HashSet<Guid>>();
private readonly Dictionary<Entity, PooledDictionary<Type, Guid>> entityToTypeToExistingComponentID = new Dictionary<Entity, PooledDictionary<Type, Guid>>(); private readonly Dictionary<Type, Dictionary<Entity, Guid>> typeToEntityToExistingComponentID = new Dictionary<Type, Dictionary<Entity, Guid>>();
private readonly Dictionary<Entity, PooledDictionary<Type, Guid>> entityToTypeToPendingComponentID = new Dictionary<Entity, PooledDictionary<Type, Guid>>(); private readonly Dictionary<Type, Dictionary<Entity, Guid>> typeToEntityToPendingComponentID = new Dictionary<Type, Dictionary<Entity, Guid>>();
private readonly Dictionary<Entity, PooledDictionary<Type, Guid>> entityToTypeToComponentID = new Dictionary<Entity, PooledDictionary<Type, Guid>>(); private readonly Dictionary<Type, Dictionary<Entity, Guid>> typeToEntityToComponentID = new Dictionary<Type, Dictionary<Entity, Guid>>();
private readonly Dictionary<Entity, PooledDictionary<Type, int>> entityToTypeToPendingComponentPriority = new Dictionary<Entity, PooledDictionary<Type, int>>(); private readonly Dictionary<Type, Dictionary<Entity, int>> typeToEntityToPendingComponentPriority = new Dictionary<Type, Dictionary<Entity, int>>();
internal void RegisterEntity(Entity entity)
{
entityToTypeToComponentID[entity] = new PooledDictionary<Type, Guid>();
entityToTypeToPendingComponentID[entity] = new PooledDictionary<Type, Guid>();
entityToTypeToPendingComponentPriority[entity] = new PooledDictionary<Type, int>();
entityToTypeToExistingComponentID[entity] = new PooledDictionary<Type, Guid>();
}
internal void RegisterDestroyedEntity(Entity entity)
{
entityToTypeToComponentID[entity].Dispose();
entityToTypeToComponentID.Remove(entity);
entityToTypeToPendingComponentID[entity].Dispose();
entityToTypeToPendingComponentID.Remove(entity);
entityToTypeToPendingComponentPriority[entity].Dispose();
entityToTypeToPendingComponentPriority.Remove(entity);
entityToTypeToExistingComponentID[entity].Dispose();
entityToTypeToExistingComponentID.Remove(entity);
}
internal void ClearMessages() internal void ClearMessages()
{ {
componentIDToComponent.Clear(); componentIDToComponent.ClearAll();
componentIDToType.Clear(); componentIDToType.Clear();
componentIDToEntityID.Clear(); componentIDToEntityID.Clear();
@ -67,22 +43,22 @@ namespace Encompass
set.Clear(); set.Clear();
} }
foreach (var dictionary in entityToTypeToExistingComponentID.Values) foreach (var dictionary in typeToEntityToExistingComponentID.Values)
{ {
dictionary.Clear(); dictionary.Clear();
} }
foreach (var dictionary in entityToTypeToPendingComponentID.Values) foreach (var dictionary in typeToEntityToPendingComponentID.Values)
{ {
dictionary.Clear(); dictionary.Clear();
} }
foreach (var dictionary in entityToTypeToComponentID.Values) foreach (var dictionary in typeToEntityToComponentID.Values)
{ {
dictionary.Clear(); dictionary.Clear();
} }
foreach (var dictionary in entityToTypeToPendingComponentPriority.Values) foreach (var dictionary in typeToEntityToPendingComponentPriority.Values)
{ {
dictionary.Clear(); dictionary.Clear();
} }
@ -99,9 +75,14 @@ namespace Encompass
componentMessageTypeToExistingComponentIDs[typeof(TComponent)].Add(componentMessage.componentID); componentMessageTypeToExistingComponentIDs[typeof(TComponent)].Add(componentMessage.componentID);
if (!entityToTypeToExistingComponentID[componentMessage.entity].ContainsKey(typeof(TComponent))) if (!typeToEntityToExistingComponentID.ContainsKey(typeof(TComponent)))
{ {
entityToTypeToExistingComponentID[componentMessage.entity].Add(typeof(TComponent), componentMessage.componentID); typeToEntityToExistingComponentID.Add(typeof(TComponent), new Dictionary<Entity, Guid>());
}
if (!typeToEntityToExistingComponentID[typeof(TComponent)].ContainsKey(componentMessage.entity))
{
typeToEntityToExistingComponentID[typeof(TComponent)].Add(componentMessage.entity, componentMessage.componentID);
} }
else else
{ {
@ -118,19 +99,25 @@ namespace Encompass
componentMessageTypeToPendingComponentIDs.Add(typeof(TComponent), new HashSet<Guid>()); componentMessageTypeToPendingComponentIDs.Add(typeof(TComponent), new HashSet<Guid>());
} }
if (!entityToTypeToPendingComponentID[pendingComponentMessage.entity].ContainsKey(typeof(TComponent))) if (!typeToEntityToPendingComponentID.ContainsKey(typeof(TComponent)))
{ {
entityToTypeToPendingComponentID[pendingComponentMessage.entity].Add(typeof(TComponent), pendingComponentMessage.componentID); typeToEntityToPendingComponentID.Add(typeof(TComponent), new Dictionary<Entity, Guid>());
entityToTypeToPendingComponentPriority[pendingComponentMessage.entity].Add(typeof(TComponent), pendingComponentMessage.priority); typeToEntityToPendingComponentPriority.Add(typeof(TComponent), new Dictionary<Entity, int>());
}
if (!typeToEntityToPendingComponentID[typeof(TComponent)].ContainsKey(pendingComponentMessage.entity))
{
typeToEntityToPendingComponentID[typeof(TComponent)].Add(pendingComponentMessage.entity, pendingComponentMessage.componentID);
typeToEntityToPendingComponentPriority[typeof(TComponent)].Add(pendingComponentMessage.entity, pendingComponentMessage.priority);
componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Add(pendingComponentMessage.componentID); componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Add(pendingComponentMessage.componentID);
} }
else else
{ {
if (pendingComponentMessage.priority < entityToTypeToPendingComponentPriority[pendingComponentMessage.entity][typeof(TComponent)]) if (pendingComponentMessage.priority < typeToEntityToPendingComponentPriority[typeof(TComponent)][pendingComponentMessage.entity])
{ {
componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Remove(entityToTypeToPendingComponentID[pendingComponentMessage.entity][typeof(TComponent)]); componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Remove(typeToEntityToPendingComponentID[typeof(TComponent)][pendingComponentMessage.entity]);
entityToTypeToPendingComponentID[pendingComponentMessage.entity][typeof(TComponent)] = pendingComponentMessage.componentID; typeToEntityToPendingComponentID[typeof(TComponent)][pendingComponentMessage.entity] = pendingComponentMessage.componentID;
entityToTypeToPendingComponentPriority[pendingComponentMessage.entity][typeof(TComponent)] = pendingComponentMessage.priority; typeToEntityToPendingComponentPriority[typeof(TComponent)][pendingComponentMessage.entity] = pendingComponentMessage.priority;
componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Add(pendingComponentMessage.componentID); componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Add(pendingComponentMessage.componentID);
} }
} }
@ -138,7 +125,7 @@ namespace Encompass
private void RegisterExistingOrPendingComponentMessage<TComponent>(Entity entity, Guid componentID, TComponent component) where TComponent : struct, IComponent private void RegisterExistingOrPendingComponentMessage<TComponent>(Entity entity, Guid componentID, TComponent component) where TComponent : struct, IComponent
{ {
componentIDToComponent[componentID] = component; componentIDToComponent.Set(componentID, component);
componentIDToEntityID[componentID] = entity.ID; componentIDToEntityID[componentID] = entity.ID;
componentIDToType[componentID] = typeof(TComponent); componentIDToType[componentID] = typeof(TComponent);
@ -148,7 +135,11 @@ namespace Encompass
} }
componentMessageTypeToComponentIDs[typeof(TComponent)].Add(componentID); componentMessageTypeToComponentIDs[typeof(TComponent)].Add(componentID);
entityToTypeToComponentID[entity][typeof(TComponent)] = componentID; if (!typeToEntityToComponentID.ContainsKey(typeof(TComponent)))
{
typeToEntityToComponentID.Add(typeof(TComponent), new Dictionary<Entity, Guid>());
}
typeToEntityToComponentID[typeof(TComponent)][entity] = componentID;
} }
// general component reads by type // general component reads by type
@ -157,7 +148,7 @@ namespace Encompass
{ {
if (componentMessageTypeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet)) if (componentMessageTypeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
{ {
return idSet.Select(id => (id, (TComponent)componentIDToComponent[id])); return idSet.Select(id => (id, componentIDToComponent.Get<TComponent>(id)));
} }
return Enumerable.Empty<(Guid, TComponent)>(); return Enumerable.Empty<(Guid, TComponent)>();
@ -167,7 +158,7 @@ namespace Encompass
{ {
if (componentMessageTypeToExistingComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet)) if (componentMessageTypeToExistingComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
{ {
return idSet.Select(id => (id, (TComponent)componentIDToComponent[id])); return idSet.Select(id => (id, componentIDToComponent.Get<TComponent>(id)));
} }
return Enumerable.Empty<(Guid, TComponent)>(); return Enumerable.Empty<(Guid, TComponent)>();
@ -177,7 +168,7 @@ namespace Encompass
{ {
if (componentMessageTypeToPendingComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet)) if (componentMessageTypeToPendingComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
{ {
return idSet.Select(id => (id, (TComponent)componentIDToComponent[id])); return idSet.Select(id => (id, componentIDToComponent.Get<TComponent>(id)));
} }
return Enumerable.Empty<(Guid, TComponent)>(); return Enumerable.Empty<(Guid, TComponent)>();
@ -239,9 +230,9 @@ namespace Encompass
internal (Guid, TComponent) ReadExistingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent internal (Guid, TComponent) ReadExistingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
if (entityToTypeToExistingComponentID.ContainsKey(entity) && entityToTypeToExistingComponentID[entity].TryGetValue(typeof(TComponent), out Guid id)) if (typeToEntityToExistingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToExistingComponentID[typeof(TComponent)].TryGetValue(entity, out Guid id))
{ {
return (id, (TComponent)componentIDToComponent[id]); return (id, componentIDToComponent.Get<TComponent>(id));
} }
else else
{ {
@ -249,23 +240,11 @@ namespace Encompass
} }
} }
internal (Guid, IComponent) ReadExistingComponentByEntityAndType(Entity entity, Type type)
{
if (entityToTypeToExistingComponentID.ContainsKey(entity) && entityToTypeToExistingComponentID[entity].TryGetValue(type, out Guid id))
{
return (id, componentIDToComponent[id]);
}
else
{
throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", type.Name, entity.ID);
}
}
internal (Guid, TComponent) ReadPendingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent internal (Guid, TComponent) ReadPendingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
if (entityToTypeToPendingComponentID.ContainsKey(entity) && entityToTypeToPendingComponentID[entity].TryGetValue(typeof(TComponent), out Guid id)) if (typeToEntityToPendingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToPendingComponentID[typeof(TComponent)].TryGetValue(entity, out Guid id))
{ {
return (id, (TComponent)componentIDToComponent[id]); return (id, componentIDToComponent.Get<TComponent>(id));
} }
else else
{ {
@ -273,55 +252,43 @@ namespace Encompass
} }
} }
internal (Guid, IComponent) ReadPendingComponentByEntityAndType(Entity entity, Type type)
{
if (entityToTypeToPendingComponentID.ContainsKey(entity) && entityToTypeToPendingComponentID[entity].TryGetValue(type, out Guid id))
{
return (id, componentIDToComponent[id]);
}
else
{
throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", type.Name, entity.ID);
}
}
// check if entity has component of type // check if entity has component of type
internal bool HasExistingOrPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent internal bool HasExistingOrPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return entityToTypeToComponentID.ContainsKey(entity) && entityToTypeToComponentID[entity].ContainsKey(typeof(TComponent)); return typeToEntityToComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToComponentID[typeof(TComponent)].ContainsKey(entity);
} }
internal bool HasExistingOrPendingComponent(Entity entity, Type type) internal bool HasExistingOrPendingComponent(Entity entity, Type type)
{ {
return entityToTypeToComponentID.ContainsKey(entity) && entityToTypeToComponentID[entity].ContainsKey(type); return typeToEntityToComponentID.ContainsKey(type) && typeToEntityToComponentID[type].ContainsKey(entity);
} }
internal bool HasExistingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent internal bool HasExistingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return entityToTypeToExistingComponentID.ContainsKey(entity) && entityToTypeToExistingComponentID[entity].ContainsKey(typeof(TComponent)); return typeToEntityToExistingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToExistingComponentID[typeof(TComponent)].ContainsKey(entity);
} }
internal bool HasExistingComponent(Entity entity, Type type) internal bool HasExistingComponent(Entity entity, Type type)
{ {
return entityToTypeToExistingComponentID.ContainsKey(entity) && entityToTypeToExistingComponentID[entity].ContainsKey(type); return typeToEntityToExistingComponentID.ContainsKey(type) && typeToEntityToExistingComponentID[type].ContainsKey(entity);
} }
internal bool HasPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent internal bool HasPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return entityToTypeToPendingComponentID.ContainsKey(entity) && entityToTypeToPendingComponentID[entity].ContainsKey(typeof(TComponent)); return typeToEntityToPendingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToPendingComponentID[typeof(TComponent)].ContainsKey(entity);
} }
internal bool HasPendingComponent(Entity entity, Type type) internal bool HasPendingComponent(Entity entity, Type type)
{ {
return entityToTypeToPendingComponentID.ContainsKey(entity) && entityToTypeToPendingComponentID[entity].ContainsKey(type); return typeToEntityToPendingComponentID.ContainsKey(type) && typeToEntityToPendingComponentID[type].ContainsKey(entity);
} }
internal IComponent GetComponentByID(Guid componentID) internal TComponent GetComponentByID<TComponent>(Guid componentID) where TComponent : struct, IComponent
{ {
if (componentIDToComponent.ContainsKey(componentID)) if (componentIDToComponent.Has<TComponent>(componentID))
{ {
return componentIDToComponent[componentID]; return componentIDToComponent.Get<TComponent>(componentID);
} }
else else
{ {

View File

@ -183,7 +183,7 @@ namespace Encompass
/// </summary> /// </summary>
protected Entity ReadEntity<TComponent>() where TComponent : struct, IComponent protected Entity ReadEntity<TComponent>() where TComponent : struct, IComponent
{ {
var (id, component) = ReadComponentHelper<TComponent>(); var (id, _) = ReadComponentHelper<TComponent>();
return GetEntityByComponentID<TComponent>(id); return GetEntityByComponentID<TComponent>(id);
} }
@ -216,7 +216,7 @@ namespace Encompass
throw new ComponentTypeMismatchException("Expected Component to be of type {0} but was actually of type {1}", typeof(TComponent).Name, componentMessageManager.GetComponentTypeByID(componentID).Name); throw new ComponentTypeMismatchException("Expected Component to be of type {0} but was actually of type {1}", typeof(TComponent).Name, componentMessageManager.GetComponentTypeByID(componentID).Name);
} }
return (TComponent)componentMessageManager.GetComponentByID(componentID); return componentMessageManager.GetComponentByID<TComponent>(componentID);
} }
// these next two are for the ComponentMessageEmitter only // these next two are for the ComponentMessageEmitter only
@ -380,57 +380,6 @@ namespace Encompass
return GetComponentHelper<TComponent>(entity).Item2; return GetComponentHelper<TComponent>(entity).Item2;
} }
private (Guid, IComponent) GetComponentHelper(Entity entity, Type type)
{
var pending = typeof(PendingComponentMessage<>).MakeGenericType(type);
var existing = typeof(ComponentMessage<>).MakeGenericType(type);
var pendingRead = receiveTypes.Contains(pending);
var existingRead = receiveTypes.Contains(existing);
if (existingRead && pendingRead)
{
if (componentMessageManager.HasPendingComponent(entity, pending))
{
return componentMessageManager.ReadPendingComponentByEntityAndType(entity, pending);
}
else if (componentMessageManager.HasExistingComponent(entity, existing))
{
return componentMessageManager.ReadExistingComponentByEntityAndType(entity, existing);
}
else
{
throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", type.Name, entity.ID);
}
}
else if (existingRead)
{
return componentMessageManager.ReadExistingComponentByEntityAndType(entity, existing);
}
else if (pendingRead)
{
return componentMessageManager.ReadPendingComponentByEntityAndType(entity, pending);
}
else
{
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, type.Name);
}
}
/// <summary>
/// Returns a Component with the specified Type that exists on the Entity.
/// </summary>
/// <exception cref="Encompass.Exceptions.NoComponentOfTypeOnEntityException">
/// Thrown when the Entity does not have a Component of the specified Type
/// </exception>
/// <exception cref="Encompass.Exceptions.IllegalReadException">
/// Thrown when the Engine does not declare that it reads the given Component Type.
/// </exception>
protected IComponent GetComponent(Entity entity, Type type)
{
return GetComponentHelper(entity, type).Item2;
}
/// <summary> /// <summary>
/// Returns true if the Entity has a Component of the given Type. /// Returns true if the Entity has a Component of the given Type.
/// </summary> /// </summary>
@ -673,7 +622,7 @@ namespace Encompass
{ {
if (!HasComponent<TComponent>(entity)) { return false; } if (!HasComponent<TComponent>(entity)) { return false; }
var (componentID, component) = GetComponentHelper<TComponent>(entity); var (componentID, _) = GetComponentHelper<TComponent>(entity);
RemoveComponent(componentID); RemoveComponent(componentID);

View File

@ -12,12 +12,10 @@ namespace Encompass
private readonly HashSet<Guid> entitiesMarkedForDestroy = new HashSet<Guid>(); private readonly HashSet<Guid> entitiesMarkedForDestroy = new HashSet<Guid>();
private readonly ComponentManager componentManager; private readonly ComponentManager componentManager;
private readonly ComponentMessageManager componentMessageManager;
public EntityManager(ComponentManager componentManager, ComponentMessageManager componentMessageManager) public EntityManager(ComponentManager componentManager)
{ {
this.componentManager = componentManager; this.componentManager = componentManager;
this.componentMessageManager = componentMessageManager;
} }
public Entity CreateEntity() public Entity CreateEntity()
@ -26,7 +24,6 @@ namespace Encompass
var entity = new Entity(id); var entity = new Entity(id);
IDToEntity[id] = entity; IDToEntity[id] = entity;
componentManager.RegisterEntity(id); componentManager.RegisterEntity(id);
componentMessageManager.RegisterEntity(entity);
return entity; return entity;
} }
@ -56,7 +53,6 @@ namespace Encompass
{ {
foreach (var entityID in entitiesMarkedForDestroy) foreach (var entityID in entitiesMarkedForDestroy)
{ {
componentMessageManager.RegisterDestroyedEntity(GetEntity(entityID));
componentManager.MarkAllComponentsOnEntityForRemoval(entityID); componentManager.MarkAllComponentsOnEntityForRemoval(entityID);
IDToEntity.Remove(entityID); IDToEntity.Remove(entityID);
componentManager.RegisterDestroyedEntity(entityID); componentManager.RegisterDestroyedEntity(entityID);

View File

@ -6,7 +6,7 @@ namespace Encompass
{ {
internal class MessageManager internal class MessageManager
{ {
private TimeManager timeManager; private readonly TimeManager timeManager;
private readonly Dictionary<Type, List<IMessage>> messageTypeToMessages = new Dictionary<Type, List<IMessage>>(); private readonly Dictionary<Type, List<IMessage>> messageTypeToMessages = new Dictionary<Type, List<IMessage>>();

View File

@ -5,7 +5,7 @@ namespace Encompass
{ {
internal class TimeManager internal class TimeManager
{ {
private List<TimeDilationData> timeDilationDatas = new List<TimeDilationData>(); private readonly List<TimeDilationData> timeDilationDatas = new List<TimeDilationData>(32);
private double Linear(double t, double b, double c, double d) private double Linear(double t, double b, double c, double d)
{ {

View File

@ -42,7 +42,7 @@ namespace Encompass
componentManager = new ComponentManager(drawLayerManager); componentManager = new ComponentManager(drawLayerManager);
messageManager = new MessageManager(timeManager); messageManager = new MessageManager(timeManager);
componentMessageManager = new ComponentMessageManager(); componentMessageManager = new ComponentMessageManager();
entityManager = new EntityManager(componentManager, componentMessageManager); entityManager = new EntityManager(componentManager);
renderManager = new RenderManager(componentManager, drawLayerManager, entityManager); renderManager = new RenderManager(componentManager, drawLayerManager, entityManager);
} }

View File

@ -9,7 +9,7 @@
<Company>Moonside Games</Company> <Company>Moonside Games</Company>
<Product>Encompass ECS</Product> <Product>Encompass ECS</Product>
<PackageProjectUrl>https://github.com/encompass-ecs</PackageProjectUrl> <PackageProjectUrl>https://github.com/encompass-ecs</PackageProjectUrl>
<PackageLicenseUrl/> <PackageLicenseUrl />
<Copyright>Evan Hemsley 2019</Copyright> <Copyright>Evan Hemsley 2019</Copyright>
<Description>Encompass is an engine-agnostic Hyper ECS framework to help you code games, or other kinds of simulations.</Description> <Description>Encompass is an engine-agnostic Hyper ECS framework to help you code games, or other kinds of simulations.</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
@ -19,11 +19,11 @@
<ItemGroup> <ItemGroup>
<None Include="..\LICENSE"> <None Include="..\LICENSE">
<Pack>True</Pack> <Pack>True</Pack>
<PackagePath/> <PackagePath />
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Collections.Pooled" Version="1.0.82"/> <PackageReference Include="Collections.Pooled" Version="1.0.82" />
<PackageReference Include="MoonTools.Core.Graph" Version="1.0.0"/> <PackageReference Include="MoonTools.Core.Graph" Version="1.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -267,45 +267,6 @@ namespace Tests
Assert.AreEqual(mockComponent, gottenMockComponent); Assert.AreEqual(mockComponent, gottenMockComponent);
} }
[Receives(typeof(EntityMessage))]
[Reads(typeof(MockComponent))]
class GetMockComponentByRuntimeType : Engine
{
public override void Update(double dt)
{
foreach (var entityMessage in ReadMessages<EntityMessage>())
{
gottenMockComponent = (MockComponent)GetComponent(entityMessage.entity, typeof(MockComponent));
}
}
}
[Test]
public void GetComponentByRuntimeType()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new GetMockComponentEngine());
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 3;
mockComponent.myString = "hello";
worldBuilder.SetComponent<MockComponent>(entity, mockComponent);
EntityMessage entityMessage;
entityMessage.entity = entity;
worldBuilder.SendMessage(entityMessage);
var world = worldBuilder.Build();
world.Update(0.01);
Assert.AreEqual(mockComponent, gottenMockComponent);
}
struct HasComponentTestMessage : IMessage struct HasComponentTestMessage : IMessage
{ {
public Entity entity; public Entity entity;