encompass-cs/encompass-cs/ComponentManager.cs

329 lines
12 KiB
C#

using System;
using System.Collections.Generic;
namespace Encompass
{
internal class ComponentManager
{
private readonly ComponentStore _existingComponentStore;
private readonly ComponentStore _immediateComponentStore;
private readonly ComponentDeltaStore _replayStore;
private readonly ComponentStore _upToDateComponentStore;
public Dictionary<Type, int> TypeToIndex { get; }
private Dictionary<int, Type> IndexToType { get; }
private readonly HashSet<int> _entitiesMarkedForRemoval = new HashSet<int>();
internal ComponentBitSet ImmediateBits { get { return _immediateComponentStore.ComponentBitSet; } }
internal ComponentBitSet ExistingBits { get { return _existingComponentStore.ComponentBitSet; } }
public ComponentManager(Dictionary<Type, int> typeToIndex, Dictionary<int, Type> indexToType)
{
_existingComponentStore = new ComponentStore(typeToIndex);
_immediateComponentStore = new ComponentStore(typeToIndex);
_replayStore = new ComponentDeltaStore(typeToIndex);
_upToDateComponentStore = new ComponentStore(typeToIndex);
TypeToIndex = typeToIndex;
IndexToType = indexToType;
}
public void RegisterComponentType<TComponent>() where TComponent : struct
{
_existingComponentStore.RegisterComponentType<TComponent>();
_immediateComponentStore.RegisterComponentType<TComponent>();
_replayStore.RegisterComponentType<TComponent>();
_upToDateComponentStore.RegisterComponentType<TComponent>();
}
internal void SetExistingComponentStore(ComponentStore componentStore)
{
_existingComponentStore.SwapWith(componentStore);
}
internal void SetUpToDateComponentStore(ComponentStore componentStore)
{
_upToDateComponentStore.SwapWith(componentStore);
}
internal void WriteComponents()
{
_existingComponentStore.UpdateUsing(_replayStore);
_existingComponentStore.ClearAllPriorities();
_upToDateComponentStore.ClearAllPriorities();
_immediateComponentStore.ClearAll();
_replayStore.ClearAll();
}
internal bool AddImmediateComponent<TComponent>(int entityID, in TComponent component, int priority) where TComponent : struct
{
if (_immediateComponentStore.Set(entityID, component, priority))
{
_replayStore.Set(entityID, component);
_upToDateComponentStore.Set(entityID, component);
return true;
}
return false;
}
internal void AddImmediateComponent<TComponent>(int entityID, in TComponent component) where TComponent : struct
{
_immediateComponentStore.Set(entityID, component);
_replayStore.Set(entityID, component);
_upToDateComponentStore.Set(entityID, component);
}
internal bool UpdateComponent<TComponent>(int entityID, in TComponent component, int priority) where TComponent : struct
{
var result = _upToDateComponentStore.Set(entityID, component, priority);
if (result)
{
_replayStore.Set(entityID, component);
}
return result;
}
#if DEBUG
internal void Debug_UpdateComponent<TComponent>(int entityID, in TComponent component) where TComponent : struct
{
_existingComponentStore.Set(entityID, component);
}
#endif
internal void AddComponent<TComponent>(int entityID, in TComponent component) where TComponent : struct
{
_upToDateComponentStore.Set(entityID, component);
_replayStore.Set(entityID, component);
}
// existing or immediate reads
internal ReadOnlySpan<TComponent> ReadExistingAndImmediateComponentsByType<TComponent>() where TComponent : struct
{
return _upToDateComponentStore.All<TComponent>();
}
internal ref readonly TComponent ExistingOrImmediateSingular<TComponent>() where TComponent : struct
{
return ref _upToDateComponentStore.Singular<TComponent>();
}
internal ReadOnlySpan<Entity> GetExistingAndImmediateEntities<TComponent>() where TComponent : struct
{
return _upToDateComponentStore.AllEntities<TComponent>();
}
internal ref readonly Entity ExistingOrImmediateSingularEntity<TComponent>() where TComponent : struct
{
return ref _upToDateComponentStore.SingularEntity<TComponent>();
}
internal bool SomeExistingOrImmediateComponent<TComponent>() where TComponent : struct
{
return _upToDateComponentStore.Any<TComponent>();
}
// existing reads
internal ReadOnlySpan<TComponent> GetExistingComponents<TComponent>() where TComponent : struct
{
return _existingComponentStore.All<TComponent>();
}
internal ref readonly TComponent ExistingSingular<TComponent>() where TComponent : struct
{
return ref _existingComponentStore.Singular<TComponent>();
}
internal ReadOnlySpan<Entity> GetExistingEntities<TComponent>() where TComponent : struct
{
return _existingComponentStore.AllEntities<TComponent>();
}
internal IEnumerable<Entity> GetExistingEntitiesAsEnumerable<TComponent>() where TComponent : struct
{
return _existingComponentStore.AllEntitiesAsEnumerable<TComponent>();
}
internal ref readonly Entity ExistingSingularEntity<TComponent>() where TComponent : struct
{
return ref _existingComponentStore.SingularEntity<TComponent>();
}
internal bool SomeExistingComponent<TComponent>() where TComponent : struct
{
return _existingComponentStore.Any<TComponent>();
}
// immediate reads
internal ReadOnlySpan<TComponent> ReadImmediateComponentsByType<TComponent>() where TComponent : struct
{
return _immediateComponentStore.All<TComponent>();
}
internal ref readonly TComponent ImmediateSingular<TComponent>() where TComponent : struct
{
return ref _immediateComponentStore.Singular<TComponent>();
}
internal ReadOnlySpan<Entity> GetImmediateEntities<TComponent>() where TComponent : struct
{
return _immediateComponentStore.AllEntities<TComponent>();
}
internal ref readonly Entity ImmediateSingularEntity<TComponent>() where TComponent : struct
{
return ref _immediateComponentStore.SingularEntity<TComponent>();
}
internal bool SomeImmediateComponent<TComponent>() where TComponent : struct
{
return _immediateComponentStore.Any<TComponent>();
}
// component getters
internal ref TComponent ReadImmediateOrExistingComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct
{
return ref _upToDateComponentStore.Get<TComponent>(entityID);
}
internal ref TComponent ReadExistingComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct
{
return ref _existingComponentStore.Get<TComponent>(entityID);
}
#if DEBUG
internal TComponent Debug_ReadExistingComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct
{
return _existingComponentStore.Get<TComponent>(entityID);
}
#endif
internal ref TComponent ReadImmediateComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct
{
return ref _immediateComponentStore.Get<TComponent>(entityID);
}
// has checkers
internal bool HasExistingOrImmediateComponent<TComponent>(int entityID) where TComponent : struct
{
return _upToDateComponentStore.Has<TComponent>(entityID);
}
internal bool HasExistingOrImmediateComponent(int entityID, Type type)
{
return _upToDateComponentStore.Has(type, entityID);
}
internal bool HasExistingComponent<TComponent>(int entityID) where TComponent : struct
{
return _existingComponentStore.Has<TComponent>(entityID);
}
internal bool HasExistingComponent(int entityID, Type type)
{
return _existingComponentStore.Has(type, entityID);
}
internal bool HasImmediateComponent<TComponent>(int entityID) where TComponent : struct
{
return _immediateComponentStore.Has<TComponent>(entityID);
}
internal bool HasImmediateComponent(int entityID, Type type)
{
return _immediateComponentStore.Has(type, entityID);
}
internal ReadOnlySpan<TComponent> GetComponentsByType<TComponent>() where TComponent : struct
{
return _existingComponentStore.All<TComponent>();
}
internal IEnumerable<TComponent> GetComponentsByTypeEnumerable<TComponent>() where TComponent : struct
{
return _existingComponentStore.AllAsEnumerable<TComponent>();
}
internal ref readonly TComponent GetComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct
{
return ref _existingComponentStore.Get<TComponent>(entityID);
}
internal bool EntityHasComponentOfType<TComponent>(int entityID) where TComponent : struct
{
return _existingComponentStore.Has<TComponent>(entityID);
}
internal void MarkAllComponentsOnEntityForRemoval(int entityID)
{
_entitiesMarkedForRemoval.Add(entityID);
}
internal void RemoveMarkedComponents()
{
foreach (var entityID in _entitiesMarkedForRemoval)
{
_existingComponentStore.Remove(entityID);
_immediateComponentStore.Remove(entityID);
_replayStore.Remove(entityID);
_upToDateComponentStore.Remove(entityID);
}
_entitiesMarkedForRemoval.Clear();
}
public bool RemoveImmediate<TComponent>(int entityID, int priority) where TComponent : struct
{
if (_immediateComponentStore.Remove<TComponent>(entityID, priority))
{
_replayStore.Remove<TComponent>(entityID, priority);
_upToDateComponentStore.Remove<TComponent>(entityID, priority);
return true;
}
return false;
}
public void Remove<TComponent>(int entityID, int priority) where TComponent : struct
{
if (_upToDateComponentStore.Remove<TComponent>(entityID, priority))
{
_replayStore.Remove<TComponent>(entityID, priority);
}
}
public bool UpToDateEntityIsEmpty(int entityID)
{
return _upToDateComponentStore.EntityBitArray(entityID).AllFalse();
}
// should be used for debugging only!
#if DEBUG
internal IEnumerable<object> Debug_Components(int entityID)
{
foreach (var typeIndex in ExistingBits.EntityBitArray(entityID).TrueIndices())
{
var method = typeof(ComponentManager).GetMethod(nameof(ComponentManager.Debug_ReadExistingComponentByEntityAndType), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var generic = method.MakeGenericMethod(IndexToType[typeIndex]);
yield return generic.Invoke(this, new object[] { entityID });
}
}
internal IEnumerable<Type> Debug_SearchComponentType(string typeString)
{
foreach (var type in TypeToIndex.Keys)
{
if (type.ToString().ToLower().Contains(typeString.ToLower()))
{
yield return type;
}
}
}
#endif
}
}