using System; using System.Collections.Generic; using System.Runtime.CompilerServices; namespace MoonTools.ECS { internal class RelationDepot { private TypeIndices RelationTypeIndices; private RelationStorage[] storages = new RelationStorage[256]; public RelationDepot(TypeIndices relationTypeIndices) { RelationTypeIndices = relationTypeIndices; } private void Register(int index) where TRelationKind : unmanaged { if (index >= storages.Length) { Array.Resize(ref storages, storages.Length * 2); } storages[index] = new RelationStorage(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private RelationStorage Lookup() where TRelationKind : unmanaged { var storageIndex = RelationTypeIndices.GetIndex(); // TODO: is there some way to avoid this null check? if (storages[storageIndex] == null) { Register(storageIndex); } return (RelationStorage) storages[storageIndex]; } public void Set(Relation relation, TRelationKind relationData) where TRelationKind : unmanaged { Lookup().Set(relation, relationData); } public (bool, bool) Remove(Relation relation) where TRelationKind : unmanaged { return Lookup().Remove(relation); } public void UnrelateAll(int entityID) where TRelationKind : unmanaged { Lookup().UnrelateAll(entityID); } public void UnrelateAll(int entityID, int relationStorageIndex) { storages[relationStorageIndex].UnrelateAll(entityID); } public IEnumerable<(Entity, Entity, TRelationKind)> Relations() where TRelationKind : unmanaged { return Lookup().All(); } public bool Related(int idA, int idB) where TRelationKind : unmanaged { return Lookup().Has(new Relation(idA, idB)); } public IEnumerable<(Entity, TRelationKind)> OutRelations(int entityID) where TRelationKind : unmanaged { return Lookup().OutRelations(entityID); } public (Entity, TRelationKind) OutRelationSingleton(int entityID) where TRelationKind : unmanaged { return Lookup().OutFirst(entityID); } public int OutRelationCount(int entityID) where TRelationKind : unmanaged { return Lookup().OutRelationCount(entityID); } public bool HasOutRelation(int entityID) where TRelationKind : unmanaged { return Lookup().HasOutRelation(entityID); } public IEnumerable<(Entity, TRelationKind)> InRelations(int entityID) where TRelationKind : unmanaged { return Lookup().InRelations(entityID); } public (Entity, TRelationKind) InRelationSingleton(int entityID) where TRelationKind : unmanaged { return Lookup().InFirst(entityID); } public bool HasInRelation(int entityID) where TRelationKind : unmanaged { return Lookup().HasInRelation(entityID); } public int InRelationCount(int entityID) where TRelationKind : unmanaged { return Lookup().InRelationCount(entityID); } } }