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