using System; using System.Runtime.CompilerServices; namespace MoonTools.ECS { internal class ComponentDepot { private TypeIndices ComponentTypeIndices; private ComponentStorage[] storages = new ComponentStorage[256]; public ComponentDepot(TypeIndices componentTypeIndices) { ComponentTypeIndices = componentTypeIndices; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void Register(int index) where TComponent : unmanaged { if (index >= storages.Length) { Array.Resize(ref storages, storages.Length * 2); } storages[index] = new ComponentStorage(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ComponentStorage Lookup() where TComponent : unmanaged { var storageIndex = ComponentTypeIndices.GetIndex(); // TODO: is there some way to avoid this null check? if (storages[storageIndex] == null) { Register(storageIndex); } return (ComponentStorage) storages[storageIndex]; } public bool Some() where TComponent : unmanaged { return Lookup().Any(); } public ref readonly TComponent Get(int entityID) where TComponent : unmanaged { return ref Lookup().Get(entityID); } #if DEBUG public object Debug_Get(int entityID, int componentTypeIndex) { return storages[componentTypeIndex].Debug_Get(entityID); } #endif public ref readonly TComponent GetFirst() where TComponent : unmanaged { return ref Lookup().GetFirst(); } public void Set(int entityID, in TComponent component) where TComponent : unmanaged { Lookup().Set(entityID, component); } public Entity GetSingletonEntity() where TComponent : unmanaged { return Lookup().FirstEntity(); } public ReadOnlySpan ReadComponents() where TComponent : unmanaged { return Lookup().AllComponents(); } public void Remove(int entityID, int storageIndex) { storages[storageIndex].Remove(entityID); } public void Remove(int entityID) where TComponent : unmanaged { Lookup().Remove(entityID); } } }