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-14 05:15:15 +00:00
|
|
|
private Dictionary<uint, List<IComponent>> entityIDToComponents = new Dictionary<uint, List<IComponent>>();
|
2019-06-15 07:39:08 +00:00
|
|
|
private Dictionary<IComponent, uint> componentToEntityID = new Dictionary<IComponent, uint>();
|
2019-06-14 03:28:26 +00:00
|
|
|
|
2019-06-14 05:15:15 +00:00
|
|
|
private Dictionary<Type, List<IComponent>> activeComponents = new Dictionary<Type, List<IComponent>>();
|
|
|
|
private Dictionary<Type, List<IComponent>> inactiveComponents = new Dictionary<Type, List<IComponent>>();
|
2019-06-14 03:28:26 +00:00
|
|
|
|
2019-06-14 05:15:15 +00:00
|
|
|
private List<IComponent> componentsToActivate = new List<IComponent>();
|
|
|
|
private List<IComponent> componentsToDeactivate = new List<IComponent>();
|
|
|
|
private List<IComponent> componentsToRemove = new List<IComponent>();
|
2019-06-14 03:28:26 +00:00
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void AddComponent<TComponent>(uint entityID, TComponent component) where TComponent : struct, IComponent
|
|
|
|
{
|
|
|
|
if (!entityIDToComponents.ContainsKey(entityID))
|
|
|
|
{
|
2019-06-14 05:15:15 +00:00
|
|
|
entityIDToComponents.Add(entityID, new List<IComponent>());
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
entityIDToComponents[entityID].Add(component);
|
2019-06-15 07:39:08 +00:00
|
|
|
componentToEntityID[component] = entityID;
|
2019-06-14 03:28:26 +00:00
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
if (!activeComponents.ContainsKey(typeof(TComponent)))
|
|
|
|
{
|
2019-06-14 05:15:15 +00:00
|
|
|
activeComponents.Add(typeof(TComponent), new List<IComponent>());
|
|
|
|
inactiveComponents.Add(typeof(TComponent), new List<IComponent>());
|
2019-06-14 03:28:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MarkForActivation(component);
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal IEnumerable<IComponent> GetComponentsByEntity(uint entityID)
|
|
|
|
{
|
2019-06-14 03:28:26 +00:00
|
|
|
return entityIDToComponents[entityID];
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal IEnumerable<TComponent> GetActiveComponentsByType<TComponent>() where TComponent : struct, IComponent
|
|
|
|
{
|
2019-06-14 03:28:26 +00:00
|
|
|
return activeComponents[typeof(TComponent)].Cast<TComponent>();
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal TComponent GetActiveComponentByType<TComponent>() where TComponent : struct, IComponent
|
|
|
|
{
|
2019-06-15 00:51:06 +00:00
|
|
|
return GetActiveComponentsByType<TComponent>().Single();
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal IEnumerable<TComponent> GetComponentsByEntityAndType<TComponent>(uint entityID) where TComponent : struct, IComponent
|
|
|
|
{
|
2019-06-14 05:15:15 +00:00
|
|
|
var entity_components = GetComponentsByEntity(entityID).Cast<TComponent>();
|
2019-06-14 03:28:26 +00:00
|
|
|
var active_components_by_type = GetActiveComponentsByType<TComponent>();
|
|
|
|
return entity_components.Intersect(active_components_by_type).Cast<TComponent>();
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal bool EntityHasComponentOfType<TComponent>(uint entityID) where TComponent : struct, IComponent
|
|
|
|
{
|
2019-06-14 03:28:26 +00:00
|
|
|
return GetComponentsByEntityAndType<TComponent>(entityID).Any();
|
|
|
|
}
|
|
|
|
|
2019-06-15 07:39:08 +00:00
|
|
|
/** Replaces the component with another. */
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void UpdateComponent<TComponent>(TComponent originalComponent, TComponent newComponent) where TComponent : struct, IComponent
|
|
|
|
{
|
2019-06-15 07:39:08 +00:00
|
|
|
var entityID = componentToEntityID[originalComponent];
|
|
|
|
|
|
|
|
entityIDToComponents[entityID].Remove(originalComponent);
|
|
|
|
entityIDToComponents[entityID].Add(newComponent);
|
|
|
|
|
|
|
|
componentToEntityID.Remove(originalComponent);
|
|
|
|
componentToEntityID.Add(newComponent, entityID);
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
if (activeComponents[originalComponent.GetType()].Remove(originalComponent))
|
|
|
|
{
|
2019-06-15 07:39:08 +00:00
|
|
|
activeComponents[originalComponent.GetType()].Add(newComponent);
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
if (inactiveComponents[originalComponent.GetType()].Remove(originalComponent))
|
|
|
|
{
|
2019-06-15 07:39:08 +00:00
|
|
|
inactiveComponents[originalComponent.GetType()].Add(newComponent);
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
if (componentsToActivate.Remove(originalComponent))
|
|
|
|
{
|
2019-06-15 07:39:08 +00:00
|
|
|
componentsToActivate.Add(newComponent);
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
if (componentsToDeactivate.Remove(originalComponent))
|
|
|
|
{
|
2019-06-15 07:39:08 +00:00
|
|
|
componentsToDeactivate.Add(newComponent);
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
if (componentsToRemove.Remove(originalComponent))
|
|
|
|
{
|
2019-06-15 07:39:08 +00:00
|
|
|
componentsToRemove.Add(newComponent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void RemoveAllComponentsFromEntity(uint entityID)
|
|
|
|
{
|
2019-06-14 03:28:26 +00:00
|
|
|
var components = GetComponentsByEntity(entityID);
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
foreach (var component in components)
|
|
|
|
{
|
2019-06-14 03:28:26 +00:00
|
|
|
activeComponents[component.GetType()].Remove(component);
|
|
|
|
inactiveComponents[component.GetType()].Remove(component);
|
|
|
|
}
|
|
|
|
|
|
|
|
entityIDToComponents.Remove(entityID);
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void MarkForActivation(IComponent component)
|
|
|
|
{
|
2019-06-14 03:28:26 +00:00
|
|
|
componentsToActivate.Add(component);
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void MarkForDeactivation(IComponent component)
|
|
|
|
{
|
2019-06-15 07:39:08 +00:00
|
|
|
componentsToDeactivate.Add(component);
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void MarkForRemoval(IComponent component)
|
|
|
|
{
|
2019-06-14 03:28:26 +00:00
|
|
|
componentsToRemove.Add(component);
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void ActivateComponents()
|
|
|
|
{
|
|
|
|
foreach (var component in componentsToActivate)
|
|
|
|
{
|
2019-06-14 03:28:26 +00:00
|
|
|
activeComponents[component.GetType()].Add(component);
|
|
|
|
inactiveComponents[component.GetType()].Remove(component);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentsToActivate.Clear();
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void DeactivateComponents()
|
|
|
|
{
|
|
|
|
foreach (var component in componentsToDeactivate)
|
|
|
|
{
|
2019-06-15 07:39:08 +00:00
|
|
|
activeComponents[component.GetType()].Remove(component);
|
|
|
|
inactiveComponents[component.GetType()].Add(component);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-16 01:05:56 +00:00
|
|
|
internal void RemoveComponents()
|
|
|
|
{
|
|
|
|
foreach (var component in componentsToRemove)
|
|
|
|
{
|
2019-06-14 03:28:26 +00:00
|
|
|
activeComponents[component.GetType()].Remove(component);
|
|
|
|
inactiveComponents[component.GetType()].Remove(component);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentsToRemove.Clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|