encompass-cs/encompass-cs/Collections/ComponentStore.cs

173 lines
5.5 KiB
C#

using Encompass.Exceptions;
using MoonTools.FastCollections;
using System;
using System.Collections.Generic;
namespace Encompass
{
internal sealed class ComponentStore
{
private Dictionary<Type, TypedComponentStore> _stores = new Dictionary<Type, TypedComponentStore>(512);
public ComponentBitSet ComponentBitSet { get; private set; }
private readonly Dictionary<Type, int> _typeToIndex;
public ComponentStore(Dictionary<Type, int> typeToIndex)
{
_typeToIndex = typeToIndex;
ComponentBitSet = new ComponentBitSet(typeToIndex);
}
public void RegisterComponentType<TComponent>() where TComponent : struct
{
if (!_stores.ContainsKey(typeof(TComponent)))
{
var store = new TypedComponentStore<TComponent>();
_stores.Add(typeof(TComponent), store);
}
if (!_typeToIndex.ContainsKey(typeof(TComponent))) { _typeToIndex.Add(typeof(TComponent), _typeToIndex.Count); }
}
private TypedComponentStore<TComponent> Lookup<TComponent>() where TComponent : struct
{
return _stores[typeof(TComponent)] as TypedComponentStore<TComponent>;
}
public bool Has<TComponent>(int entityID) where TComponent : struct
{
return Lookup<TComponent>().Has(entityID);
}
public bool Has(Type type, int entityID)
{
return _stores[type].Has(entityID);
}
public BitSet512 EntityBitArray(int entityID)
{
return ComponentBitSet.EntityBitArray(entityID);
}
public ref TComponent Get<TComponent>(int entityID) where TComponent : struct
{
return ref Lookup<TComponent>().Get(entityID);
}
public ref readonly TComponent Singular<TComponent>() where TComponent : struct
{
if (!Any<TComponent>()) { throw new NoComponentOfTypeException("No component of type {0} exists", typeof(TComponent).Name); }
return ref Lookup<TComponent>().Singular();
}
public ref readonly Entity SingularEntity<TComponent>() where TComponent : struct
{
if (!Any<TComponent>()) { throw new NoComponentOfTypeException("No component of type {0} exists", typeof(TComponent).Name); }
return ref Lookup<TComponent>().SingularEntity();
}
public void Set<TComponent>(int entityID, in TComponent component) where TComponent : struct
{
Lookup<TComponent>().Set(entityID, component);
ComponentBitSet.Set<TComponent>(entityID);
}
public bool Set<TComponent>(int entityID, in TComponent component, int priority) where TComponent : struct
{
if (Lookup<TComponent>().Set(entityID, component, priority))
{
ComponentBitSet.Set<TComponent>(entityID);
return true;
}
return false;
}
public bool Remove<TComponent>(int entityID, int priority) where TComponent : struct
{
if (Lookup<TComponent>().Remove(entityID, priority))
{
ComponentBitSet.RemoveComponent<TComponent>(entityID);
return true;
}
return false;
}
public void ForceRemove<TComponent>(int entityID) where TComponent : struct
{
Lookup<TComponent>().ForceRemove(entityID);
ComponentBitSet.RemoveComponent<TComponent>(entityID);
}
public void Remove(int entityID)
{
foreach (var entry in _stores.Values)
{
entry.ForceRemove(entityID);
}
ComponentBitSet.RemoveEntity(entityID);
}
public bool Any<TComponent>() where TComponent : struct
{
return Lookup<TComponent>().Count > 0;
}
public ReadOnlySpan<TComponent> All<TComponent>() where TComponent : struct
{
return Lookup<TComponent>().AllComponents();
}
public IEnumerable<TComponent> AllAsEnumerable<TComponent>() where TComponent : struct
{
return Lookup<TComponent>().AllComponentsAsEnumerable();
}
public ReadOnlySpan<Entity> AllEntities<TComponent>() where TComponent : struct
{
return Lookup<TComponent>().AllEntities();
}
public IEnumerable<Entity> AllEntitiesAsEnumerable<TComponent>() where TComponent : struct
{
return Lookup<TComponent>().AllEntitiesAsEnumerable();
}
public void Clear<TComponent>() where TComponent : struct
{
Lookup<TComponent>().Clear();
}
public void ClearAllPriorities()
{
foreach (var store in _stores.Values)
{
store.ClearPriorities();
}
}
public void ClearAll()
{
ComponentBitSet.Clear();
foreach (var store in _stores.Values)
{
store.Clear();
}
}
public void SwapWith(ComponentStore other)
{
(_stores, other._stores) = (other._stores, _stores);
(ComponentBitSet, other.ComponentBitSet) = (other.ComponentBitSet, ComponentBitSet);
}
public void UpdateUsing(ComponentDeltaStore delta)
{
foreach (var replayer in delta.CurrentReplayers)
{
replayer.Replay(this);
}
}
}
}