Guest User

Untitled

a guest
Jan 27th, 2019
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.37 KB | None | 0 0
  1.     internal class EntityManager
  2.     {
  3.         #region Constructor
  4.  
  5.         public EntityManager()
  6.         {
  7.             activeEntities = new List<Guid>();
  8.             componentPools = new Dictionary<Type, object>();
  9.             systems = new KeyedByTypeCollection<ISystem>();
  10.         }
  11.  
  12.         #endregion Constructor
  13.  
  14.         #region Variables
  15.  
  16.         private List<Guid> activeEntities;
  17.         private Dictionary<Type, object> componentPools;
  18.         private KeyedByTypeCollection<ISystem> systems;
  19.  
  20.         #endregion Variables
  21.  
  22.         #region Properties
  23.  
  24.         public IReadOnlyList<ISystem> Systems { get { return systems; } }
  25.  
  26.         #endregion Properties
  27.  
  28.         #region Methods
  29.  
  30.         public Guid CreateEntity()
  31.         {
  32.             Guid entityId = GenerateEntityId();
  33.             activeEntities.Add(entityId);
  34.  
  35.             UpdateSystems((system) =>
  36.             {
  37.                 if (system.ComponentRequirements.IsEmpty)
  38.                     AddEntityToSystemCache(system, entityId);
  39.             });
  40.  
  41.             return entityId;
  42.         }
  43.  
  44.         public void DestroyEntity(Guid entityId)
  45.         {
  46.             activeEntities.Remove(entityId);
  47.             RemoveEntityFromComponentPools(entityId);
  48.  
  49.             UpdateSystems((system) =>
  50.             {
  51.                 RemoveEntityFromSystemCache(system, entityId);
  52.             });
  53.         }
  54.  
  55.         public void AddComponentToEntity<TComponent>(Guid entityId, TComponent component) where TComponent : IComponent
  56.         {
  57.             AddEntityToComponentPool(entityId, component);
  58.  
  59.             Type[] componentTypes = GetComponentTypesFromEntityById(entityId);
  60.  
  61.             UpdateSystems((system) =>
  62.             {
  63.                 if (system.ComponentRequirements.ValidateEntity(componentTypes))
  64.                     AddEntityToSystemCache(system, entityId);
  65.             });
  66.         }
  67.  
  68.         public void RemoveComponentFromEntity<TComponent>(Guid entityId) where TComponent : IComponent
  69.         {
  70.             RemoveEntityFromComponentPool<TComponent>(entityId);
  71.  
  72.             UpdateSystems((system) =>
  73.             {
  74.                 if (ComponentIsRequiredBySystem<TComponent>(system))
  75.                     RemoveEntityFromSystemCache(system, entityId);
  76.             });
  77.         }
  78.  
  79.         private Guid GenerateEntityId()
  80.         {
  81.             return Guid.NewGuid();
  82.         }
  83.  
  84.         private void AddEntityToComponentPool<TComponent>(Guid entityId, TComponent component) where TComponent : IComponent
  85.         {
  86.             GetComponentPoolByType<TComponent>().Add(entityId, component);
  87.         }
  88.  
  89.         private void RemoveEntityFromComponentPool<TComponent>(Guid entityId) where TComponent : IComponent
  90.         {
  91.             GetComponentPoolByType<TComponent>().Remove(entityId);
  92.         }
  93.  
  94.         private void RemoveEntityFromComponentPools(Guid entityId)
  95.         {
  96.             foreach (KeyValuePair<Type, object> componentPool in componentPools)
  97.             {
  98.                 Dictionary<Guid, object> typedTargetPool = (Dictionary<Guid, object>)componentPool.Value;
  99.                 typedTargetPool.Remove(entityId);
  100.             }
  101.         }
  102.  
  103.         private void AddEntityToSystemCache(ISystem system, Guid entityId)
  104.         {
  105.             system.EntityCache.Add(entityId);
  106.         }
  107.  
  108.         private void RemoveEntityFromSystemCache(ISystem system, Guid entityId)
  109.         {
  110.             system.EntityCache.Remove(entityId);
  111.         }
  112.  
  113.         private bool ComponentIsRequiredBySystem<TComponent>(ISystem system) where TComponent : IComponent
  114.         {
  115.             return system.ComponentRequirements.ComponentIsRequired<TComponent>();
  116.         }
  117.  
  118.         private void UpdateSystems(Action<ISystem> systemUpdateAction)
  119.         {
  120.             foreach (ISystem system in systems)
  121.             {
  122.                 systemUpdateAction(system);
  123.             }
  124.         }
  125.  
  126.         public void AddComponentPool<TComponent>() where TComponent : IComponent
  127.         {
  128.             componentPools.Add(typeof(TComponent), new Dictionary<Guid, TComponent>());
  129.         }
  130.  
  131.         public void RemoveComponentPool<TComponent>() where TComponent : IComponent
  132.         {
  133.             if (!ComponentPoolIsRequiredBySystems<TComponent>())
  134.             {
  135.                 componentPools.Remove(typeof(TComponent));
  136.             }
  137.         }
  138.  
  139.         public Dictionary<Guid, TComponent> GetComponentPoolByType<TComponent>() where TComponent : IComponent
  140.         {
  141.             object targetPool = componentPools[typeof(TComponent)];
  142.             return (Dictionary<Guid, TComponent>)targetPool;
  143.         }
  144.  
  145.         private Type[] GetComponentTypesFromEntityById(Guid entityId)
  146.         {
  147.             return componentPools
  148.                     .Where(pool => ((IDictionary)pool.Value)
  149.                     .Contains(entityId))
  150.                     .Select(componentType => componentType.Key)
  151.                     .ToArray();
  152.         }
  153.  
  154.         private bool ComponentPoolIsRequiredBySystems<TComponent>() where TComponent : IComponent
  155.         {
  156.             return systems.Any(system => system.ComponentRequirements.ComponentIsRequired<TComponent>());
  157.         }
  158.  
  159.         public void AddSystem<TSystem>(TSystem system) where TSystem : ISystem
  160.         {
  161.             systems.Add(system);
  162.             ValidateActiveEntities(system);
  163.         }
  164.  
  165.         public void RemoveSystem<TSystem>() where TSystem : ISystem
  166.         {
  167.             systems.Remove(typeof(TSystem));
  168.         }
  169.  
  170.         private void ValidateActiveEntities<TSystem>(TSystem system) where TSystem : ISystem
  171.         {
  172.             for (int i = 0; i < activeEntities.Count; i++)
  173.             {
  174.                 Guid entityId = activeEntities[i];
  175.                 Type[] componentTypes = GetComponentTypesFromEntityById(entityId);
  176.  
  177.                 if (ValidateEntityByComponents(system, componentTypes))
  178.                 {
  179.                     AddEntityToSystemCache(system, entityId);
  180.                 }
  181.             }
  182.         }
  183.  
  184.         private bool ValidateEntityByComponents<TSystem>(TSystem system, Type[] componentTypes) where TSystem : ISystem
  185.         {
  186.             return system.ComponentRequirements.ValidateEntity(componentTypes);
  187.         }
  188.  
  189.         private void AddEntityToSystemCache<TSystem>(TSystem system, Guid entityId) where TSystem : ISystem
  190.         {
  191.             system.EntityCache.Add(entityId);
  192.         }
  193.  
  194.         #endregion Methods
  195.     }
Add Comment
Please, Sign In to add comment