<#@ template language="C#" #> <#@ output extension=".cs" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Linq" #> <#@ include file="Helpers.ttinclude" #> using Ghost.Core; using Ghost.Entities.Components; using Ghost.Entities.Query; using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Collections; namespace Ghost.Entities; <# for (int arity = 1; arity <= Amount; arity++) { var generics = AppendGenerics(arity); var restrictions = AppendGenericRestrictions(arity, "unmanaged, IComponentData"); var poolParams = Enumerable.Range(0, arity) .Select(i => $"ComponentPool pool{i}") .Aggregate((a, b) => a + ", " + b); var constructorParams = Enumerable.Range(0, arity) .Select(i => $"_pool{i}") .Aggregate((a, b) => a + ", " + b); #> public unsafe ref struct QueryEnumerable<<#= generics #>> <#= restrictions #> { private QueryFilter _filter; private readonly World _world; <# for (int i = 0; i < arity; i++){ #> private readonly ComponentPool> _pool<#= i #>; <# } #> private readonly int _count; internal QueryEnumerable(World world, <#= poolParams #>, int count) { _filter = new(); <# for (int i = 0; i < arity; i++) {#> _filter._all.Add(TypeHandle.Get>()); <# } #> _world = world; <# for (int i = 0; i < arity; i++) { #> _pool<#= i #> = pool<#= i #>; <# } #> _count = count; } internal QueryEnumerable(World world, <#= poolParams #>, int count, ref readonly QueryFilter filter) { _filter = filter; _world = world; <# for (int i = 0; i < arity; i++) { #> _pool<#= i #> = pool<#= i #>; <# } #> _count = count; } #pragma warning disable CS9084 // Struct member returns 'this' or other instance members by reference public Enumerator GetEnumerator() => new(_world, <#= constructorParams #>, _count, ref _filter); #pragma warning restore CS9084 // Struct member returns 'this' or other instance members by reference public ref struct Enumerator { private ref QueryFilter _filter; private UnsafeBitSet _filterMask; private readonly ReadOnlySpan _entities; private readonly Stack.Scope _stackScope; <# for (int i = 0; i < arity; i++){ #> private readonly ComponentPool> _pool<#= i #>; <# } #> private int _index; private int _count; public QueryItem<<#= generics #>> Current { get; private set; } internal Enumerator(World world, <#= poolParams #>, int count, ref QueryFilter filter) { _stackScope = AllocationManager.CreateStackScope(); _filter = ref filter; _filterMask = _filter.ComputeFilterBitMask(world, Allocator.Stack); _entities = world.EntityManager.Entities; <# for (int i = 0; i < arity; i++){ #> _pool<#= i #> = pool<#= i #>; <# } #> _count = count; _index = -1; Current = default; } public bool MoveNext() { _index = _filterMask.NextSetBit(_index + 1); if (_index < 0 || _count <= 0) { return false; } _count--; Current = new QueryItem<<#= generics #>>(_entities[_index], <#= constructorParams #>); return true; } public readonly void Dispose() { _stackScope.Dispose(); _filter.Dispose(); } } <# for (int i = 1; i <= ExtensionAmount; i++) { var compGenerics = AppendGenerics(i, "TComponent"); var compRestrictions = AppendGenericRestrictions(i, "TComponent", "unmanaged, IComponentData"); #> public QueryEnumerable<<#= generics #>> WithAll<<#= compGenerics #>>() <#= compRestrictions #> { <# for (int j = 0; j < i; j++) {#> _filter._all.Add(TypeHandle.Get>()); <# } #> return this; } public QueryEnumerable<<#= generics #>> WithAny<<#= compGenerics #>>() <#= compRestrictions #> { <# for (int j = 0; j < i; j++) {#> _filter._any.Add(TypeHandle.Get>()); <# } #> return this; } public QueryEnumerable<<#= generics #>> WithAbsent<<#= compGenerics #>>() <#= compRestrictions #> { <# for (int j = 0; j < i; j++) {#> _filter._absent.Add(TypeHandle.Get>()); <# } #> return this; } public QueryEnumerable<<#= generics #>> WithDisabled<<#= compGenerics #>>() <#= compRestrictions #> { <# for (int j = 0; j < i; j++) {#> _filter._disabled.Add(TypeHandle.Get>()); <# } #> return this; } <# } #> } <# } #>