encompass-cs/encompass-cs/ComponentManager.cs

273 lines
11 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
2020-03-18 00:40:11 +00:00
using MoonTools.FastCollections;
2019-06-16 01:05:56 +00:00
namespace Encompass
{
internal class ComponentManager
{
2019-06-20 17:46:15 +00:00
private readonly DrawLayerManager drawLayerManager;
private readonly ComponentStore existingComponentStore;
2019-12-30 03:08:32 +00:00
private readonly ComponentStore immediateComponentStore;
private readonly ComponentDeltaStore replayStore;
private ComponentStore upToDateComponentStore;
public Dictionary<Type, int> TypeToIndex { get; }
private readonly HashSet<int> entitiesMarkedForRemoval = new HashSet<int>();
2019-07-18 01:53:31 +00:00
internal ComponentBitSet ImmediateBits { get { return immediateComponentStore.ComponentBitSet; } }
internal ComponentBitSet ExistingBits { get { return existingComponentStore.ComponentBitSet; } }
2019-12-28 21:53:02 +00:00
public ComponentManager(DrawLayerManager drawLayerManager, Dictionary<Type, int> typeToIndex)
2019-06-19 23:13:02 +00:00
{
this.drawLayerManager = drawLayerManager;
existingComponentStore = new ComponentStore(typeToIndex);
2019-12-30 03:08:32 +00:00
immediateComponentStore = new ComponentStore(typeToIndex);
replayStore = new ComponentDeltaStore(typeToIndex);
upToDateComponentStore = new ComponentStore(typeToIndex);
TypeToIndex = typeToIndex;
2019-06-19 23:13:02 +00:00
}
2019-12-16 07:28:02 +00:00
public void RegisterComponentType<TComponent>() where TComponent : struct, IComponent
{
existingComponentStore.RegisterComponentType<TComponent>();
immediateComponentStore.RegisterComponentType<TComponent>();
2019-12-30 03:08:32 +00:00
replayStore.RegisterComponentType<TComponent>();
upToDateComponentStore.RegisterComponentType<TComponent>();
2019-12-16 07:28:02 +00:00
}
internal void SetExistingComponentStore(ComponentStore componentStore)
2019-06-16 01:05:56 +00:00
{
existingComponentStore.SwapWith(componentStore);
}
internal void SetUpToDateComponentStore(ComponentStore componentStore)
{
upToDateComponentStore.SwapWith(componentStore);
}
2019-12-29 21:54:08 +00:00
internal void RegisterDrawableComponent<TComponent>(int entityID, TComponent component, int layer) where TComponent : struct, IComponent
{
2019-12-29 21:54:08 +00:00
drawLayerManager.RegisterComponentWithLayer(entityID, component, layer);
}
internal void WriteComponents()
{
2019-12-30 03:08:32 +00:00
existingComponentStore.UpdateUsing(replayStore);
existingComponentStore.ClearAllPriorities();
upToDateComponentStore.ClearAllPriorities();
immediateComponentStore.ClearAll();
2019-12-30 03:08:32 +00:00
replayStore.ClearAll();
}
2019-12-29 21:54:08 +00:00
internal bool AddImmediateComponent<TComponent>(int entityID, TComponent component, int priority) where TComponent : struct, IComponent
{
2019-12-29 21:54:08 +00:00
if (immediateComponentStore.Set(entityID, component, priority))
{
2019-12-30 03:08:32 +00:00
replayStore.Set(entityID, component);
2019-12-29 21:54:08 +00:00
upToDateComponentStore.Set(entityID, component);
return true;
}
return false;
}
internal void AddImmediateComponent<TComponent>(int entityID, TComponent component) where TComponent : struct, IComponent
{
immediateComponentStore.Set(entityID, component);
replayStore.Set(entityID, component);
upToDateComponentStore.Set(entityID, component);
}
internal bool UpdateComponent<TComponent>(int entityID, TComponent component, int priority) where TComponent : struct, IComponent
{
2019-12-30 03:08:32 +00:00
var result = upToDateComponentStore.Set(entityID, component, priority);
if (result)
{
replayStore.Set(entityID, component);
}
return result;
}
internal void AddComponent<TComponent>(int entityID, TComponent component) where TComponent : struct, IComponent
{
upToDateComponentStore.Set(entityID, component);
replayStore.Set(entityID, component);
}
// existing or immediate reads
internal IEnumerable<(TComponent, int)> ReadExistingAndImmediateComponentsByType<TComponent>() where TComponent : struct, IComponent
{
return upToDateComponentStore.All<TComponent>();
}
internal (TComponent, int) ReadFirstExistingOrImmediateComponentByType<TComponent>() where TComponent : struct, IComponent
{
if (!SomeExistingOrImmediateComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
var enumerator = ReadExistingAndImmediateComponentsByType<TComponent>().GetEnumerator();
enumerator.MoveNext();
return enumerator.Current;
}
internal bool SomeExistingOrImmediateComponent<TComponent>() where TComponent : struct, IComponent
{
return upToDateComponentStore.Any<TComponent>();
}
// existing reads
internal (TComponent, int) ReadFirstExistingComponentByType<TComponent>() where TComponent : struct, IComponent
{
if (!SomeExistingComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
var enumerator = GetComponentsIncludingEntity<TComponent>().GetEnumerator();
enumerator.MoveNext();
return enumerator.Current;
}
internal bool SomeExistingComponent<TComponent>() where TComponent : struct, IComponent
{
return existingComponentStore.Any<TComponent>();
}
// immediate reads
internal IEnumerable<(TComponent, int)> ReadImmediateComponentsByType<TComponent>() where TComponent : struct, IComponent
{
return immediateComponentStore.All<TComponent>();
}
internal (TComponent, int) ReadFirstImmediateComponentByType<TComponent>() where TComponent : struct, IComponent
{
if (!SomeImmediateComponent<TComponent>()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); }
var enumerator = ReadImmediateComponentsByType<TComponent>().GetEnumerator();
enumerator.MoveNext();
return enumerator.Current;
}
internal bool SomeImmediateComponent<TComponent>() where TComponent : struct, IComponent
{
return immediateComponentStore.Any<TComponent>();
}
// component getters
2019-12-29 21:54:08 +00:00
internal TComponent ReadImmediateOrExistingComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
{
2019-12-29 21:54:08 +00:00
return upToDateComponentStore.Get<TComponent>(entityID);
}
2019-12-29 21:54:08 +00:00
internal TComponent ReadExistingComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
{
2019-12-29 21:54:08 +00:00
return existingComponentStore.Get<TComponent>(entityID);
}
2019-12-29 21:54:08 +00:00
internal TComponent ReadImmediateComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
{
2019-12-29 21:54:08 +00:00
return immediateComponentStore.Get<TComponent>(entityID);
}
// has checkers
2019-12-29 21:54:08 +00:00
internal bool HasExistingOrImmediateComponent<TComponent>(int entityID) where TComponent : struct, IComponent
{
2019-12-29 21:54:08 +00:00
return upToDateComponentStore.Has<TComponent>(entityID);
}
2019-12-29 21:54:08 +00:00
internal bool HasExistingOrImmediateComponent(int entityID, Type type)
{
2019-12-29 21:54:08 +00:00
return upToDateComponentStore.Has(type, entityID);
}
2019-12-29 21:54:08 +00:00
internal bool HasExistingComponent<TComponent>(int entityID) where TComponent : struct, IComponent
{
2019-12-29 21:54:08 +00:00
return existingComponentStore.Has<TComponent>(entityID);
}
2019-12-29 21:54:08 +00:00
internal bool HasExistingComponent(int entityID, Type type)
{
2019-12-29 21:54:08 +00:00
return existingComponentStore.Has(type, entityID);
}
2019-12-29 21:54:08 +00:00
internal bool HasImmediateComponent<TComponent>(int entityID) where TComponent : struct, IComponent
{
2019-12-29 21:54:08 +00:00
return immediateComponentStore.Has<TComponent>(entityID);
}
2019-12-29 21:54:08 +00:00
internal bool HasImmediateComponent(int entityID, Type type)
{
2019-12-29 21:54:08 +00:00
return immediateComponentStore.Has(type, entityID);
2019-12-05 22:59:55 +00:00
}
internal IEnumerable<(TComponent, int)> GetComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent
2019-12-05 22:59:55 +00:00
{
return existingComponentStore.All<TComponent>();
}
2019-12-05 20:10:33 +00:00
internal IEnumerable<TComponent> GetComponentsByType<TComponent>() where TComponent : struct, IComponent
2019-06-19 21:14:44 +00:00
{
foreach (var pair in existingComponentStore.All<TComponent>())
2019-12-17 04:40:15 +00:00
{
yield return pair.Item1;
}
2019-06-19 21:14:44 +00:00
}
2019-12-29 21:54:08 +00:00
internal TComponent GetComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
2019-06-16 01:05:56 +00:00
{
2019-12-29 21:54:08 +00:00
return existingComponentStore.Get<TComponent>(entityID);
}
2019-12-29 21:54:08 +00:00
internal bool EntityHasComponentOfType<TComponent>(int entityID) where TComponent : struct, IComponent
2019-06-19 21:14:44 +00:00
{
2019-12-29 21:54:08 +00:00
return existingComponentStore.Has<TComponent>(entityID);
}
2019-12-29 21:54:08 +00:00
internal void MarkAllComponentsOnEntityForRemoval(int entityID)
{
2019-12-29 21:54:08 +00:00
entitiesMarkedForRemoval.Add(entityID);
}
internal void RemoveMarkedComponents()
{
foreach (var entityID in entitiesMarkedForRemoval)
{
existingComponentStore.Remove(entityID);
immediateComponentStore.Remove(entityID);
2019-12-30 03:08:32 +00:00
replayStore.Remove(entityID);
upToDateComponentStore.Remove(entityID);
drawLayerManager.UnRegisterEntityWithLayer(entityID);
}
2019-12-05 20:10:33 +00:00
entitiesMarkedForRemoval.Clear();
}
2019-12-29 21:54:08 +00:00
public bool RemoveImmediate<TComponent>(int entityID, int priority) where TComponent : struct, IComponent
2019-06-16 01:05:56 +00:00
{
2019-12-29 21:54:08 +00:00
if (immediateComponentStore.Remove<TComponent>(entityID, priority))
{
2019-12-30 03:08:32 +00:00
replayStore.Remove<TComponent>(entityID, priority);
2019-12-29 21:54:08 +00:00
upToDateComponentStore.Remove<TComponent>(entityID, priority);
drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entityID);
return true;
}
return false;
}
2019-12-29 21:54:08 +00:00
public void Remove<TComponent>(int entityID, int priority) where TComponent : struct, IComponent
{
2019-12-29 21:54:08 +00:00
if (upToDateComponentStore.Remove<TComponent>(entityID, priority))
{
2019-12-30 03:08:32 +00:00
replayStore.Remove<TComponent>(entityID, priority);
2019-12-29 21:54:08 +00:00
drawLayerManager.UnRegisterComponentWithLayer<TComponent>(entityID);
}
}
2020-03-18 00:40:11 +00:00
public bool UpToDateEntityIsEmpty(int entityID)
{
return upToDateComponentStore.EntityBitArray(entityID).AllFalse();
}
}
}