Files
GhostEngine/Ghost.SparseEntities/Template/QueryEnumerable.tt
2025-12-04 16:55:26 +09:00

175 lines
4.8 KiB
Plaintext

<#@ 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<T{i}> 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<T<#= i #>> _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<T<#= i #>>());
<# } #>
_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<Entity> _entities;
private readonly Stack.Scope _stackScope;
<# for (int i = 0; i < arity; i++){ #>
private readonly ComponentPool<T<#= i #>> _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<TComponent<#= j #>>());
<# } #>
return this;
}
public QueryEnumerable<<#= generics #>> WithAny<<#= compGenerics #>>()
<#= compRestrictions #>
{
<# for (int j = 0; j < i; j++) {#>
_filter._any.Add(TypeHandle.Get<TComponent<#= j #>>());
<# } #>
return this;
}
public QueryEnumerable<<#= generics #>> WithAbsent<<#= compGenerics #>>()
<#= compRestrictions #>
{
<# for (int j = 0; j < i; j++) {#>
_filter._absent.Add(TypeHandle.Get<TComponent<#= j #>>());
<# } #>
return this;
}
public QueryEnumerable<<#= generics #>> WithDisabled<<#= compGenerics #>>()
<#= compRestrictions #>
{
<# for (int j = 0; j < i; j++) {#>
_filter._disabled.Add(TypeHandle.Get<TComponent<#= j #>>());
<# } #>
return this;
}
<# } #>
}
<# } #>