using System; using System.Collections; using System.Collections.Generic; using System.Linq; using gaemstone.ECS.Internal; using gaemstone.ECS.Utility; using static flecs_hub.flecs; namespace gaemstone.ECS; public unsafe class Iterator : Iterator , IEnumerable> { public new World World => new(base.World); public Iterator(ecs_iter_t* handle) : base(handle) { } public Iterator(ecs_iter_t value) : base(value) { } public static TermIterator FromTerm(World world, Term term) { using var alloc = TempAllocator.Use(); var flecsTerm = term.ToFlecs(alloc); var flecsIter = ecs_term_iter(world, &flecsTerm); return new(flecsIter); } public new Entity? GetVar(Variable var) => Entity.GetOrNull(World, base.GetVar(var)); public new Iterator SetVar(Variable var, Entity entity) => (Iterator)base.SetVar(var, entity); public new Entity? First() => Entity.GetOrNull(World, base.First()); public new IEnumerable> GetAllEntities() => base.GetAllEntities().Select(e => Entity.GetOrInvalid(World, e)); public new Id FieldId(int index) => Id.GetUnsafe(World, base.FieldId(index)); public new Entity Entity(int index) => Entity.GetOrInvalid(World, base.Entity(index)); // IEnumerable implementation public virtual IEnumerator> GetEnumerator() { while (Next()) yield return this; } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } [Flags] public enum IteratorFlags : uint { /// Does iterator contain valid result. IsValid = EcsIterIsValid, /// Does iterator provide (component). NoData = EcsIterNoData, /// Is iterator instanced. IsInstanced = EcsIterIsInstanced, /// Does result have shared terms. HasShared = EcsIterHasShared, /// Result only populates table. TableOnly = EcsIterTableOnly, /// Treat terms with entity subject as optional. EntityOptional = EcsIterEntityOptional, /// Iterator has no results. NoResults = EcsIterNoResults, /// Only evaluate non-this terms. IgnoreThis = EcsIterIgnoreThis, /// Does iterator have conditionally set fields. MatchVar = EcsIterMatchVar, /// HasCondSet = EcsIterHasCondSet, /// Profile iterator performance. Profile = EcsIterProfile, } public class Variable { public int Index { get; } public string Name { get; } public Variable(int index, string name) { Index = index; Name = name; } } public unsafe class TermIterator : Iterator { internal TermIterator(ecs_iter_t value) : base(value) { } public override bool Next() => ecs_term_next(Handle); }