Refactor folder structure

This commit is contained in:
2026-02-18 00:50:46 +09:00
parent 426786397c
commit db8ca971a8
413 changed files with 2885 additions and 3634 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,234 @@
<#@ template language="C#" #>
<#@ output extension="gen.cs" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ include file="Helpers.ttinclude" #>
using Ghost.Core;
using Misaki.HighPerformance.LowLevel;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
using System.Runtime.CompilerServices;
namespace Ghost.Entities;
public unsafe partial struct EntityQuery
{
<# for (var i = 1; i <= Amount; i++)
{
var generics = AppendParameters(i, "T{0}");
var compGenerics = AppendParameters(i, "ref T{0} component{0}");
var deconstrictOutPrams = AppendParameters(i, "out Ref<T{0}> component{0}");
var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 2);
#>
public readonly ref struct ComponentIterator<<#= generics#>>
<#= restrictions #>
{
<# if (i > 1) { #>
public ref struct QueryItem
{
<# for (var j = 0; j < i; j++) { #>
public ref T<#= j #> component<#= j #>;
<# } #>
internal QueryItem(<#= compGenerics #>)
{
<# for (var j = 0; j < i; j++) { #>
this.component<#= j #> = ref component<#= j #>;
<# } #>
}
public void Deconstruct(<#= deconstrictOutPrams #>)
{
<# for (var j = 0; j < i; j++) { #>
component<#= j #> = new Ref<T<#= j #>>(ref this.component<#= j #>);
<# } #>
}
}
<# } #>
public ref struct Enumerator : IDisposable
{
private fixed int _compTypeIDs[<#= i #>];
private fixed int _offsets[<#= i #>];
private fixed long _compBasePtrs[<#= i #>];
private readonly ReadOnlyUnsafeCollection<Identifier<Archetype>> _matchingArchetypes;
private readonly EntityQueryMask _mask;
private readonly World _world;
private readonly Stack.Scope _scope;
private UnsafeList<int> _changedComponentIDs;
private ref Archetype _currentArchetype;
private ref Chunk _currentChunk;
private byte* _chunkBasePtr;
private int _currentChunkEntityCount;
private int _currentArchetypeIndex;
private int _currentChunkIndex;
private int _currentEntityIndex;
internal Enumerator(ReadOnlyUnsafeCollection<Identifier<Archetype>> matchingArchetypes, EntityQueryMask mask, World world)
{
<# for (var j = 0; j < i; j++) { #>
_compTypeIDs[<#= j #>] = ComponentTypeID<T<#= j #>>.Value;
_offsets[<#= j #>] = 0;
_compBasePtrs[<#= j #>] = 0;
<# } #>
_matchingArchetypes = matchingArchetypes;
_mask = mask;
_world = world;
_scope = AllocationManager.CreateStackScope();
_changedComponentIDs = new UnsafeList<int>(<#= i #>, _scope.AllocationHandle);
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i = 0; i < <#= i #>; i++)
{
if (id == _compTypeIDs[i])
{
_changedComponentIDs.Add(id);
break;
}
}
}
Reset();
}
<# if (i > 1) { #>
public QueryItem Current => new(
<# for (var j = 0; j < i; j++) { #>
ref *(T<#= j #>*)(_compBasePtrs[<#= j #>] + _currentEntityIndex * sizeof(T<#= j #>))<#= j < i - 1 ? "," : "" #>
<# } #>
);
<# } else { #>
public ref T0 Current => ref *(T0*)(_compBasePtrs[0] + _currentEntityIndex * sizeof(T0));
<# } #>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetChunk(int chunkIndex)
{
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
_chunkBasePtr = _currentChunk.GetUnsafePtr();
_currentChunkEntityCount = _currentChunk._count;
for (var index = 0; index < <#= i #>; index++)
{
var layout = _currentArchetype.GetLayout(_compTypeIDs[index])
.GetValueOrThrow();
_offsets[index] = layout.offset;
_compBasePtrs[index] = (long)(_chunkBasePtr + _offsets[index]);
}
for (var i = 0; i < _changedComponentIDs.Count; i++)
{
_currentArchetype.MarkChanged(_currentChunkIndex, _changedComponentIDs[i], _world.Version);
}
}
public bool MoveNext()
{
while (true)
{
_currentEntityIndex++;
if (_currentEntityIndex < _currentChunk._count)
{
var pChunkData = _currentChunk.GetUnsafePtr();
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
{
return true;
}
continue;
}
_currentChunkIndex++;
if (!Unsafe.IsNullRef(ref _currentArchetype) && _currentChunkIndex < _currentArchetype.ChunkCount)
{
SetChunk(_currentChunkIndex);
_currentEntityIndex = -1; // Reset for new chunk
continue;
}
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
_currentEntityIndex = -1;
continue;
}
// If archetype has no chunks, loop will try next archetype
}
else
{
return false; // End of all data
}
}
}
public void Reset()
{
_currentArchetype = ref Unsafe.NullRef<Archetype>();
_currentChunk = ref Unsafe.NullRef<Chunk>();
_currentArchetypeIndex = 0;
_currentChunkIndex = 0;
_currentEntityIndex = -1;
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
}
}
}
public readonly void Dispose()
{
_scope.Dispose();
}
}
private readonly ReadOnlyUnsafeCollection<Identifier<Archetype>> _matchingArchetypes;
private readonly EntityQueryMask _mask;
private readonly World _world;
internal ComponentIterator(ReadOnlyUnsafeCollection<Identifier<Archetype>> matchingArchetypes, EntityQueryMask mask, World world)
{
_matchingArchetypes = matchingArchetypes;
_mask = mask;
_world = world;
}
public Enumerator GetEnumerator()
{
return new Enumerator(_matchingArchetypes, _mask, _world);
}
}
public readonly ComponentIterator<<#= generics#>> GetComponentIterator<<#= generics#>>()
<#= restrictions #>
{
var world = World.GetWorld(_worldID);
if (world is null)
{
return default;
}
return new ComponentIterator<<#= generics#>>(_matchingArchetypes.AsReadOnly(), _mask, world);
}
<# } #>
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,235 @@
<#@ template language="C#" #>
<#@ output extension="gen.cs" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ include file="Helpers.ttinclude" #>
using Ghost.Core;
using Misaki.HighPerformance.LowLevel;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
using System.Runtime.CompilerServices;
namespace Ghost.Entities;
public unsafe partial struct EntityQuery
{
<# for (var i = 1; i <= Amount; i++)
{
var generics = AppendParameters(i, "T{0}");
var compGenerics = AppendParameters(i, "ref T{0} component{0}");
var deconstrictOutPrams = AppendParameters(i, "out Ref<T{0}> component{0}");
var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 2);
#>
public readonly ref struct EntityComponentIterator<<#= generics #>>
<#= restrictions #>
{
public ref struct QueryItem
{
public Entity entity;
<# for (var j = 0; j < i; j++) { #>
public ref T<#= j #> component<#= j #>;
<# } #>
internal QueryItem(Entity entity, <#= compGenerics #>)
{
this.entity = entity;
<# for (var j = 0; j < i; j++) { #>
this.component<#= j #> = ref component<#= j #>;
<# } #>
}
public void Deconstruct(out Entity entity, <#= deconstrictOutPrams #>)
{
entity = this.entity;
<# for (var j = 0; j < i; j++) { #>
component<#= j #> = new Ref<T<#= j #>>(ref this.component<#= j #>);
<# } #>
}
}
public ref struct Enumerator : IDisposable
{
private fixed int _compTypeIDs[<#= i #>];
private fixed int _offsets[<#= i #>];
private fixed long _compBasePtrs[<#= i #>];
private readonly ReadOnlyUnsafeCollection<Identifier<Archetype>> _matchingArchetypes;
private readonly EntityQueryMask _mask;
private readonly World _world;
private readonly Stack.Scope _scope;
private UnsafeList<int> _changedComponentIDs;
private ref Archetype _currentArchetype;
private ref Chunk _currentChunk;
private byte* _chunkBasePtr;
private int _currentChunkEntityCount;
private int _currentArchetypeIndex;
private int _currentChunkIndex;
private int _currentEntityIndex;
internal Enumerator(ReadOnlyUnsafeCollection<Identifier<Archetype>> matchingArchetypes, EntityQueryMask mask, World world)
{
<# for (var j = 0; j < i; j++) { #>
_compTypeIDs[<#= j #>] = ComponentTypeID<T<#= j #>>.Value;
_offsets[<#= j #>] = 0;
_compBasePtrs[<#= j #>] = 0;
<# } #>
_matchingArchetypes = matchingArchetypes;
_mask = mask;
_world = world;
_scope = AllocationManager.CreateStackScope();
_changedComponentIDs = new UnsafeList<int>(<#= i #>, _scope.AllocationHandle);
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i = 0; i < <#= i #>; i++)
{
if (id == _compTypeIDs[i])
{
_changedComponentIDs.Add(id);
break;
}
}
}
Reset();
}
public QueryItem Current => new(
*(Entity*)(_chunkBasePtr + _currentArchetype.EntityIDsOffset + _currentEntityIndex * sizeof(Entity)),
<# for (var j = 0; j < i; j++) { #>
ref *(T<#= j #>*)(_compBasePtrs[<#= j #>] + _currentEntityIndex * sizeof(T<#= j #>))<#= j < i - 1 ? "," : "" #>
<# } #>
);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetChunk(int chunkIndex)
{
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
_chunkBasePtr = _currentChunk.GetUnsafePtr();
_currentChunkEntityCount = _currentChunk._count;
for (var index = 0; index < <#= i #>; index++)
{
var layout = _currentArchetype.GetLayout(_compTypeIDs[index])
.GetValueOrThrow();
_offsets[index] = layout.offset;
_compBasePtrs[index] = (long)(_chunkBasePtr + _offsets[index]);
}
for (var i = 0; i < _changedComponentIDs.Count; i++)
{
_currentArchetype.MarkChanged(_currentChunkIndex, _changedComponentIDs[i], _world.Version);
}
}
public bool MoveNext()
{
while (true)
{
_currentEntityIndex++;
if (_currentEntityIndex < _currentChunk._count)
{
var pChunkData = _currentChunk.GetUnsafePtr();
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
{
return true;
}
continue;
}
_currentChunkIndex++;
if (!Unsafe.IsNullRef(ref _currentArchetype) && _currentChunkIndex < _currentArchetype.ChunkCount)
{
SetChunk(_currentChunkIndex);
_currentEntityIndex = -1; // Reset for new chunk
continue;
}
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
_currentEntityIndex = -1;
continue;
}
// If archetype has no chunks, loop will try next archetype
}
else
{
return false; // End of all data
}
}
}
public void Reset()
{
_currentArchetype = ref Unsafe.NullRef<Archetype>();
_currentChunk = ref Unsafe.NullRef<Chunk>();
_currentArchetypeIndex = 0;
_currentChunkIndex = 0;
_currentEntityIndex = -1;
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
}
}
}
public readonly void Dispose()
{
_scope.Dispose();
}
}
private readonly ReadOnlyUnsafeCollection<Identifier<Archetype>> _matchingArchetypes;
private readonly EntityQueryMask _mask;
private readonly World _world;
internal EntityComponentIterator(ReadOnlyUnsafeCollection<Identifier<Archetype>> matchingArchetypes, EntityQueryMask mask, World world)
{
_matchingArchetypes = matchingArchetypes;
_mask = mask;
_world = world;
}
public Enumerator GetEnumerator()
{
return new Enumerator(_matchingArchetypes, _mask, _world);
}
}
public readonly EntityComponentIterator<<#= generics#>> GetEntityComponentIterator<<#= generics#>>()
<#= restrictions #>
{
var world = World.GetWorld(_worldID);
if (world is null)
{
return default;
}
return new EntityComponentIterator<<#= generics#>>(_matchingArchetypes.AsReadOnly(), _mask, world);
}
<# } #>
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,119 @@
<#@ template language="C#" #>
<#@ output extension="gen.cs" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ include file="Helpers.ttinclude" #>
namespace Ghost.Entities;
public unsafe partial struct EntityQuery
{
<# for (var f = 0; f < 2; f++)
{
var isForEachWithEntity = f != 0;
#>
<# for (var i = 1; i <= Amount; i++)
{
var generics = AppendParameters(i, "T{0}");
var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 2);
var delegateTupe = isForEachWithEntity ? "ForEachWithEntity" : "ForEach";
#>
public readonly void ForEach<<#= generics #>>(<#= delegateTupe #><<#= generics #>> action)
<#= restrictions #>
{
var world = World.GetWorldUncheck(_worldID);
var globalVersion = world.Version;
<# for (var localIndex = 0; localIndex < i; localIndex++) { #>
var comp<#= localIndex #>TypeID = ComponentTypeID<T<#= localIndex #>>.Value;
<# } #>
var compTypeIDs = stackalloc int[]
{
<# for (var localIndex = 0; localIndex < i; localIndex++) { #>
comp<#= localIndex #>TypeID.Value,
<# } #>
};
var changedCompIDs = stackalloc int[<#= i #>];
var offsets = stackalloc int[<#= i #>];
var basePtrs = stackalloc byte*[<#= i #>];
var changedCompCount = 0;
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i =0; i < <#= i #>; i++)
{
if (id == compTypeIDs[i])
{
changedCompIDs[changedCompCount] = id;
changedCompCount++;
break;
}
}
}
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < <#= i #>; index++)
{
var layoutResult = archetype.GetLayout(compTypeIDs[index]);
if (!layoutResult)
{
hasAllComponents = false;
break;
}
offsets[index] = layoutResult.Value.offset;
}
if (!hasAllComponents)
{
continue;
}
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
{
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
var pChunkData = chunk.GetUnsafePtr();
for (var j = 0; j < changedCompCount; j++)
{
archetype.MarkChanged(chunkIndex, changedCompIDs[j], globalVersion);
}
for (var index = 0; index < <#= i #>; index++)
{
basePtrs[index] = pChunkData + offsets[index];
}
for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++)
{
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
{
continue;
}
<# for (var localIndex = 0; localIndex < i; localIndex++) { #>
var pComp<#= localIndex #> = (T<#= localIndex #>*)(basePtrs[<#= localIndex #>] + (sizeof(T<#= localIndex #>) * entityIndex));
<# } #>
<# if (isForEachWithEntity) { #>
var pEntity = (Entity*)(pChunkData + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex));
action(*pEntity, <#= AppendParameters(i, "ref *pComp{0}") #>);
<# } else { #>
action(<#= AppendParameters(i, "ref *pComp{0}") #>);
<# } #>
}
}
}
}
<# } #>
<# } #>
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,243 @@
<#@ template language="C#" #>
<#@ output extension="gen.cs" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ include file="Helpers.ttinclude" #>
using Ghost.Core;
using Misaki.HighPerformance.Jobs;
using Misaki.HighPerformance.LowLevel.Collections;
namespace Ghost.Entities;
<# for (var i = 1; i <= Amount; i++)
{
var generics = AppendGenerics(i);
var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 1);
#>
public interface IJobEntity<<#= generics #>>
<#= restrictions #>
{
void Execute(Entity entity, <#= AppendParameters(i, "ref T{0} component{0}") #>, int threadIndex);
}
internal unsafe struct JobEntityBatch<TJob, <#= generics #>> : IJobParallelFor
where TJob : unmanaged, IJobEntity<<#= generics #>>
<#= restrictions #>
{
public fixed int componentIDs[<#= i #>];
public fixed bool componentRW[<#= i #>];
public TJob userJob;
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkCount;
public UnsafeList<int> entityOffset;
<# for (var j = 0; j < i; j++){ #>
public UnsafeList<int> offsets<#= j #>;
public UnsafeList<int> bitsOffsets<#= j #>;
public UnsafeList<int> versionindices<#= j #>;
<# } #>
public int version;
public void Execute(int loopIndex, int threadIndex)
{
// 1. Get the specific pChunk for this thread
var pChunk = (byte*)chunks[loopIndex];
var pVersions = (int*)chunkVersions[loopIndex];
var count = chunkCount[loopIndex];
<# for (var j = 0; j < i; j++){ #>
var off<#= j #> = offsets<#= j #>[loopIndex];
var enableOff<#= j #> = bitsOffsets<#= j #>[loopIndex];
var versionIndex<#= j #> = versionindices<#= j #>[loopIndex];
<# } #>
var pEntity = (Entity*)(pChunk + entityOffset[loopIndex]);
<# for (var j = 0; j < i; j++){ #>
var ptr<#= j #> = (<#= "T" + j #>*)(pChunk + off<#= j #>);
<# } #>
// 2. Update versions for RW components
<# for (var j = 0; j < i; j++){ #>
if (componentRW[<#= j #>])
{
pVersions[versionIndex<#= j #>] = version;
}
<# } #>
// 3. Iterate all entities in this chunk
for (var i = 0; i < count; i++)
{
<# for (var j = 0; j < i; j++){ #>
if (enableOff<#= j #> != -1 && !EntityQuery.CheckBit(pChunk + enableOff<#= j #>, i))
{
continue;
}
<# } #>
userJob.Execute(pEntity[i], <#= AppendParameters(i, "ref ptr{0}[i]") #>, threadIndex);
}
}
}
<# } #>
public unsafe partial struct EntityQuery
{
<# for (var i = 1; i <= Amount; i++)
{
var generics = AppendGenerics(i);
var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 2);
#>
private struct DisposeJobEntity<#= i #> : IJob
{
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkEntityCounts;
public UnsafeList<int> entityOffsets;
<# for (var j = 0; j < i; j++){ #>
public UnsafeList<int> offsets<#= j #>;
public UnsafeList<int> bitsOffsets<#= j #>;
public UnsafeList<int> versionindices<#= j #>;
<# } #>
public void Execute(int threadIndex)
{
chunks.Dispose();
chunkVersions.Dispose();
chunkEntityCounts.Dispose();
entityOffsets.Dispose();
<# for (var j = 0; j < i; j++){ #>
offsets<#= j #>.Dispose();
bitsOffsets<#= j #>.Dispose();
versionindices<#= j #>.Dispose();
<# } #>
}
}
public JobHandle ScheduleEntityParallel<TJob, <#= generics #>>(TJob jobData, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntity<<#= generics #>>
<#= restrictions #>
{
var world = World.GetWorld(_worldID);
if (world is null)
{
return JobHandle.Invalid;
}
if (world.JobScheduler == null)
{
throw new InvalidOperationException("The World has no JobScheduler assigned.");
}
// 1. Flatten the World
var chunks = new UnsafeList<IntPtr>(128, JobScheduler.TempAllocatorHandle);
var chunkVersions = new UnsafeList<IntPtr>(128, JobScheduler.TempAllocatorHandle);
var chunkEntityCounts = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var entityOffsets = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
<# for (var j = 0; j < i; j++){ #>
var offsets<#= j #> = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets<#= j #> = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices<#= j #> = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
<# } #>
// Iterate the Query's matching archetypes
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
if (arch.ChunkCount == 0)
{
continue;
}
// Get offsets ONCE per archetype
<# for (var j = 0; j < i; j++){ #>
var layout<#= j #> = arch.GetLayout(ComponentTypeID<T<#= j #>>.Value)
.GetValueOrThrow();
<# } #>
// Add all chunks from this archetype
for (var i = 0; i < arch.ChunkCount; i++)
{
ref var chunkRef = ref arch.GetChunkReference(i);
chunks.Add((IntPtr)chunkRef.GetUnsafePtr());
chunkVersions.Add((IntPtr)chunkRef.GetVersionUnsafePtr());
chunkEntityCounts.Add(chunkRef._count);
entityOffsets.Add(arch.EntityIDsOffset);
<# for (var j = 0; j < i; j++){ #>
offsets<#= j #>.Add(layout<#= j #>.offset);
bitsOffsets<#= j #>.Add(layout<#= j #>.enableBitsOffset);
versionIndices<#= j #>.Add(layout<#= j #>.versionIndex);
<# } #>
}
}
// 2. Create the Runner
var runner = new JobEntityBatch<TJob, <#= generics #>>
{
userJob = jobData,
chunks = chunks,
chunkVersions = chunkVersions,
chunkCount = chunkEntityCounts,
entityOffset = entityOffsets,
<# for (var j = 0; j < i; j++){ #>
offsets<#= j #> = offsets<#= j #>,
bitsOffsets<#= j #> = bitsOffsets<#= j #>,
versionindices<#= j #> = versionIndices<#= j #>,
<# } #>
version = world.Version,
};
runner.componentIDs[0] = ComponentTypeID<T0>.Value;
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i =0; i < 1; i++)
{
if (id == runner.componentIDs[i])
{
runner.componentRW[i] = true;
break;
}
}
}
var jobHandle = world.JobScheduler.ScheduleParallel(ref runner, chunks.Count, batchSize, dependency);
// 3. Dispose the temp lists
var disposeJob = new DisposeJobEntity<#= i #>
{
chunks = chunks,
chunkVersions = chunkVersions,
chunkEntityCounts = chunkEntityCounts,
entityOffsets = entityOffsets,
<# for (var j = 0; j < i; j++){ #>
offsets<#= j #> = offsets<#= j #>,
bitsOffsets<#= j #> = bitsOffsets<#= j #>,
versionindices<#= j #> = versionIndices<#= j #>,
<# } #>
};
world.JobScheduler.Schedule(ref disposeJob, jobHandle);
return jobHandle;
}
<# } #>
}

View File

@@ -0,0 +1,36 @@
namespace Ghost.Entities;
public delegate void ForEach<T0>(ref T0 component0)
where T0 : unmanaged, IComponent;
public delegate void ForEach<T0, T1>(ref T0 component0, ref T1 component1)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent;
public delegate void ForEach<T0, T1, T2>(ref T0 component0, ref T1 component1, ref T2 component2)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent;
public delegate void ForEach<T0, T1, T2, T3>(ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent;
public delegate void ForEach<T0, T1, T2, T3, T4>(ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent where T4 : unmanaged, IComponent;
public delegate void ForEach<T0, T1, T2, T3, T4, T5>(ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4, ref T5 component5)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent where T4 : unmanaged, IComponent where T5 : unmanaged, IComponent;
public delegate void ForEach<T0, T1, T2, T3, T4, T5, T6>(ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4, ref T5 component5, ref T6 component6)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent where T4 : unmanaged, IComponent where T5 : unmanaged, IComponent where T6 : unmanaged, IComponent;
public delegate void ForEach<T0, T1, T2, T3, T4, T5, T6, T7>(ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4, ref T5 component5, ref T6 component6, ref T7 component7)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent where T4 : unmanaged, IComponent where T5 : unmanaged, IComponent where T6 : unmanaged, IComponent where T7 : unmanaged, IComponent;
public delegate void ForEachWithEntity<T0>(Entity entity, ref T0 component0)
where T0 : unmanaged, IComponent;
public delegate void ForEachWithEntity<T0, T1>(Entity entity, ref T0 component0, ref T1 component1)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent;
public delegate void ForEachWithEntity<T0, T1, T2>(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent;
public delegate void ForEachWithEntity<T0, T1, T2, T3>(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent;
public delegate void ForEachWithEntity<T0, T1, T2, T3, T4>(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent where T4 : unmanaged, IComponent;
public delegate void ForEachWithEntity<T0, T1, T2, T3, T4, T5>(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4, ref T5 component5)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent where T4 : unmanaged, IComponent where T5 : unmanaged, IComponent;
public delegate void ForEachWithEntity<T0, T1, T2, T3, T4, T5, T6>(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4, ref T5 component5, ref T6 component6)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent where T4 : unmanaged, IComponent where T5 : unmanaged, IComponent where T6 : unmanaged, IComponent;
public delegate void ForEachWithEntity<T0, T1, T2, T3, T4, T5, T6, T7>(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4, ref T5 component5, ref T6 component6, ref T7 component7)
where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent where T4 : unmanaged, IComponent where T5 : unmanaged, IComponent where T6 : unmanaged, IComponent where T7 : unmanaged, IComponent;

View File

@@ -0,0 +1,27 @@
<#@ template language="C#" #>
<#@ output extension="gen.cs" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ include file="Helpers.ttinclude" #>
namespace Ghost.Entities;
<# for (var i = 1; i <= Amount; i++)
{
var generics = AppendParameters(i, "T{0}");
var compGenerics = AppendParameters(i, "ref T{0} component{0}");
var restrictions = AppendGenericRestrictions(i, "unmanaged, IComponent");
#>
public delegate void ForEach<<#= generics #>>(<#= compGenerics #>)
<#= restrictions #>;
<# } #>
<# for (var i = 1; i <= Amount; i++)
{
var generics = AppendParameters(i, "T{0}");
var compGenerics = AppendParameters(i, "ref T{0} component{0}");
var restrictions = AppendGenericRestrictions(i, "unmanaged, IComponent");
#>
public delegate void ForEachWithEntity<<#= generics #>>(Entity entity, <#= compGenerics #>)
<#= restrictions #>;
<# } #>

View File

@@ -0,0 +1,147 @@
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#+
public int Amount = 8;
public int ExtensionAmount = 3;
public string Indent(StringBuilder sb, int spaces)
{
var indent = new string(' ', spaces);
return sb.ToString().Replace("\n", "\n" + indent);
}
string AppendGenerics(int amount, string template)
{
var sb = new StringBuilder();
for (var i = 0; i < amount; i++)
{
if (i > 0) sb.Append(", ");
sb.Append(string.Format(template, i));
}
return sb.ToString();
}
string AppendGenerics(int amount)
{
return AppendGenerics(amount, "T{0}");
}
public StringBuilder AppendParameters(int amount, string template)
{
var sb = new StringBuilder();
for (var localIndex = 0; localIndex < amount; localIndex++)
{
sb.Append(string.Format(template, localIndex));
if (localIndex < amount - 1)
{
sb.Append(", ");
}
}
return sb;
}
public StringBuilder AppendGenericRestrictions(int amount, string Ttemplate, string template)
{
var sb = new StringBuilder();
for (var localIndex = 0; localIndex < amount; localIndex++)
{
sb.Append($"where {Ttemplate}{localIndex} : {template}");
if (localIndex < amount - 1)
{
sb.Append(' ');
}
}
return sb;
}
public StringBuilder AppendGenericRestrictions(int amount, string template)
{
return AppendGenericRestrictions(amount, "T", template);
}
public StringBuilder AppendGenericRestrictionsMultiline(int amount, string Ttemplate, string template, int indentation)
{
var sb = new StringBuilder();
var spaces = new string(' ', indentation * 4);
for (var localIndex = 0; localIndex < amount; localIndex++)
{
sb.Append($"{spaces}where {Ttemplate}{localIndex} : {template}");
if (localIndex < amount - 1)
{
sb.AppendLine();
}
}
return sb;
}
public StringBuilder AppendGenericRestrictionsMultiline(int amount, string template, int indentation)
{
return AppendGenericRestrictionsMultiline(amount, "T", template, indentation);
}
public StringBuilder TryGetComponentPools(int amount)
{
var sb = new StringBuilder();
for (var localIndex = 0; localIndex < amount; localIndex++)
{
sb.Append($"_componentStorage.TryGetPool<T{localIndex}>(out var pool{localIndex})");
if (localIndex < amount - 1)
{
sb.Append(" && ");
}
}
return sb;
}
public StringBuilder HasEntity(int amount)
{
var sb = new StringBuilder();
for (var localIndex = 1; localIndex < amount; localIndex++)
{
sb.Append($"pool{localIndex}.Has(entity)");
if (localIndex < amount - 1)
{
sb.Append(" && ");
}
}
return sb;
}
public StringBuilder GetComponent(int amount)
{
var sb = new StringBuilder();
for (var localIndex = 0; localIndex < amount; localIndex++)
{
sb.Append($"pool{localIndex}.GetRef(entity)");
if (localIndex < amount - 1)
{
sb.Append(", ");
}
}
return sb;
}
public StringBuilder GetComponentRef(int amount)
{
var sb = new StringBuilder();
for (var localIndex = 0; localIndex < amount; localIndex++)
{
sb.Append($"ref pool{localIndex}.GetRef(entity)");
if (localIndex < amount - 1)
{
sb.Append(", ");
}
}
return sb;
}
#>

View File

@@ -0,0 +1,380 @@
using System.Runtime.CompilerServices;
namespace Ghost.Entities;
public ref partial struct QueryBuilder
{
/// <summary>
/// Adds the specified component type(s) to the 'All' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAll<T0>()
where T0 : unmanaged, IComponent
{
_all.Add(ComponentTypeID<T0>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'All' filter of the query and requires read-write access.
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAllRW<T0>()
where T0 : unmanaged, IComponent
{
_all.Add(ComponentTypeID<T0>.Value);
_rw.Add(ComponentTypeID<T0>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Any' filter of the query.
/// Targets entities that have at least one of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAny<T0>()
where T0 : unmanaged, IComponent
{
_any.Add(ComponentTypeID<T0>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Absent' filter of the query.
/// Targets entities that do not have any of the specified component types.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAbsent<T0>()
where T0 : unmanaged, IComponent
{
_absent.Add(ComponentTypeID<T0>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'None' filter of the query.
/// Targets entities that do not have any of the specified component types, or those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithNone<T0>()
where T0 : unmanaged, IComponent
{
_none.Add(ComponentTypeID<T0>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Disabled' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithDisabled<T0>()
where T0 : unmanaged, IEnableableComponent
{
_disabled.Add(ComponentTypeID<T0>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Present' filter of the query.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithPresent<T0>()
where T0 : unmanaged, IComponent
{
_present.Add(ComponentTypeID<T0>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Present' filter of the query and requires read-write access.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithPresentRW<T0>()
where T0 : unmanaged, IComponent
{
_present.Add(ComponentTypeID<T0>.Value);
_rw.Add(ComponentTypeID<T0>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'All' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAll<T0, T1>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
_all.Add(ComponentTypeID<T0>.Value);
_all.Add(ComponentTypeID<T1>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'All' filter of the query and requires read-write access.
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAllRW<T0, T1>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
_all.Add(ComponentTypeID<T0>.Value);
_rw.Add(ComponentTypeID<T0>.Value);
_all.Add(ComponentTypeID<T1>.Value);
_rw.Add(ComponentTypeID<T1>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Any' filter of the query.
/// Targets entities that have at least one of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAny<T0, T1>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
_any.Add(ComponentTypeID<T0>.Value);
_any.Add(ComponentTypeID<T1>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Absent' filter of the query.
/// Targets entities that do not have any of the specified component types.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAbsent<T0, T1>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
_absent.Add(ComponentTypeID<T0>.Value);
_absent.Add(ComponentTypeID<T1>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'None' filter of the query.
/// Targets entities that do not have any of the specified component types, or those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithNone<T0, T1>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
_none.Add(ComponentTypeID<T0>.Value);
_none.Add(ComponentTypeID<T1>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Disabled' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithDisabled<T0, T1>()
where T0 : unmanaged, IEnableableComponent
where T1 : unmanaged, IEnableableComponent
{
_disabled.Add(ComponentTypeID<T0>.Value);
_disabled.Add(ComponentTypeID<T1>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Present' filter of the query.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithPresent<T0, T1>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
_present.Add(ComponentTypeID<T0>.Value);
_present.Add(ComponentTypeID<T1>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Present' filter of the query and requires read-write access.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithPresentRW<T0, T1>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
_present.Add(ComponentTypeID<T0>.Value);
_rw.Add(ComponentTypeID<T0>.Value);
_present.Add(ComponentTypeID<T1>.Value);
_rw.Add(ComponentTypeID<T1>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'All' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAll<T0, T1, T2>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
{
_all.Add(ComponentTypeID<T0>.Value);
_all.Add(ComponentTypeID<T1>.Value);
_all.Add(ComponentTypeID<T2>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'All' filter of the query and requires read-write access.
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAllRW<T0, T1, T2>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
{
_all.Add(ComponentTypeID<T0>.Value);
_rw.Add(ComponentTypeID<T0>.Value);
_all.Add(ComponentTypeID<T1>.Value);
_rw.Add(ComponentTypeID<T1>.Value);
_all.Add(ComponentTypeID<T2>.Value);
_rw.Add(ComponentTypeID<T2>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Any' filter of the query.
/// Targets entities that have at least one of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAny<T0, T1, T2>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
{
_any.Add(ComponentTypeID<T0>.Value);
_any.Add(ComponentTypeID<T1>.Value);
_any.Add(ComponentTypeID<T2>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Absent' filter of the query.
/// Targets entities that do not have any of the specified component types.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAbsent<T0, T1, T2>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
{
_absent.Add(ComponentTypeID<T0>.Value);
_absent.Add(ComponentTypeID<T1>.Value);
_absent.Add(ComponentTypeID<T2>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'None' filter of the query.
/// Targets entities that do not have any of the specified component types, or those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithNone<T0, T1, T2>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
{
_none.Add(ComponentTypeID<T0>.Value);
_none.Add(ComponentTypeID<T1>.Value);
_none.Add(ComponentTypeID<T2>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Disabled' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithDisabled<T0, T1, T2>()
where T0 : unmanaged, IEnableableComponent
where T1 : unmanaged, IEnableableComponent
where T2 : unmanaged, IEnableableComponent
{
_disabled.Add(ComponentTypeID<T0>.Value);
_disabled.Add(ComponentTypeID<T1>.Value);
_disabled.Add(ComponentTypeID<T2>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Present' filter of the query.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithPresent<T0, T1, T2>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
{
_present.Add(ComponentTypeID<T0>.Value);
_present.Add(ComponentTypeID<T1>.Value);
_present.Add(ComponentTypeID<T2>.Value);
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Present' filter of the query and requires read-write access.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithPresentRW<T0, T1, T2>()
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
{
_present.Add(ComponentTypeID<T0>.Value);
_rw.Add(ComponentTypeID<T0>.Value);
_present.Add(ComponentTypeID<T1>.Value);
_rw.Add(ComponentTypeID<T1>.Value);
_present.Add(ComponentTypeID<T2>.Value);
_rw.Add(ComponentTypeID<T2>.Value);
return this;
}
}

View File

@@ -0,0 +1,142 @@
<#@ template language="C#" #>
<#@ output extension="gen.cs" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ include file="Helpers.ttinclude" #>
using System.Runtime.CompilerServices;
namespace Ghost.Entities;
public ref partial struct QueryBuilder
{
<# for (var i = 1; i <= 3; i++)
{
var generics = AppendGenerics(i);
var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 2);
var enableRestrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IEnableableComponent", 2);
#>
/// <summary>
/// Adds the specified component type(s) to the 'All' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAll<<#= generics #>>()
<#= restrictions #>
{
<# for (var j = 0; j < i; j++) { #>
_all.Add(ComponentTypeID<T<#= j #>>.Value);
<# } #>
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'All' filter of the query and requires read-write access.
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAllRW<<#= generics #>>()
<#= restrictions #>
{
<# for (var j = 0; j < i; j++) { #>
_all.Add(ComponentTypeID<T<#= j #>>.Value);
_rw.Add(ComponentTypeID<T<#= j #>>.Value);
<# } #>
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Any' filter of the query.
/// Targets entities that have at least one of the specified component types and those component(s) must be enabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAny<<#= generics #>>()
<#= restrictions #>
{
<# for (var j = 0; j < i; j++) { #>
_any.Add(ComponentTypeID<T<#= j #>>.Value);
<# } #>
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Absent' filter of the query.
/// Targets entities that do not have any of the specified component types.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithAbsent<<#= generics #>>()
<#= restrictions #>
{
<# for (var j = 0; j < i; j++) { #>
_absent.Add(ComponentTypeID<T<#= j #>>.Value);
<# } #>
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'None' filter of the query.
/// Targets entities that do not have any of the specified component types, or those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithNone<<#= generics #>>()
<#= restrictions #>
{
<# for (var j = 0; j < i; j++) { #>
_none.Add(ComponentTypeID<T<#= j #>>.Value);
<# } #>
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Disabled' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithDisabled<<#= generics #>>()
<#= enableRestrictions #>
{
<# for (var j = 0; j < i; j++) { #>
_disabled.Add(ComponentTypeID<T<#= j #>>.Value);
<# } #>
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Present' filter of the query.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithPresent<<#= generics #>>()
<#= restrictions #>
{
<# for (var j = 0; j < i; j++) { #>
_present.Add(ComponentTypeID<T<#= j #>>.Value);
<# } #>
return this;
}
/// <summary>
/// Adds the specified component type(s) to the 'Present' filter of the query and requires read-write access.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public QueryBuilder WithPresentRW<<#= generics #>>()
<#= restrictions #>
{
<# for (var j = 0; j < i; j++) { #>
_present.Add(ComponentTypeID<T<#= j #>>.Value);
_rw.Add(ComponentTypeID<T<#= j #>>.Value);
<# } #>
return this;
}
<# } #>
}