2019-06-14 03:28:26 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
namespace Encompass
|
|
|
|
{
|
|
|
|
internal class ComponentManager
|
|
|
|
{
|
2019-06-19 21:14:44 +00:00
|
|
|
private Dictionary<Guid, Type> componentIDToType = new Dictionary<Guid, Type>();
|
2019-06-17 18:33:38 +00:00
|
|
|
private Dictionary<Guid, IComponent> IDToComponent = new Dictionary<Guid, IComponent>();
|
|
|
|
private Dictionary<Guid, List<Guid>> entityIDToComponentIDs = new Dictionary<Guid, List<Guid>>();
|
|
|
|
private Dictionary<Guid, Guid> componentIDToEntityID = new Dictionary<Guid, Guid>();
|
2019-06-14 03:28:26 +00:00
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
private Dictionary<Type, List<Guid>> activeComponents = new Dictionary<Type, List<Guid>>();
|
|
|
|
private Dictionary<Type, List<Guid>> inactiveComponents = new Dictionary<Type, List<Guid>>();
|
2019-06-14 03:28:26 +00:00
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
private List<Guid> componentsToActivate = new List<Guid>();
|
|
|
|
private List<Guid> componentsToDeactivate = new List<Guid>();
|
|
|
|
private List<Guid> componentsToRemove = new List<Guid>();
|
2019-06-14 03:28:26 +00:00
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal Guid AddComponent<TComponent>(Guid entityID, TComponent component) where TComponent : struct, IComponent
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
var componentID = Guid.NewGuid();
|
|
|
|
|
|
|
|
IDToComponent[componentID] = component;
|
2019-06-19 21:14:44 +00:00
|
|
|
componentIDToType[componentID] = typeof(TComponent);
|
2019-06-17 18:33:38 +00:00
|
|
|
|
|
|
|
if (!entityIDToComponentIDs.ContainsKey(entityID))
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
entityIDToComponentIDs.Add(entityID, new List<Guid>());
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
entityIDToComponentIDs[entityID].Add(componentID);
|
|
|
|
componentIDToEntityID[componentID] = entityID;
|
2019-06-14 03:28:26 +00:00
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
if (!activeComponents.ContainsKey(typeof(TComponent)))
|
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
activeComponents.Add(typeof(TComponent), new List<Guid>());
|
|
|
|
inactiveComponents.Add(typeof(TComponent), new List<Guid>());
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
MarkForActivation(componentID);
|
|
|
|
|
|
|
|
return componentID;
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal IEnumerable<KeyValuePair<Guid, IComponent>> GetComponentsByEntity(Guid entityID)
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
return entityIDToComponentIDs[entityID].Select((id) => new KeyValuePair<Guid, IComponent>(id, IDToComponent[id]));
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal IEnumerable<KeyValuePair<Guid, TComponent>> GetActiveComponentsByType<TComponent>() where TComponent : struct, IComponent
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 19:12:07 +00:00
|
|
|
return activeComponents.ContainsKey(typeof(TComponent)) ?
|
|
|
|
activeComponents[typeof(TComponent)].Select((id) => new KeyValuePair<Guid, TComponent>(id, (TComponent)IDToComponent[id])) :
|
|
|
|
Enumerable.Empty<KeyValuePair<Guid, TComponent>>();
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-19 21:14:44 +00:00
|
|
|
internal IEnumerable<KeyValuePair<Guid, IComponent>> GetActiveComponentsByType(Type type)
|
|
|
|
{
|
|
|
|
return activeComponents.ContainsKey(type) ?
|
|
|
|
activeComponents[type].Select((id) => new KeyValuePair<Guid, IComponent>(id, IDToComponent[id])) :
|
|
|
|
Enumerable.Empty<KeyValuePair<Guid, IComponent>>();
|
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal KeyValuePair<Guid, TComponent> GetActiveComponentByType<TComponent>() where TComponent : struct, IComponent
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-15 00:51:06 +00:00
|
|
|
return GetActiveComponentsByType<TComponent>().Single();
|
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal IEnumerable<KeyValuePair<Guid, TComponent>> GetComponentsByEntityAndType<TComponent>(Guid entityID) where TComponent : struct, IComponent
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
var entity_components = GetComponentsByEntity(entityID).Select((kv) => new KeyValuePair<Guid, TComponent>(kv.Key, (TComponent)kv.Value));
|
2019-06-14 03:28:26 +00:00
|
|
|
var active_components_by_type = GetActiveComponentsByType<TComponent>();
|
2019-06-17 18:33:38 +00:00
|
|
|
return entity_components.Intersect(active_components_by_type);
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-19 21:14:44 +00:00
|
|
|
internal IEnumerable<KeyValuePair<Guid, IComponent>> GetComponentsByEntityAndType(Guid entityID, Type type)
|
|
|
|
{
|
|
|
|
var entityComponents = GetComponentsByEntity(entityID);
|
|
|
|
var activeComponentsByType = GetActiveComponentsByType(type);
|
|
|
|
return entityComponents.Intersect(activeComponentsByType);
|
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal bool EntityHasComponentOfType<TComponent>(Guid entityID) where TComponent : struct, IComponent
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-14 03:28:26 +00:00
|
|
|
return GetComponentsByEntityAndType<TComponent>(entityID).Any();
|
|
|
|
}
|
|
|
|
|
2019-06-19 21:14:44 +00:00
|
|
|
internal bool EntityHasComponentOfType(Guid entityID, Type type)
|
|
|
|
{
|
|
|
|
return GetComponentsByEntityAndType(entityID, type).Any();
|
|
|
|
}
|
|
|
|
|
|
|
|
internal IComponent GetComponentByID(Guid componentID)
|
|
|
|
{
|
|
|
|
return IDToComponent[componentID];
|
|
|
|
}
|
|
|
|
|
|
|
|
internal Type GetComponentTypeByID(Guid componentID)
|
|
|
|
{
|
|
|
|
return componentIDToType[componentID];
|
|
|
|
}
|
|
|
|
|
|
|
|
internal Guid GetEntityIDFromComponentID(Guid componentID)
|
|
|
|
{
|
|
|
|
return componentIDToEntityID[componentID];
|
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal void UpdateComponent<TComponent>(Guid componentID, TComponent newComponentValue) where TComponent : struct, IComponent
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-19 21:14:44 +00:00
|
|
|
var entityID = GetEntityIDFromComponentID(componentID);
|
2019-06-17 18:33:38 +00:00
|
|
|
IDToComponent[componentID] = newComponentValue;
|
2019-06-15 07:39:08 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal void RemoveAllComponentsFromEntity(Guid entityID)
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
var componentIDs = entityIDToComponentIDs[entityID];
|
2019-06-14 03:28:26 +00:00
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
foreach (var componentID in componentIDs)
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
var component = IDToComponent[componentID];
|
|
|
|
activeComponents[component.GetType()].Remove(componentID);
|
|
|
|
inactiveComponents[component.GetType()].Remove(componentID);
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
entityIDToComponentIDs.Remove(entityID);
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal void MarkForActivation(Guid componentID)
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
componentsToActivate.Add(componentID);
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal void MarkForDeactivation(Guid componentID)
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
componentsToDeactivate.Add(componentID);
|
2019-06-15 07:39:08 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 18:33:38 +00:00
|
|
|
internal void MarkForRemoval(Guid componentID)
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
componentsToRemove.Add(componentID);
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void ActivateComponents()
|
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
foreach (var componentID in componentsToActivate)
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
var component = IDToComponent[componentID];
|
|
|
|
activeComponents[component.GetType()].Add(componentID);
|
|
|
|
inactiveComponents[component.GetType()].Remove(componentID);
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
componentsToActivate.Clear();
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void DeactivateComponents()
|
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
foreach (var componentID in componentsToDeactivate)
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
var component = IDToComponent[componentID];
|
|
|
|
activeComponents[component.GetType()].Remove(componentID);
|
|
|
|
inactiveComponents[component.GetType()].Add(componentID);
|
2019-06-15 07:39:08 +00:00
|
|
|
}
|
2019-06-17 18:33:38 +00:00
|
|
|
|
|
|
|
componentsToDeactivate.Clear();
|
2019-06-15 07:39:08 +00:00
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void RemoveComponents()
|
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
foreach (var componentID in componentsToRemove)
|
2019-06-16 01:05:56 +00:00
|
|
|
{
|
2019-06-17 18:33:38 +00:00
|
|
|
var component = IDToComponent[componentID];
|
|
|
|
activeComponents[component.GetType()].Remove(componentID);
|
|
|
|
inactiveComponents[component.GetType()].Remove(componentID);
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
componentsToRemove.Clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|