using System; using System.Collections.Generic; namespace MoonTools.ECS { public abstract class EntityComponentReader { internal readonly World World; internal EntityStorage EntityStorage => World.EntityStorage; internal ComponentDepot ComponentDepot => World.ComponentDepot; internal RelationDepot RelationDepot => World.RelationDepot; protected FilterBuilder FilterBuilder => new FilterBuilder(FilterStorage, ComponentTypeIndices); internal FilterStorage FilterStorage => World.FilterStorage; internal TypeIndices ComponentTypeIndices => World.ComponentTypeIndices; internal TypeIndices RelationTypeIndices => World.RelationTypeIndices; internal TemplateStorage TemplateStorage => World.TemplateStorage; internal ComponentDepot TemplateComponentDepot => World.TemplateComponentDepot; public EntityComponentReader(World world) { World = world; } protected ReadOnlySpan ReadComponents() where TComponent : unmanaged { return ComponentDepot.ReadComponents(); } protected bool Has(in Entity entity) where TComponent : unmanaged { var storageIndex = ComponentTypeIndices.GetIndex(); return EntityStorage.HasComponent(entity.ID, storageIndex); } protected bool Some() where TComponent : unmanaged { return ComponentDepot.Some(); } protected ref readonly TComponent Get(in Entity entity) where TComponent : unmanaged { return ref ComponentDepot.Get(entity.ID); } protected ref readonly TComponent GetSingleton() where TComponent : unmanaged { return ref ComponentDepot.GetFirst(); } protected Entity GetSingletonEntity() where TComponent : unmanaged { return ComponentDepot.GetSingletonEntity(); } protected ReverseSpanEnumerator<(Entity, Entity)> Relations() where TRelationKind : unmanaged { return RelationDepot.Relations(); } protected bool Related(in Entity a, in Entity b) where TRelationKind : unmanaged { return RelationDepot.Related(a.ID, b.ID); } protected TRelationKind GetRelationData(in Entity a, in Entity b) where TRelationKind : unmanaged { return RelationDepot.Get(a, b); } // relations go A->B, so given A, will give all entities in outgoing relations of this kind. protected ReverseSpanEnumerator OutRelations(in Entity entity) where TRelationKind : unmanaged { return RelationDepot.OutRelations(entity.ID); } protected Entity OutRelationSingleton(in Entity entity) where TRelationKind : unmanaged { return RelationDepot.OutRelationSingleton(entity.ID); } // NOTE: this WILL crash if at least n + 1 relations do not exist! protected Entity NthOutRelation(in Entity entity, int n) where TRelationKind : unmanaged { return RelationDepot.NthOutRelation(entity.ID, n); } protected bool HasOutRelation(in Entity entity) where TRelationKind : unmanaged { return RelationDepot.HasOutRelation(entity.ID); } protected int OutRelationCount(in Entity entity) where TRelationKind : unmanaged { return RelationDepot.OutRelationCount(entity.ID); } // Relations go A->B, so given B, will give all entities in incoming A relations of this kind. protected ReverseSpanEnumerator InRelations(in Entity entity) where TRelationKind : unmanaged { return RelationDepot.InRelations(entity.ID); } protected Entity InRelationSingleton(in Entity entity) where TRelationKind : unmanaged { return RelationDepot.InRelationSingleton(entity.ID); } // NOTE: this WILL crash if at least n + 1 relations do not exist! protected Entity NthInRelation(in Entity entity, int n) where TRelationKind : unmanaged { return RelationDepot.NthInRelation(entity.ID, n); } protected bool HasInRelation(in Entity entity) where TRelationKind : unmanaged { return RelationDepot.HasInRelation(entity.ID); } protected int InRelationCount(in Entity entity) where TRelationKind : unmanaged { return RelationDepot.InRelationCount(entity.ID); } } }