started rewriting managers to not reference interfaces
parent
2a7e97463e
commit
506aee8c37
|
@ -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]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>>();
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue