start removing component ID system
parent
506aee8c37
commit
a4c3040239
|
@ -1,48 +1,141 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Encompass
|
namespace Encompass
|
||||||
{
|
{
|
||||||
internal class ComponentStore
|
internal class ComponentStore
|
||||||
{
|
{
|
||||||
private readonly Dictionary<Type, object> Stores = new Dictionary<Type, object>();
|
interface IComponentStore
|
||||||
private readonly Dictionary<Type, Action> ClearMethods = new Dictionary<Type, Action>();
|
{
|
||||||
|
T All<T>() where T : struct, IComponent;
|
||||||
|
}
|
||||||
|
|
||||||
private Dictionary<Guid, TComponent> Lookup<TComponent>() where TComponent : struct, IComponent
|
abstract class TypedComponentStore
|
||||||
|
{
|
||||||
|
public abstract int Count { get; }
|
||||||
|
public abstract bool Has(Entity entity);
|
||||||
|
public abstract bool Remove(Entity entity);
|
||||||
|
public abstract void Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TypedComponentStore<TComponent> : TypedComponentStore where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
private readonly Dictionary<Entity, TComponent> store = new Dictionary<Entity, TComponent>();
|
||||||
|
private readonly Dictionary<Entity, int> priorities = new Dictionary<Entity, int>();
|
||||||
|
|
||||||
|
public override int Count { get => store.Count; }
|
||||||
|
|
||||||
|
public TComponent Get(Entity entity)
|
||||||
|
{
|
||||||
|
return store[entity];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set(Entity entity, TComponent component)
|
||||||
|
{
|
||||||
|
store[entity] = component;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set(Entity entity, TComponent component, int priority)
|
||||||
|
{
|
||||||
|
if (!priorities.ContainsKey(entity) || priority < priorities[entity]) {
|
||||||
|
store[entity] = component;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Has(Entity entity)
|
||||||
|
{
|
||||||
|
return store.ContainsKey(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Clear()
|
||||||
|
{
|
||||||
|
store.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<(Entity, TComponent)> All()
|
||||||
|
{
|
||||||
|
return store.Select(kvp => (kvp.Key, kvp.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// public override IEnumerable<T> All<T>()
|
||||||
|
// {
|
||||||
|
// return store.Values.Cast<T>();
|
||||||
|
// }
|
||||||
|
|
||||||
|
public override bool Remove(Entity entity)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Dictionary<Type, TypedComponentStore> Stores = new Dictionary<Type, TypedComponentStore>();
|
||||||
|
|
||||||
|
public void RegisterComponentType<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (!Stores.ContainsKey(typeof(TComponent)))
|
if (!Stores.ContainsKey(typeof(TComponent)))
|
||||||
{
|
{
|
||||||
var dictionary = new Dictionary<Guid, TComponent>();
|
var store = new TypedComponentStore<TComponent>();
|
||||||
Stores.Add(typeof(TComponent), dictionary);
|
Stores.Add(typeof(TComponent), store);
|
||||||
ClearMethods.Add(typeof(TComponent), dictionary.Clear);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Stores[typeof(TComponent)] as Dictionary<Guid, TComponent>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Has<TComponent>(Guid id) where TComponent : struct, IComponent
|
private TypedComponentStore<TComponent> Lookup<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return Lookup<TComponent>().ContainsKey(id);
|
return Stores[typeof(TComponent)] as TypedComponentStore<TComponent>;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TComponent Get<TComponent>(Guid id) where TComponent : struct, IComponent
|
public bool Has<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return Lookup<TComponent>()[id];
|
return Lookup<TComponent>().Has(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(Type type, Guid id, IComponent component)
|
public bool Has(Type type, Entity entity)
|
||||||
{
|
{
|
||||||
(Stores[type] as Dictionary<Guid, IComponent>)[id] = component;
|
return Stores[type].Has(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set<TComponent>(Guid id, TComponent component) where TComponent : struct, IComponent
|
public TComponent Get<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
Lookup<TComponent>()[id] = component;
|
return Lookup<TComponent>().Get(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove<TComponent>(Guid id) where TComponent : struct, IComponent
|
public void Set<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
Lookup<TComponent>().Remove(id);
|
Lookup<TComponent>().Set(entity, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
Lookup<TComponent>().Set(entity, component, priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
Lookup<TComponent>().Remove(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(Entity entity)
|
||||||
|
{
|
||||||
|
foreach (var entry in Stores.Values)
|
||||||
|
{
|
||||||
|
entry.Remove(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Any<TComponent>() where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
return Lookup<TComponent>().Count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public IEnumerable<TComponent> All<TComponent>() where TComponent : struct, IComponent
|
||||||
|
// {
|
||||||
|
// return Lookup<TComponent>().All<TComponent>();
|
||||||
|
// }
|
||||||
|
|
||||||
|
public IEnumerable<(Entity, TComponent)> All<TComponent>() where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
return Lookup<TComponent>().All();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear<TComponent>() where TComponent : struct, IComponent
|
public void Clear<TComponent>() where TComponent : struct, IComponent
|
||||||
|
@ -52,9 +145,9 @@ namespace Encompass
|
||||||
|
|
||||||
public void ClearAll()
|
public void ClearAll()
|
||||||
{
|
{
|
||||||
foreach (var type in Stores.Keys)
|
foreach (var store in Stores.Values)
|
||||||
{
|
{
|
||||||
ClearMethods[type]();
|
store.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,66 +10,35 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
private readonly DrawLayerManager drawLayerManager;
|
private readonly DrawLayerManager drawLayerManager;
|
||||||
|
|
||||||
private readonly Dictionary<Guid, Type> componentIDToType = new Dictionary<Guid, Type>();
|
private readonly ComponentStore componentStore = new ComponentStore();
|
||||||
private readonly ComponentStore IDToComponent = new ComponentStore();
|
|
||||||
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, PooledDictionary<Type, Guid>> entityIDToComponentTypeToComponentID = new Dictionary<Guid, PooledDictionary<Type, Guid>>();
|
private readonly Dictionary<(Entity, Type), IComponent> componentWriteData = new Dictionary<(Entity, Type), IComponent>();
|
||||||
|
|
||||||
private readonly Dictionary<Type, HashSet<Guid>> typeToComponentIDs = new Dictionary<Type, HashSet<Guid>>();
|
|
||||||
|
|
||||||
private readonly Dictionary<(Entity, Type), (Guid, IComponent)> componentWriteData = new Dictionary<(Entity, Type), (Guid, IComponent)>();
|
|
||||||
private readonly Dictionary<(Entity, Type), int> componentWritePriorities = new Dictionary<(Entity, Type), int>();
|
private readonly Dictionary<(Entity, Type), int> componentWritePriorities = new Dictionary<(Entity, Type), int>();
|
||||||
private readonly HashSet<Guid> componentIDsMarkedForWrite = new HashSet<Guid>();
|
private readonly HashSet<Entity> entitiesMarkedForRemoval = new HashSet<Entity>();
|
||||||
private readonly HashSet<Guid> componentsMarkedForRemoval = new HashSet<Guid>();
|
|
||||||
|
|
||||||
public ComponentManager(DrawLayerManager drawLayerManager)
|
public ComponentManager(DrawLayerManager drawLayerManager)
|
||||||
{
|
{
|
||||||
this.drawLayerManager = drawLayerManager;
|
this.drawLayerManager = drawLayerManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RegisterEntity(Guid entityID)
|
internal void MarkComponentForWrite<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
entityIDToComponentIDs.Add(entityID, new PooledSet<Guid>());
|
componentStore.RegisterComponentType<TComponent>();
|
||||||
entityIDToComponentTypeToComponentID.Add(entityID, new PooledDictionary<Type, Guid>());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Guid NextID()
|
|
||||||
{
|
|
||||||
return Guid.NewGuid();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Guid MarkComponentForWrite<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
Guid id;
|
|
||||||
if (EntityHasComponentOfType<TComponent>(entity))
|
|
||||||
{
|
|
||||||
id = GetComponentByEntityAndType<TComponent>(entity).Item1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id = NextID();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (componentWriteData.ContainsKey((entity, typeof(TComponent))))
|
if (componentWriteData.ContainsKey((entity, typeof(TComponent))))
|
||||||
{
|
{
|
||||||
var currentPriority = componentWritePriorities[(entity, typeof(TComponent))];
|
var currentPriority = componentWritePriorities[(entity, typeof(TComponent))];
|
||||||
if (priority < currentPriority)
|
if (priority < currentPriority)
|
||||||
{
|
{
|
||||||
componentWriteData[(entity, typeof(TComponent))] = (id, component);
|
componentWriteData[(entity, typeof(TComponent))] = component;
|
||||||
componentWritePriorities[(entity, typeof(TComponent))] = priority;
|
componentWritePriorities[(entity, typeof(TComponent))] = priority;
|
||||||
componentIDsMarkedForWrite.Add(id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
componentWriteData.Add((entity, typeof(TComponent)), (id, component));
|
componentWriteData.Add((entity, typeof(TComponent)), component);
|
||||||
componentWritePriorities[(entity, typeof(TComponent))] = priority;
|
componentWritePriorities[(entity, typeof(TComponent))] = priority;
|
||||||
componentIDsMarkedForWrite.Add(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RegisterDrawableComponent<TComponent>(Guid componentID, TComponent component) where TComponent : IDrawableComponent
|
internal void RegisterDrawableComponent<TComponent>(Guid componentID, TComponent component) where TComponent : IDrawableComponent
|
||||||
|
@ -77,23 +46,9 @@ namespace Encompass
|
||||||
drawLayerManager.RegisterComponentWithLayer(componentID, component.Layer);
|
drawLayerManager.RegisterComponentWithLayer(componentID, component.Layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddComponent(Entity entity, Type type, Guid componentID, IComponent component)
|
internal void AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
IDToComponent.Set(type, componentID, component);
|
componentStore.Set<TComponent>(entity, component);
|
||||||
componentIDToEntityID[componentID] = entity.ID;
|
|
||||||
componentIDToType[componentID] = type;
|
|
||||||
entityIDToComponentTypeToComponentID[entity.ID][type] = componentID;
|
|
||||||
if (!typeToComponentIDs.ContainsKey(type))
|
|
||||||
{
|
|
||||||
typeToComponentIDs.Add(type, new HashSet<Guid>());
|
|
||||||
}
|
|
||||||
typeToComponentIDs[type].Add(componentID);
|
|
||||||
entityIDToComponentIDs[entity.ID].Add(componentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void UpdateComponent(Guid componentID, IComponent component)
|
|
||||||
{
|
|
||||||
IDToComponent[componentID] = component;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void WriteComponents()
|
internal void WriteComponents()
|
||||||
|
@ -101,165 +56,59 @@ namespace Encompass
|
||||||
foreach (var keyValuePair in componentWriteData)
|
foreach (var keyValuePair in componentWriteData)
|
||||||
{
|
{
|
||||||
var (entity, type) = keyValuePair.Key;
|
var (entity, type) = keyValuePair.Key;
|
||||||
var (componentID, component) = keyValuePair.Value;
|
var component = keyValuePair.Value;
|
||||||
|
|
||||||
if (!componentIDsMarkedForWrite.Contains(componentID) || !entityIDToComponentTypeToComponentID.ContainsKey(entity.ID)) { continue; }
|
AddComponent(entity, component);
|
||||||
|
|
||||||
if (entityIDToComponentTypeToComponentID[entity.ID].ContainsKey(type))
|
|
||||||
{
|
|
||||||
UpdateComponent(componentID, component);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddComponent(entity, type, componentID, component);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWriteData.Clear();
|
componentWriteData.Clear();
|
||||||
componentIDsMarkedForWrite.Clear();
|
|
||||||
componentWritePriorities.Clear();
|
componentWritePriorities.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IEnumerable<Guid> GetComponentIDsByEntityID(Guid entityID)
|
internal IEnumerable<TComponent> GetComponentsByType<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (entityIDToComponentIDs.TryGetValue(entityID, out PooledSet<Guid> idSet))
|
return componentStore.All<TComponent>().Select(pair => pair.Item2);
|
||||||
{
|
|
||||||
return idSet;
|
|
||||||
}
|
|
||||||
return Enumerable.Empty<Guid>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IEnumerable<(Guid, TComponent)> GetComponentsByType<TComponent>() where TComponent : struct, IComponent
|
internal TComponent GetComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (typeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
|
return componentStore.Get<TComponent>(entity);
|
||||||
{
|
|
||||||
return idSet.Select(id => (id, IDToComponent.Get<TComponent>(id)));
|
|
||||||
}
|
|
||||||
return Enumerable.Empty<(Guid, TComponent)>();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal (Guid, TComponent) GetComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
if (entityIDToComponentTypeToComponentID.ContainsKey(entity.ID) && entityIDToComponentTypeToComponentID[entity.ID].TryGetValue(typeof(TComponent), out Guid id))
|
|
||||||
{
|
|
||||||
return (id, IDToComponent.Get<TComponent>(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", typeof(TComponent).Name, entity.ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool EntityHasComponentOfType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
internal bool EntityHasComponentOfType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return (entityIDToComponentTypeToComponentID.ContainsKey(entity.ID) && entityIDToComponentTypeToComponentID[entity.ID].ContainsKey(typeof(TComponent)));
|
return componentStore.Has<TComponent>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool ComponentOfTypeExists<TComponent>() where TComponent : struct, IComponent
|
internal bool ComponentOfTypeExists<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (typeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
|
return componentStore.Any<TComponent>();
|
||||||
{
|
|
||||||
return idSet.Count > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IComponent GetComponentByID(Guid componentID)
|
internal void MarkAllComponentsOnEntityForRemoval(Entity entity)
|
||||||
{
|
{
|
||||||
if (IDToComponent.Has<TComponent>(componentID))
|
entitiesMarkedForRemoval.Add(entity);
|
||||||
{
|
|
||||||
return IDToComponent[componentID];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Type GetComponentTypeByID(Guid componentID)
|
|
||||||
{
|
|
||||||
if (componentIDToType.ContainsKey(componentID))
|
|
||||||
{
|
|
||||||
return componentIDToType[componentID];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Guid GetEntityIDByComponentID(Guid componentID)
|
|
||||||
{
|
|
||||||
if (componentIDToEntityID.ContainsKey(componentID))
|
|
||||||
{
|
|
||||||
return componentIDToEntityID[componentID];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void MarkAllComponentsOnEntityForRemoval(Guid entityID)
|
|
||||||
{
|
|
||||||
foreach (var componentID in GetComponentIDsByEntityID(entityID))
|
|
||||||
{
|
|
||||||
MarkForRemoval(componentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void MarkForRemoval(Guid componentID)
|
|
||||||
{
|
|
||||||
componentsMarkedForRemoval.Add(componentID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RemoveMarkedComponents()
|
internal void RemoveMarkedComponents()
|
||||||
{
|
{
|
||||||
foreach (var componentID in componentsMarkedForRemoval)
|
foreach (var entity in entitiesMarkedForRemoval)
|
||||||
{
|
{
|
||||||
if (componentIDsMarkedForWrite.Contains(componentID))
|
componentStore.Remove(entity);
|
||||||
{
|
drawLayerManager.UnRegisterComponentWithLayer(entity);
|
||||||
componentIDsMarkedForWrite.Remove(componentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IDToComponent.ContainsKey(componentID))
|
|
||||||
{
|
|
||||||
Remove(componentID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentsMarkedForRemoval.Clear();
|
entitiesMarkedForRemoval.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Remove<TComponent>(Guid componentID) where TComponent : struct, IComponent
|
public void Remove<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
var type = componentIDToType[componentID];
|
componentStore.Remove<TComponent>(entity);
|
||||||
|
|
||||||
var entityID = componentIDToEntityID[componentID];
|
|
||||||
if (entityIDToComponentIDs.ContainsKey(entityID))
|
|
||||||
{
|
|
||||||
entityIDToComponentIDs[entityID].Remove(componentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entityIDToComponentTypeToComponentID.ContainsKey(entityID))
|
|
||||||
{
|
|
||||||
entityIDToComponentTypeToComponentID[entityID].Remove(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
IDToComponent.Remove<TComponent>(componentID);
|
|
||||||
componentIDToType.Remove(componentID);
|
|
||||||
componentIDToEntityID.Remove(componentID);
|
|
||||||
typeToComponentIDs[type].Remove(componentID);
|
|
||||||
|
|
||||||
drawLayerManager.UnRegisterComponentWithLayer(componentID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterDestroyedEntity(Guid entityID)
|
private void Remove(Entity entity)
|
||||||
{
|
{
|
||||||
entityIDToComponentIDs[entityID].Dispose();
|
componentStore.Remove(entity);
|
||||||
entityIDToComponentIDs.Remove(entityID);
|
|
||||||
|
|
||||||
entityIDToComponentTypeToComponentID[entityID].Dispose();
|
|
||||||
entityIDToComponentTypeToComponentID.Remove(entityID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,56 +7,18 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
class ComponentMessageManager
|
class ComponentMessageManager
|
||||||
{
|
{
|
||||||
private readonly ComponentStore componentIDToComponent = new ComponentStore();
|
private readonly ComponentStore componentStore = new ComponentStore();
|
||||||
private readonly Dictionary<Guid, Type> componentIDToType = new Dictionary<Guid, Type>();
|
|
||||||
|
|
||||||
private readonly Dictionary<Guid, Guid> componentIDToEntityID = new Dictionary<Guid, Guid>();
|
private readonly ComponentStore existingComponentStore = new ComponentStore();
|
||||||
|
private readonly ComponentStore pendingComponentStore = new ComponentStore();
|
||||||
private readonly Dictionary<Type, HashSet<Guid>> componentMessageTypeToExistingComponentIDs = 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, Dictionary<Entity, Guid>> typeToEntityToExistingComponentID = new Dictionary<Type, Dictionary<Entity, Guid>>();
|
|
||||||
private readonly Dictionary<Type, Dictionary<Entity, Guid>> typeToEntityToPendingComponentID = new Dictionary<Type, Dictionary<Entity, Guid>>();
|
|
||||||
private readonly Dictionary<Type, Dictionary<Entity, Guid>> typeToEntityToComponentID = new Dictionary<Type, Dictionary<Entity, Guid>>();
|
|
||||||
|
|
||||||
private readonly Dictionary<Type, Dictionary<Entity, int>> typeToEntityToPendingComponentPriority = new Dictionary<Type, Dictionary<Entity, int>>();
|
private readonly Dictionary<Type, Dictionary<Entity, int>> typeToEntityToPendingComponentPriority = new Dictionary<Type, Dictionary<Entity, int>>();
|
||||||
|
|
||||||
internal void ClearMessages()
|
internal void ClearMessages()
|
||||||
{
|
{
|
||||||
componentIDToComponent.ClearAll();
|
componentStore.ClearAll();
|
||||||
componentIDToType.Clear();
|
existingComponentStore.ClearAll();
|
||||||
componentIDToEntityID.Clear();
|
pendingComponentStore.ClearAll();
|
||||||
|
|
||||||
foreach (var set in componentMessageTypeToExistingComponentIDs.Values)
|
|
||||||
{
|
|
||||||
set.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var set in componentMessageTypeToPendingComponentIDs.Values)
|
|
||||||
{
|
|
||||||
set.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var set in componentMessageTypeToComponentIDs.Values)
|
|
||||||
{
|
|
||||||
set.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var dictionary in typeToEntityToExistingComponentID.Values)
|
|
||||||
{
|
|
||||||
dictionary.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var dictionary in typeToEntityToPendingComponentID.Values)
|
|
||||||
{
|
|
||||||
dictionary.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var dictionary in typeToEntityToComponentID.Values)
|
|
||||||
{
|
|
||||||
dictionary.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var dictionary in typeToEntityToPendingComponentPriority.Values)
|
foreach (var dictionary in typeToEntityToPendingComponentPriority.Values)
|
||||||
{
|
{
|
||||||
|
@ -66,129 +28,55 @@ namespace Encompass
|
||||||
|
|
||||||
internal void AddExistingComponentMessage<TComponent>(ComponentMessage<TComponent> componentMessage) where TComponent : struct, IComponent
|
internal void AddExistingComponentMessage<TComponent>(ComponentMessage<TComponent> componentMessage) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
RegisterExistingOrPendingComponentMessage(componentMessage.entity, componentMessage.componentID, componentMessage.component);
|
RegisterExistingOrPendingComponentMessage(componentMessage.entity, componentMessage.component);
|
||||||
|
|
||||||
if (!componentMessageTypeToExistingComponentIDs.ContainsKey(typeof(TComponent)))
|
existingComponentStore.Set(componentMessage.entity, componentMessage.component);
|
||||||
{
|
|
||||||
componentMessageTypeToExistingComponentIDs.Add(typeof(TComponent), new HashSet<Guid>());
|
|
||||||
}
|
|
||||||
|
|
||||||
componentMessageTypeToExistingComponentIDs[typeof(TComponent)].Add(componentMessage.componentID);
|
|
||||||
|
|
||||||
if (!typeToEntityToExistingComponentID.ContainsKey(typeof(TComponent)))
|
|
||||||
{
|
|
||||||
typeToEntityToExistingComponentID.Add(typeof(TComponent), new Dictionary<Entity, Guid>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!typeToEntityToExistingComponentID[typeof(TComponent)].ContainsKey(componentMessage.entity))
|
|
||||||
{
|
|
||||||
typeToEntityToExistingComponentID[typeof(TComponent)].Add(componentMessage.entity, componentMessage.componentID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new MultipleComponentOfSameTypeException("Entity {0} cannot have multiple components of type {1}", componentMessage.entity.ID, typeof(TComponent).Name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddPendingComponentMessage<TComponent>(PendingComponentMessage<TComponent> pendingComponentMessage) where TComponent : struct, IComponent
|
internal void AddPendingComponentMessage<TComponent>(PendingComponentMessage<TComponent> pendingComponentMessage) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
RegisterExistingOrPendingComponentMessage(pendingComponentMessage.entity, pendingComponentMessage.componentID, pendingComponentMessage.component);
|
RegisterExistingOrPendingComponentMessage(pendingComponentMessage.entity, pendingComponentMessage.component);
|
||||||
|
|
||||||
if (!componentMessageTypeToPendingComponentIDs.ContainsKey(typeof(TComponent)))
|
pendingComponentStore.Set(pendingComponentMessage.entity, pendingComponentMessage.component, pendingComponentMessage.priority);
|
||||||
{
|
|
||||||
componentMessageTypeToPendingComponentIDs.Add(typeof(TComponent), new HashSet<Guid>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!typeToEntityToPendingComponentID.ContainsKey(typeof(TComponent)))
|
|
||||||
{
|
|
||||||
typeToEntityToPendingComponentID.Add(typeof(TComponent), new Dictionary<Entity, Guid>());
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pendingComponentMessage.priority < typeToEntityToPendingComponentPriority[typeof(TComponent)][pendingComponentMessage.entity])
|
|
||||||
{
|
|
||||||
componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Remove(typeToEntityToPendingComponentID[typeof(TComponent)][pendingComponentMessage.entity]);
|
|
||||||
typeToEntityToPendingComponentID[typeof(TComponent)][pendingComponentMessage.entity] = pendingComponentMessage.componentID;
|
|
||||||
typeToEntityToPendingComponentPriority[typeof(TComponent)][pendingComponentMessage.entity] = pendingComponentMessage.priority;
|
|
||||||
componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Add(pendingComponentMessage.componentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterExistingOrPendingComponentMessage<TComponent>(Entity entity, Guid componentID, TComponent component) where TComponent : struct, IComponent
|
private void RegisterExistingOrPendingComponentMessage<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
componentIDToComponent.Set(componentID, component);
|
componentStore.Set(entity, component);
|
||||||
componentIDToEntityID[componentID] = entity.ID;
|
|
||||||
componentIDToType[componentID] = typeof(TComponent);
|
|
||||||
|
|
||||||
if (!componentMessageTypeToComponentIDs.ContainsKey(typeof(TComponent)))
|
|
||||||
{
|
|
||||||
componentMessageTypeToComponentIDs.Add(typeof(TComponent), new HashSet<Guid>());
|
|
||||||
}
|
|
||||||
componentMessageTypeToComponentIDs[typeof(TComponent)].Add(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
|
||||||
|
|
||||||
internal IEnumerable<(Guid, TComponent)> ReadExistingAndPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
|
internal IEnumerable<(Entity, TComponent)> ReadExistingAndPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (componentMessageTypeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
|
return componentStore.All<TComponent>();
|
||||||
{
|
|
||||||
return idSet.Select(id => (id, componentIDToComponent.Get<TComponent>(id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Enumerable.Empty<(Guid, TComponent)>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IEnumerable<(Guid, TComponent)> ReadExistingComponentsByType<TComponent>() where TComponent : struct, IComponent
|
internal IEnumerable<(Entity, TComponent)> ReadExistingComponentsByType<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (componentMessageTypeToExistingComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
|
return existingComponentStore.All<TComponent>();
|
||||||
{
|
|
||||||
return idSet.Select(id => (id, componentIDToComponent.Get<TComponent>(id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Enumerable.Empty<(Guid, TComponent)>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IEnumerable<(Guid, TComponent)> ReadPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
|
internal IEnumerable<(Entity, TComponent)> ReadPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (componentMessageTypeToPendingComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
|
return pendingComponentStore.All<TComponent>();
|
||||||
{
|
|
||||||
return idSet.Select(id => (id, componentIDToComponent.Get<TComponent>(id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Enumerable.Empty<(Guid, TComponent)>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// singular component reads by type
|
// singular component reads by type
|
||||||
|
|
||||||
internal (Guid, TComponent) ReadFirstExistingOrPendingComponentByType<TComponent>() where TComponent : struct, IComponent
|
internal (Entity, TComponent) ReadFirstExistingOrPendingComponentByType<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (!SomeExistingOrPendingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
|
if (!SomeExistingOrPendingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
|
||||||
return ReadExistingAndPendingComponentsByType<TComponent>().First();
|
return ReadExistingAndPendingComponentsByType<TComponent>().First();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal (Guid, TComponent) ReadFirstExistingComponentByType<TComponent>() where TComponent : struct, IComponent
|
internal (Entity, TComponent) ReadFirstExistingComponentByType<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (!SomeExistingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
|
if (!SomeExistingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
|
||||||
return ReadExistingComponentsByType<TComponent>().First();
|
return ReadExistingComponentsByType<TComponent>().First();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal (Guid, TComponent) ReadFirstPendingComponentByType<TComponent>() where TComponent : struct, IComponent
|
internal (Entity, TComponent) ReadFirstPendingComponentByType<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (!SomeExistingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
|
if (!SomeExistingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
|
||||||
return ReadPendingComponentsByType<TComponent>().First();
|
return ReadPendingComponentsByType<TComponent>().First();
|
||||||
|
@ -198,126 +86,61 @@ namespace Encompass
|
||||||
|
|
||||||
internal bool SomeExistingOrPendingComponent<TComponent>() where TComponent : struct, IComponent
|
internal bool SomeExistingOrPendingComponent<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (componentMessageTypeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
|
return componentStore.Any<TComponent>();
|
||||||
{
|
|
||||||
return idSet.Count > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool SomeExistingComponent<TComponent>() where TComponent : struct, IComponent
|
internal bool SomeExistingComponent<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (componentMessageTypeToExistingComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
|
return existingComponentStore.Any<TComponent>();
|
||||||
{
|
|
||||||
return idSet.Count > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool SomePendingComponent<TComponent>() where TComponent : struct, IComponent
|
internal bool SomePendingComponent<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (componentMessageTypeToPendingComponentIDs.TryGetValue(typeof(TComponent), out HashSet<Guid> idSet))
|
return pendingComponentStore.Any<TComponent>();
|
||||||
{
|
|
||||||
return idSet.Count > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read components by entity and type
|
// read components by entity and type
|
||||||
|
|
||||||
internal (Guid, TComponent) ReadExistingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
internal TComponent ReadExistingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (typeToEntityToExistingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToExistingComponentID[typeof(TComponent)].TryGetValue(entity, out Guid id))
|
return existingComponentStore.Get<TComponent>(entity);
|
||||||
{
|
|
||||||
return (id, componentIDToComponent.Get<TComponent>(id));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", typeof(TComponent).Name, entity.ID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal (Guid, TComponent) ReadPendingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
internal TComponent ReadPendingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (typeToEntityToPendingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToPendingComponentID[typeof(TComponent)].TryGetValue(entity, out Guid id))
|
return pendingComponentStore.Get<TComponent>(entity);
|
||||||
{
|
|
||||||
return (id, componentIDToComponent.Get<TComponent>(id));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", typeof(TComponent).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 typeToEntityToComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToComponentID[typeof(TComponent)].ContainsKey(entity);
|
return componentStore.Has<TComponent>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool HasExistingOrPendingComponent(Entity entity, Type type)
|
internal bool HasExistingOrPendingComponent(Entity entity, Type type)
|
||||||
{
|
{
|
||||||
return typeToEntityToComponentID.ContainsKey(type) && typeToEntityToComponentID[type].ContainsKey(entity);
|
return componentStore.Has(type, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool HasExistingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
internal bool HasExistingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return typeToEntityToExistingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToExistingComponentID[typeof(TComponent)].ContainsKey(entity);
|
return existingComponentStore.Has<TComponent>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool HasExistingComponent(Entity entity, Type type)
|
internal bool HasExistingComponent(Entity entity, Type type)
|
||||||
{
|
{
|
||||||
return typeToEntityToExistingComponentID.ContainsKey(type) && typeToEntityToExistingComponentID[type].ContainsKey(entity);
|
return existingComponentStore.Has(type, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool HasPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
internal bool HasPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return typeToEntityToPendingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToPendingComponentID[typeof(TComponent)].ContainsKey(entity);
|
return pendingComponentStore.Has<TComponent>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool HasPendingComponent(Entity entity, Type type)
|
internal bool HasPendingComponent(Entity entity, Type type)
|
||||||
{
|
{
|
||||||
return typeToEntityToPendingComponentID.ContainsKey(type) && typeToEntityToPendingComponentID[type].ContainsKey(entity);
|
return pendingComponentStore.Has(type, entity);
|
||||||
}
|
|
||||||
|
|
||||||
internal TComponent GetComponentByID<TComponent>(Guid componentID) where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
if (componentIDToComponent.Has<TComponent>(componentID))
|
|
||||||
{
|
|
||||||
return componentIDToComponent.Get<TComponent>(componentID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Type GetComponentTypeByID(Guid componentID)
|
|
||||||
{
|
|
||||||
if (componentIDToType.ContainsKey(componentID))
|
|
||||||
{
|
|
||||||
return componentIDToType[componentID];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Guid GetEntityIDByComponentID(Guid componentID)
|
|
||||||
{
|
|
||||||
if (componentIDToEntityID.ContainsKey(componentID))
|
|
||||||
{
|
|
||||||
return componentIDToEntityID[componentID];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace Encompass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UnRegisterComponentWithLayer(Guid id)
|
public void UnRegisterComponentWithLayer(Entity entity)
|
||||||
{
|
{
|
||||||
if (componentIDToLayerIndex.ContainsKey(id))
|
if (componentIDToLayerIndex.ContainsKey(id))
|
||||||
{
|
{
|
||||||
|
|
|
@ -154,37 +154,12 @@ namespace Encompass
|
||||||
return entityManager.GetEntity(entityID);
|
return entityManager.GetEntity(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the Entity ID associated with the specified Component Type and ID.
|
|
||||||
/// </summary>
|
|
||||||
private Guid GetEntityIDByComponentID<TComponent>(Guid componentID) where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
|
|
||||||
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
|
|
||||||
|
|
||||||
if (!pendingRead && !existingRead)
|
|
||||||
{
|
|
||||||
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return componentMessageManager.GetEntityIDByComponentID(componentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the Entity associated with the specified Component Type and ID.
|
|
||||||
/// </summary>
|
|
||||||
private Entity GetEntityByComponentID<TComponent>(Guid componentID) where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
return GetEntity(GetEntityIDByComponentID<TComponent>(componentID));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an Entity containing the specified Component type.
|
/// Returns an Entity containing the specified Component type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected Entity ReadEntity<TComponent>() where TComponent : struct, IComponent
|
protected Entity ReadEntity<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
var (id, _) = ReadComponentHelper<TComponent>();
|
return ReadComponentHelper<TComponent>().Item1;
|
||||||
return GetEntityByComponentID<TComponent>(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -192,46 +167,17 @@ namespace Encompass
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected IEnumerable<Entity> ReadEntities<TComponent>() where TComponent : struct, IComponent
|
protected IEnumerable<Entity> ReadEntities<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
foreach (var (id, _) in ReadComponentsHelper<TComponent>())
|
return ReadComponentsHelper<TComponent>().Select(pair => pair.Item1);
|
||||||
{
|
|
||||||
yield return GetEntityByComponentID<TComponent>(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the Component struct with the specified Component Type and ID.
|
|
||||||
/// </summary>
|
|
||||||
internal TComponent GetComponentByID<TComponent>(Guid componentID) where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
|
|
||||||
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
|
|
||||||
|
|
||||||
if (!pendingRead && !existingRead)
|
|
||||||
{
|
|
||||||
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (componentMessageManager.GetComponentTypeByID(componentID) != typeof(TComponent))
|
|
||||||
{
|
|
||||||
throw new ComponentTypeMismatchException("Expected Component to be of type {0} but was actually of type {1}", typeof(TComponent).Name, componentMessageManager.GetComponentTypeByID(componentID).Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return componentMessageManager.GetComponentByID<TComponent>(componentID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// these next two are for the ComponentMessageEmitter only
|
// these next two are for the ComponentMessageEmitter only
|
||||||
|
|
||||||
internal IEnumerable<(Guid, TComponent)> ReadComponentsFromWorld<TComponent>() where TComponent : struct, IComponent
|
internal IEnumerable<TComponent> ReadComponentsFromWorld<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return componentManager.GetComponentsByType<TComponent>();
|
return componentManager.GetComponentsByType<TComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Entity ReadEntityFromWorld(Guid componentID)
|
private IEnumerable<(Entity, TComponent)> ReadComponentsHelper<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
|
||||||
return GetEntity(componentManager.GetEntityIDByComponentID(componentID));
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<(Guid, TComponent)> ReadComponentsHelper<TComponent>() where TComponent : struct, IComponent
|
|
||||||
{
|
{
|
||||||
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
|
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
|
||||||
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
|
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
|
||||||
|
@ -266,10 +212,10 @@ namespace Encompass
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected IEnumerable<(TComponent, Entity)> ReadComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent
|
protected IEnumerable<(TComponent, Entity)> ReadComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return ReadComponentsHelper<TComponent>().Select((tuple) => (tuple.Item2, GetEntityByComponentID<TComponent>(tuple.Item1)));
|
return ReadComponentsHelper<TComponent>().Select((tuple) => (tuple.Item2, tuple.Item1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Guid, TComponent) ReadComponentHelper<TComponent>() where TComponent : struct, IComponent
|
private (Entity, TComponent) ReadComponentHelper<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
|
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
|
||||||
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
|
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
|
||||||
|
@ -304,8 +250,8 @@ namespace Encompass
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected (TComponent, Entity) ReadComponentIncludingEntity<TComponent>() where TComponent : struct, IComponent
|
protected (TComponent, Entity) ReadComponentIncludingEntity<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
var (id, component) = ReadComponentHelper<TComponent>();
|
var (entity, component) = ReadComponentHelper<TComponent>();
|
||||||
return (component, GetEntityByComponentID<TComponent>(id));
|
return (component, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -333,7 +279,7 @@ namespace Encompass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Guid, TComponent) GetComponentHelper<TComponent>(Entity entity) where TComponent : struct, IComponent
|
private TComponent GetComponentHelper<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
|
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
|
||||||
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
|
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
|
||||||
|
@ -377,7 +323,7 @@ namespace Encompass
|
||||||
/// </exception>
|
/// </exception>
|
||||||
protected TComponent GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
protected TComponent GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return GetComponentHelper<TComponent>(entity).Item2;
|
return GetComponentHelper<TComponent>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -451,7 +397,7 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
var priority = writePriorities.ContainsKey(typeof(TComponent)) ? writePriorities[typeof(TComponent)] : 0;
|
var priority = writePriorities.ContainsKey(typeof(TComponent)) ? writePriorities[typeof(TComponent)] : 0;
|
||||||
|
|
||||||
var componentID = componentManager.MarkComponentForWrite(entity, component, priority);
|
componentManager.MarkComponentForWrite(entity, component, priority);
|
||||||
|
|
||||||
if (!sendTypes.Contains(typeof(ComponentWriteMessage<TComponent>)))
|
if (!sendTypes.Contains(typeof(ComponentWriteMessage<TComponent>)))
|
||||||
{
|
{
|
||||||
|
@ -462,7 +408,6 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
PendingComponentMessage<TComponent> newComponentMessage;
|
PendingComponentMessage<TComponent> newComponentMessage;
|
||||||
newComponentMessage.entity = entity;
|
newComponentMessage.entity = entity;
|
||||||
newComponentMessage.componentID = componentID;
|
|
||||||
newComponentMessage.component = component;
|
newComponentMessage.component = component;
|
||||||
newComponentMessage.priority = priority;
|
newComponentMessage.priority = priority;
|
||||||
SendPendingComponentMessage(newComponentMessage);
|
SendPendingComponentMessage(newComponentMessage);
|
||||||
|
@ -622,21 +567,10 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
if (!HasComponent<TComponent>(entity)) { return false; }
|
if (!HasComponent<TComponent>(entity)) { return false; }
|
||||||
|
|
||||||
var (componentID, _) = GetComponentHelper<TComponent>(entity);
|
componentManager.Remove<TComponent>(entity);
|
||||||
|
|
||||||
RemoveComponent(componentID);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes the Component with the specified ID from its Entity.
|
|
||||||
/// </summary>
|
|
||||||
private void RemoveComponent(Guid componentID)
|
|
||||||
{
|
|
||||||
componentManager.MarkForRemoval(componentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Activates the Encompass time dilation system.
|
/// Activates the Encompass time dilation system.
|
||||||
/// Engines that have the IgnoresTimeDilation property will ignore all time dilation.
|
/// Engines that have the IgnoresTimeDilation property will ignore all time dilation.
|
||||||
|
|
|
@ -9,11 +9,10 @@ namespace Encompass
|
||||||
|
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
{
|
{
|
||||||
foreach (var (componentID, component) in ReadComponentsFromWorld<TComponent>())
|
foreach (var (component, entity) in ReadComponentsIncludingEntity<TComponent>())
|
||||||
{
|
{
|
||||||
ComponentMessage<TComponent> componentMessage;
|
ComponentMessage<TComponent> componentMessage;
|
||||||
componentMessage.entity = ReadEntityFromWorld(componentID);
|
componentMessage.entity = entity;
|
||||||
componentMessage.componentID = componentID;
|
|
||||||
componentMessage.component = component;
|
componentMessage.component = component;
|
||||||
SendMessage(componentMessage);
|
SendMessage(componentMessage);
|
||||||
SendExistingComponentMessage(componentMessage);
|
SendExistingComponentMessage(componentMessage);
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
private readonly Dictionary<Guid, Entity> IDToEntity = new Dictionary<Guid, Entity>();
|
private readonly Dictionary<Guid, Entity> IDToEntity = new Dictionary<Guid, Entity>();
|
||||||
|
|
||||||
private readonly HashSet<Guid> entitiesMarkedForDestroy = new HashSet<Guid>();
|
private readonly HashSet<Entity> entitiesMarkedForDestroy = new HashSet<Entity>();
|
||||||
|
|
||||||
private readonly ComponentManager componentManager;
|
private readonly ComponentManager componentManager;
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ namespace Encompass
|
||||||
var id = NextID();
|
var id = NextID();
|
||||||
var entity = new Entity(id);
|
var entity = new Entity(id);
|
||||||
IDToEntity[id] = entity;
|
IDToEntity[id] = entity;
|
||||||
componentManager.RegisterEntity(id);
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,18 +43,17 @@ namespace Encompass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MarkForDestroy(Guid entityID)
|
public void MarkForDestroy(Entity entity)
|
||||||
{
|
{
|
||||||
entitiesMarkedForDestroy.Add(entityID);
|
entitiesMarkedForDestroy.Add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DestroyMarkedEntities()
|
public void DestroyMarkedEntities()
|
||||||
{
|
{
|
||||||
foreach (var entityID in entitiesMarkedForDestroy)
|
foreach (var entity in entitiesMarkedForDestroy)
|
||||||
{
|
{
|
||||||
componentManager.MarkAllComponentsOnEntityForRemoval(entityID);
|
componentManager.MarkAllComponentsOnEntityForRemoval(entity);
|
||||||
IDToEntity.Remove(entityID);
|
IDToEntity.Remove(entity.ID);
|
||||||
componentManager.RegisterDestroyedEntity(entityID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entitiesMarkedForDestroy.Clear();
|
entitiesMarkedForDestroy.Clear();
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Encompass
|
namespace Encompass
|
||||||
{
|
{
|
||||||
internal struct ComponentMessage<TComponent> : IMessage where TComponent : struct, IComponent
|
internal struct ComponentMessage<TComponent> : IMessage where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
public Entity entity;
|
public Entity entity;
|
||||||
public Guid componentID;
|
|
||||||
public TComponent component;
|
public TComponent component;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,8 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Encompass
|
namespace Encompass
|
||||||
{
|
{
|
||||||
internal struct PendingComponentMessage<TComponent> : IMessage where TComponent : struct, IComponent
|
internal struct PendingComponentMessage<TComponent> : IMessage where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
public Entity entity;
|
public Entity entity;
|
||||||
public Guid componentID;
|
|
||||||
public TComponent component;
|
public TComponent component;
|
||||||
public int priority;
|
public int priority;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,8 @@ namespace Encompass
|
||||||
|
|
||||||
foreach (var componentID in componentIDSet)
|
foreach (var componentID in componentIDSet)
|
||||||
{
|
{
|
||||||
var component = componentManager.GetComponentByID(componentID);
|
|
||||||
var componentType = componentManager.GetComponentTypeByID(componentID);
|
var componentType = componentManager.GetComponentTypeByID(componentID);
|
||||||
|
var component = componentManager.GetComponentByID(componentType, componentID);
|
||||||
var entityID = componentManager.GetEntityIDByComponentID(componentID);
|
var entityID = componentManager.GetEntityIDByComponentID(componentID);
|
||||||
var entity = entityManager.GetEntity(entityID);
|
var entity = entityManager.GetEntity(entityID);
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace Encompass
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetComponent<TComponent>(Entity entity, TComponent component, int priority = 0) where TComponent : struct, IComponent
|
public void SetComponent<TComponent>(Entity entity, TComponent component, int priority = 0) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
var componentID = componentManager.MarkComponentForWrite(entity, component, priority);
|
componentManager.MarkComponentForWrite(entity, component, priority);
|
||||||
if (component is IDrawableComponent drawableComponent)
|
if (component is IDrawableComponent drawableComponent)
|
||||||
{
|
{
|
||||||
componentManager.RegisterDrawableComponent(componentID, drawableComponent);
|
componentManager.RegisterDrawableComponent(componentID, drawableComponent);
|
||||||
|
|
Loading…
Reference in New Issue