Files
GhostEngine/Ghost.Entities/Templates/EntityQuery.JobEntity.gen.cs
Misaki 92b966fe0d Render graph integration and resource management refactor
Introduces a full-featured render graph system with pass culling, resource aliasing, and automatic barrier generation. Refactors resource and barrier APIs, improves error handling, and unifies result types. Renderer and render passes now use the new graph-based workflow. Updates shader includes, adds a blit shader, and improves HLSL parsing. Removes dynamic descriptor heaps in favor of persistent ones. Project file now includes the render graph module. Lays the foundation for advanced rendering features and improved memory efficiency.
2026-01-21 18:32:03 +09:00

2890 lines
95 KiB
C#

using Ghost.Core;
using Misaki.HighPerformance.Jobs;
using Misaki.HighPerformance.LowLevel.Collections;
namespace Ghost.Entities;
public interface IJobEntity<T0>
where T0 : unmanaged, IComponent
{
void Execute(Entity entity, ref T0 component0, int threadIndex);
}
internal unsafe struct JobEntityBatch<TJob, T0> : IJobParallelFor
where TJob : unmanaged, IJobEntity<T0>
where T0 : unmanaged, IComponent
{
public fixed int componentIDs[1];
public fixed bool componentRW[1];
public TJob userJob;
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkCount;
public UnsafeList<int> entityOffset;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
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];
var off0 = offsets0[loopIndex];
var enableOff0 = bitsOffsets0[loopIndex];
var versionIndex0 = versionindices0[loopIndex];
var pEntity = (Entity*)(pChunk + entityOffset[loopIndex]);
var ptr0 = (T0*)(pChunk + off0);
// 2. Update versions for RW components
if (componentRW[0])
{
pVersions[versionIndex0] = version;
}
// 3. Iterate all entities in this chunk
for (var i = 0; i < count; i++)
{
if (enableOff0 != -1 && !EntityQuery.CheckBit(pChunk + enableOff0, i))
{
continue;
}
userJob.Execute(pEntity[i], ref ptr0[i], threadIndex);
}
}
}
public interface IJobEntity<T0, T1>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
void Execute(Entity entity, ref T0 component0, ref T1 component1, int threadIndex);
}
internal unsafe struct JobEntityBatch<TJob, T0, T1> : IJobParallelFor
where TJob : unmanaged, IJobEntity<T0, T1>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
public fixed int componentIDs[2];
public fixed bool componentRW[2];
public TJob userJob;
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkCount;
public UnsafeList<int> entityOffset;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
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];
var off0 = offsets0[loopIndex];
var enableOff0 = bitsOffsets0[loopIndex];
var versionIndex0 = versionindices0[loopIndex];
var off1 = offsets1[loopIndex];
var enableOff1 = bitsOffsets1[loopIndex];
var versionIndex1 = versionindices1[loopIndex];
var pEntity = (Entity*)(pChunk + entityOffset[loopIndex]);
var ptr0 = (T0*)(pChunk + off0);
var ptr1 = (T1*)(pChunk + off1);
// 2. Update versions for RW components
if (componentRW[0])
{
pVersions[versionIndex0] = version;
}
if (componentRW[1])
{
pVersions[versionIndex1] = version;
}
// 3. Iterate all entities in this chunk
for (var i = 0; i < count; i++)
{
if (enableOff0 != -1 && !EntityQuery.CheckBit(pChunk + enableOff0, i))
{
continue;
}
if (enableOff1 != -1 && !EntityQuery.CheckBit(pChunk + enableOff1, i))
{
continue;
}
userJob.Execute(pEntity[i], ref ptr0[i], ref ptr1[i], threadIndex);
}
}
}
public interface IJobEntity<T0, T1, T2>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
{
void Execute(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2, int threadIndex);
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2> : IJobParallelFor
where TJob : unmanaged, IJobEntity<T0, T1, T2>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
{
public fixed int componentIDs[3];
public fixed bool componentRW[3];
public TJob userJob;
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkCount;
public UnsafeList<int> entityOffset;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
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];
var off0 = offsets0[loopIndex];
var enableOff0 = bitsOffsets0[loopIndex];
var versionIndex0 = versionindices0[loopIndex];
var off1 = offsets1[loopIndex];
var enableOff1 = bitsOffsets1[loopIndex];
var versionIndex1 = versionindices1[loopIndex];
var off2 = offsets2[loopIndex];
var enableOff2 = bitsOffsets2[loopIndex];
var versionIndex2 = versionindices2[loopIndex];
var pEntity = (Entity*)(pChunk + entityOffset[loopIndex]);
var ptr0 = (T0*)(pChunk + off0);
var ptr1 = (T1*)(pChunk + off1);
var ptr2 = (T2*)(pChunk + off2);
// 2. Update versions for RW components
if (componentRW[0])
{
pVersions[versionIndex0] = version;
}
if (componentRW[1])
{
pVersions[versionIndex1] = version;
}
if (componentRW[2])
{
pVersions[versionIndex2] = version;
}
// 3. Iterate all entities in this chunk
for (var i = 0; i < count; i++)
{
if (enableOff0 != -1 && !EntityQuery.CheckBit(pChunk + enableOff0, i))
{
continue;
}
if (enableOff1 != -1 && !EntityQuery.CheckBit(pChunk + enableOff1, i))
{
continue;
}
if (enableOff2 != -1 && !EntityQuery.CheckBit(pChunk + enableOff2, i))
{
continue;
}
userJob.Execute(pEntity[i], ref ptr0[i], ref ptr1[i], ref ptr2[i], threadIndex);
}
}
}
public interface IJobEntity<T0, T1, T2, T3>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
where T3 : unmanaged, IComponent
{
void Execute(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, int threadIndex);
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3> : IJobParallelFor
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
where T3 : unmanaged, IComponent
{
public fixed int componentIDs[4];
public fixed bool componentRW[4];
public TJob userJob;
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkCount;
public UnsafeList<int> entityOffset;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public UnsafeList<int> offsets3;
public UnsafeList<int> bitsOffsets3;
public UnsafeList<int> versionindices3;
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];
var off0 = offsets0[loopIndex];
var enableOff0 = bitsOffsets0[loopIndex];
var versionIndex0 = versionindices0[loopIndex];
var off1 = offsets1[loopIndex];
var enableOff1 = bitsOffsets1[loopIndex];
var versionIndex1 = versionindices1[loopIndex];
var off2 = offsets2[loopIndex];
var enableOff2 = bitsOffsets2[loopIndex];
var versionIndex2 = versionindices2[loopIndex];
var off3 = offsets3[loopIndex];
var enableOff3 = bitsOffsets3[loopIndex];
var versionIndex3 = versionindices3[loopIndex];
var pEntity = (Entity*)(pChunk + entityOffset[loopIndex]);
var ptr0 = (T0*)(pChunk + off0);
var ptr1 = (T1*)(pChunk + off1);
var ptr2 = (T2*)(pChunk + off2);
var ptr3 = (T3*)(pChunk + off3);
// 2. Update versions for RW components
if (componentRW[0])
{
pVersions[versionIndex0] = version;
}
if (componentRW[1])
{
pVersions[versionIndex1] = version;
}
if (componentRW[2])
{
pVersions[versionIndex2] = version;
}
if (componentRW[3])
{
pVersions[versionIndex3] = version;
}
// 3. Iterate all entities in this chunk
for (var i = 0; i < count; i++)
{
if (enableOff0 != -1 && !EntityQuery.CheckBit(pChunk + enableOff0, i))
{
continue;
}
if (enableOff1 != -1 && !EntityQuery.CheckBit(pChunk + enableOff1, i))
{
continue;
}
if (enableOff2 != -1 && !EntityQuery.CheckBit(pChunk + enableOff2, i))
{
continue;
}
if (enableOff3 != -1 && !EntityQuery.CheckBit(pChunk + enableOff3, i))
{
continue;
}
userJob.Execute(pEntity[i], ref ptr0[i], ref ptr1[i], ref ptr2[i], ref ptr3[i], threadIndex);
}
}
}
public interface IJobEntity<T0, T1, T2, T3, T4>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
where T3 : unmanaged, IComponent
where T4 : unmanaged, IComponent
{
void Execute(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4, int threadIndex);
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4> : IJobParallelFor
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
where T3 : unmanaged, IComponent
where T4 : unmanaged, IComponent
{
public fixed int componentIDs[5];
public fixed bool componentRW[5];
public TJob userJob;
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkCount;
public UnsafeList<int> entityOffset;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public UnsafeList<int> offsets3;
public UnsafeList<int> bitsOffsets3;
public UnsafeList<int> versionindices3;
public UnsafeList<int> offsets4;
public UnsafeList<int> bitsOffsets4;
public UnsafeList<int> versionindices4;
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];
var off0 = offsets0[loopIndex];
var enableOff0 = bitsOffsets0[loopIndex];
var versionIndex0 = versionindices0[loopIndex];
var off1 = offsets1[loopIndex];
var enableOff1 = bitsOffsets1[loopIndex];
var versionIndex1 = versionindices1[loopIndex];
var off2 = offsets2[loopIndex];
var enableOff2 = bitsOffsets2[loopIndex];
var versionIndex2 = versionindices2[loopIndex];
var off3 = offsets3[loopIndex];
var enableOff3 = bitsOffsets3[loopIndex];
var versionIndex3 = versionindices3[loopIndex];
var off4 = offsets4[loopIndex];
var enableOff4 = bitsOffsets4[loopIndex];
var versionIndex4 = versionindices4[loopIndex];
var pEntity = (Entity*)(pChunk + entityOffset[loopIndex]);
var ptr0 = (T0*)(pChunk + off0);
var ptr1 = (T1*)(pChunk + off1);
var ptr2 = (T2*)(pChunk + off2);
var ptr3 = (T3*)(pChunk + off3);
var ptr4 = (T4*)(pChunk + off4);
// 2. Update versions for RW components
if (componentRW[0])
{
pVersions[versionIndex0] = version;
}
if (componentRW[1])
{
pVersions[versionIndex1] = version;
}
if (componentRW[2])
{
pVersions[versionIndex2] = version;
}
if (componentRW[3])
{
pVersions[versionIndex3] = version;
}
if (componentRW[4])
{
pVersions[versionIndex4] = version;
}
// 3. Iterate all entities in this chunk
for (var i = 0; i < count; i++)
{
if (enableOff0 != -1 && !EntityQuery.CheckBit(pChunk + enableOff0, i))
{
continue;
}
if (enableOff1 != -1 && !EntityQuery.CheckBit(pChunk + enableOff1, i))
{
continue;
}
if (enableOff2 != -1 && !EntityQuery.CheckBit(pChunk + enableOff2, i))
{
continue;
}
if (enableOff3 != -1 && !EntityQuery.CheckBit(pChunk + enableOff3, i))
{
continue;
}
if (enableOff4 != -1 && !EntityQuery.CheckBit(pChunk + enableOff4, i))
{
continue;
}
userJob.Execute(pEntity[i], ref ptr0[i], ref ptr1[i], ref ptr2[i], ref ptr3[i], ref ptr4[i], threadIndex);
}
}
}
public interface IJobEntity<T0, T1, T2, T3, T4, T5>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
where T3 : unmanaged, IComponent
where T4 : unmanaged, IComponent
where T5 : unmanaged, IComponent
{
void Execute(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4, ref T5 component5, int threadIndex);
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5> : IJobParallelFor
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5>
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 fixed int componentIDs[6];
public fixed bool componentRW[6];
public TJob userJob;
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkCount;
public UnsafeList<int> entityOffset;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public UnsafeList<int> offsets3;
public UnsafeList<int> bitsOffsets3;
public UnsafeList<int> versionindices3;
public UnsafeList<int> offsets4;
public UnsafeList<int> bitsOffsets4;
public UnsafeList<int> versionindices4;
public UnsafeList<int> offsets5;
public UnsafeList<int> bitsOffsets5;
public UnsafeList<int> versionindices5;
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];
var off0 = offsets0[loopIndex];
var enableOff0 = bitsOffsets0[loopIndex];
var versionIndex0 = versionindices0[loopIndex];
var off1 = offsets1[loopIndex];
var enableOff1 = bitsOffsets1[loopIndex];
var versionIndex1 = versionindices1[loopIndex];
var off2 = offsets2[loopIndex];
var enableOff2 = bitsOffsets2[loopIndex];
var versionIndex2 = versionindices2[loopIndex];
var off3 = offsets3[loopIndex];
var enableOff3 = bitsOffsets3[loopIndex];
var versionIndex3 = versionindices3[loopIndex];
var off4 = offsets4[loopIndex];
var enableOff4 = bitsOffsets4[loopIndex];
var versionIndex4 = versionindices4[loopIndex];
var off5 = offsets5[loopIndex];
var enableOff5 = bitsOffsets5[loopIndex];
var versionIndex5 = versionindices5[loopIndex];
var pEntity = (Entity*)(pChunk + entityOffset[loopIndex]);
var ptr0 = (T0*)(pChunk + off0);
var ptr1 = (T1*)(pChunk + off1);
var ptr2 = (T2*)(pChunk + off2);
var ptr3 = (T3*)(pChunk + off3);
var ptr4 = (T4*)(pChunk + off4);
var ptr5 = (T5*)(pChunk + off5);
// 2. Update versions for RW components
if (componentRW[0])
{
pVersions[versionIndex0] = version;
}
if (componentRW[1])
{
pVersions[versionIndex1] = version;
}
if (componentRW[2])
{
pVersions[versionIndex2] = version;
}
if (componentRW[3])
{
pVersions[versionIndex3] = version;
}
if (componentRW[4])
{
pVersions[versionIndex4] = version;
}
if (componentRW[5])
{
pVersions[versionIndex5] = version;
}
// 3. Iterate all entities in this chunk
for (var i = 0; i < count; i++)
{
if (enableOff0 != -1 && !EntityQuery.CheckBit(pChunk + enableOff0, i))
{
continue;
}
if (enableOff1 != -1 && !EntityQuery.CheckBit(pChunk + enableOff1, i))
{
continue;
}
if (enableOff2 != -1 && !EntityQuery.CheckBit(pChunk + enableOff2, i))
{
continue;
}
if (enableOff3 != -1 && !EntityQuery.CheckBit(pChunk + enableOff3, i))
{
continue;
}
if (enableOff4 != -1 && !EntityQuery.CheckBit(pChunk + enableOff4, i))
{
continue;
}
if (enableOff5 != -1 && !EntityQuery.CheckBit(pChunk + enableOff5, i))
{
continue;
}
userJob.Execute(pEntity[i], ref ptr0[i], ref ptr1[i], ref ptr2[i], ref ptr3[i], ref ptr4[i], ref ptr5[i], threadIndex);
}
}
}
public interface IJobEntity<T0, T1, T2, T3, T4, T5, T6>
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
{
void Execute(Entity entity, ref T0 component0, ref T1 component1, ref T2 component2, ref T3 component3, ref T4 component4, ref T5 component5, ref T6 component6, int threadIndex);
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5, T6> : IJobParallelFor
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5, T6>
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 fixed int componentIDs[7];
public fixed bool componentRW[7];
public TJob userJob;
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkCount;
public UnsafeList<int> entityOffset;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public UnsafeList<int> offsets3;
public UnsafeList<int> bitsOffsets3;
public UnsafeList<int> versionindices3;
public UnsafeList<int> offsets4;
public UnsafeList<int> bitsOffsets4;
public UnsafeList<int> versionindices4;
public UnsafeList<int> offsets5;
public UnsafeList<int> bitsOffsets5;
public UnsafeList<int> versionindices5;
public UnsafeList<int> offsets6;
public UnsafeList<int> bitsOffsets6;
public UnsafeList<int> versionindices6;
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];
var off0 = offsets0[loopIndex];
var enableOff0 = bitsOffsets0[loopIndex];
var versionIndex0 = versionindices0[loopIndex];
var off1 = offsets1[loopIndex];
var enableOff1 = bitsOffsets1[loopIndex];
var versionIndex1 = versionindices1[loopIndex];
var off2 = offsets2[loopIndex];
var enableOff2 = bitsOffsets2[loopIndex];
var versionIndex2 = versionindices2[loopIndex];
var off3 = offsets3[loopIndex];
var enableOff3 = bitsOffsets3[loopIndex];
var versionIndex3 = versionindices3[loopIndex];
var off4 = offsets4[loopIndex];
var enableOff4 = bitsOffsets4[loopIndex];
var versionIndex4 = versionindices4[loopIndex];
var off5 = offsets5[loopIndex];
var enableOff5 = bitsOffsets5[loopIndex];
var versionIndex5 = versionindices5[loopIndex];
var off6 = offsets6[loopIndex];
var enableOff6 = bitsOffsets6[loopIndex];
var versionIndex6 = versionindices6[loopIndex];
var pEntity = (Entity*)(pChunk + entityOffset[loopIndex]);
var ptr0 = (T0*)(pChunk + off0);
var ptr1 = (T1*)(pChunk + off1);
var ptr2 = (T2*)(pChunk + off2);
var ptr3 = (T3*)(pChunk + off3);
var ptr4 = (T4*)(pChunk + off4);
var ptr5 = (T5*)(pChunk + off5);
var ptr6 = (T6*)(pChunk + off6);
// 2. Update versions for RW components
if (componentRW[0])
{
pVersions[versionIndex0] = version;
}
if (componentRW[1])
{
pVersions[versionIndex1] = version;
}
if (componentRW[2])
{
pVersions[versionIndex2] = version;
}
if (componentRW[3])
{
pVersions[versionIndex3] = version;
}
if (componentRW[4])
{
pVersions[versionIndex4] = version;
}
if (componentRW[5])
{
pVersions[versionIndex5] = version;
}
if (componentRW[6])
{
pVersions[versionIndex6] = version;
}
// 3. Iterate all entities in this chunk
for (var i = 0; i < count; i++)
{
if (enableOff0 != -1 && !EntityQuery.CheckBit(pChunk + enableOff0, i))
{
continue;
}
if (enableOff1 != -1 && !EntityQuery.CheckBit(pChunk + enableOff1, i))
{
continue;
}
if (enableOff2 != -1 && !EntityQuery.CheckBit(pChunk + enableOff2, i))
{
continue;
}
if (enableOff3 != -1 && !EntityQuery.CheckBit(pChunk + enableOff3, i))
{
continue;
}
if (enableOff4 != -1 && !EntityQuery.CheckBit(pChunk + enableOff4, i))
{
continue;
}
if (enableOff5 != -1 && !EntityQuery.CheckBit(pChunk + enableOff5, i))
{
continue;
}
if (enableOff6 != -1 && !EntityQuery.CheckBit(pChunk + enableOff6, i))
{
continue;
}
userJob.Execute(pEntity[i], ref ptr0[i], ref ptr1[i], ref ptr2[i], ref ptr3[i], ref ptr4[i], ref ptr5[i], ref ptr6[i], threadIndex);
}
}
}
public interface IJobEntity<T0, T1, T2, T3, T4, T5, T6, T7>
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
{
void Execute(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, int threadIndex);
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5, T6, T7> : IJobParallelFor
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5, T6, T7>
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 fixed int componentIDs[8];
public fixed bool componentRW[8];
public TJob userJob;
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkCount;
public UnsafeList<int> entityOffset;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public UnsafeList<int> offsets3;
public UnsafeList<int> bitsOffsets3;
public UnsafeList<int> versionindices3;
public UnsafeList<int> offsets4;
public UnsafeList<int> bitsOffsets4;
public UnsafeList<int> versionindices4;
public UnsafeList<int> offsets5;
public UnsafeList<int> bitsOffsets5;
public UnsafeList<int> versionindices5;
public UnsafeList<int> offsets6;
public UnsafeList<int> bitsOffsets6;
public UnsafeList<int> versionindices6;
public UnsafeList<int> offsets7;
public UnsafeList<int> bitsOffsets7;
public UnsafeList<int> versionindices7;
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];
var off0 = offsets0[loopIndex];
var enableOff0 = bitsOffsets0[loopIndex];
var versionIndex0 = versionindices0[loopIndex];
var off1 = offsets1[loopIndex];
var enableOff1 = bitsOffsets1[loopIndex];
var versionIndex1 = versionindices1[loopIndex];
var off2 = offsets2[loopIndex];
var enableOff2 = bitsOffsets2[loopIndex];
var versionIndex2 = versionindices2[loopIndex];
var off3 = offsets3[loopIndex];
var enableOff3 = bitsOffsets3[loopIndex];
var versionIndex3 = versionindices3[loopIndex];
var off4 = offsets4[loopIndex];
var enableOff4 = bitsOffsets4[loopIndex];
var versionIndex4 = versionindices4[loopIndex];
var off5 = offsets5[loopIndex];
var enableOff5 = bitsOffsets5[loopIndex];
var versionIndex5 = versionindices5[loopIndex];
var off6 = offsets6[loopIndex];
var enableOff6 = bitsOffsets6[loopIndex];
var versionIndex6 = versionindices6[loopIndex];
var off7 = offsets7[loopIndex];
var enableOff7 = bitsOffsets7[loopIndex];
var versionIndex7 = versionindices7[loopIndex];
var pEntity = (Entity*)(pChunk + entityOffset[loopIndex]);
var ptr0 = (T0*)(pChunk + off0);
var ptr1 = (T1*)(pChunk + off1);
var ptr2 = (T2*)(pChunk + off2);
var ptr3 = (T3*)(pChunk + off3);
var ptr4 = (T4*)(pChunk + off4);
var ptr5 = (T5*)(pChunk + off5);
var ptr6 = (T6*)(pChunk + off6);
var ptr7 = (T7*)(pChunk + off7);
// 2. Update versions for RW components
if (componentRW[0])
{
pVersions[versionIndex0] = version;
}
if (componentRW[1])
{
pVersions[versionIndex1] = version;
}
if (componentRW[2])
{
pVersions[versionIndex2] = version;
}
if (componentRW[3])
{
pVersions[versionIndex3] = version;
}
if (componentRW[4])
{
pVersions[versionIndex4] = version;
}
if (componentRW[5])
{
pVersions[versionIndex5] = version;
}
if (componentRW[6])
{
pVersions[versionIndex6] = version;
}
if (componentRW[7])
{
pVersions[versionIndex7] = version;
}
// 3. Iterate all entities in this chunk
for (var i = 0; i < count; i++)
{
if (enableOff0 != -1 && !EntityQuery.CheckBit(pChunk + enableOff0, i))
{
continue;
}
if (enableOff1 != -1 && !EntityQuery.CheckBit(pChunk + enableOff1, i))
{
continue;
}
if (enableOff2 != -1 && !EntityQuery.CheckBit(pChunk + enableOff2, i))
{
continue;
}
if (enableOff3 != -1 && !EntityQuery.CheckBit(pChunk + enableOff3, i))
{
continue;
}
if (enableOff4 != -1 && !EntityQuery.CheckBit(pChunk + enableOff4, i))
{
continue;
}
if (enableOff5 != -1 && !EntityQuery.CheckBit(pChunk + enableOff5, i))
{
continue;
}
if (enableOff6 != -1 && !EntityQuery.CheckBit(pChunk + enableOff6, i))
{
continue;
}
if (enableOff7 != -1 && !EntityQuery.CheckBit(pChunk + enableOff7, i))
{
continue;
}
userJob.Execute(pEntity[i], ref ptr0[i], ref ptr1[i], ref ptr2[i], ref ptr3[i], ref ptr4[i], ref ptr5[i], ref ptr6[i], ref ptr7[i], threadIndex);
}
}
}
public unsafe partial struct EntityQuery
{
private struct DisposeJobEntity1 : IJob
{
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkEntityCounts;
public UnsafeList<int> entityOffsets;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public void Execute(int threadIndex)
{
chunks.Dispose();
chunkVersions.Dispose();
chunkEntityCounts.Dispose();
entityOffsets.Dispose();
offsets0.Dispose();
bitsOffsets0.Dispose();
versionindices0.Dispose();
}
}
public JobHandle ScheduleEntityParallel<TJob, T0>(TJob jobData, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntity<T0>
where T0 : unmanaged, IComponent
{
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);
var offsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices0 = 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
var layout0 = arch.GetLayout(ComponentTypeID<T0>.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);
offsets0.Add(layout0.offset);
bitsOffsets0.Add(layout0.enableBitsOffset);
versionIndices0.Add(layout0.versionIndex);
}
}
// 2. Create the Runner
var runner = new JobEntityBatch<TJob, T0>
{
userJob = jobData,
chunks = chunks,
chunkVersions = chunkVersions,
chunkCount = chunkEntityCounts,
entityOffset = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
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 DisposeJobEntity1
{
chunks = chunks,
chunkVersions = chunkVersions,
chunkEntityCounts = chunkEntityCounts,
entityOffsets = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
};
world.JobScheduler.Schedule(ref disposeJob, jobHandle);
return jobHandle;
}
private struct DisposeJobEntity2 : IJob
{
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkEntityCounts;
public UnsafeList<int> entityOffsets;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public void Execute(int threadIndex)
{
chunks.Dispose();
chunkVersions.Dispose();
chunkEntityCounts.Dispose();
entityOffsets.Dispose();
offsets0.Dispose();
bitsOffsets0.Dispose();
versionindices0.Dispose();
offsets1.Dispose();
bitsOffsets1.Dispose();
versionindices1.Dispose();
}
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1>(TJob jobData, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntity<T0, T1>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
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);
var offsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices1 = 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
var layout0 = arch.GetLayout(ComponentTypeID<T0>.Value)
.GetValueOrThrow();
var layout1 = arch.GetLayout(ComponentTypeID<T1>.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);
offsets0.Add(layout0.offset);
bitsOffsets0.Add(layout0.enableBitsOffset);
versionIndices0.Add(layout0.versionIndex);
offsets1.Add(layout1.offset);
bitsOffsets1.Add(layout1.enableBitsOffset);
versionIndices1.Add(layout1.versionIndex);
}
}
// 2. Create the Runner
var runner = new JobEntityBatch<TJob, T0, T1>
{
userJob = jobData,
chunks = chunks,
chunkVersions = chunkVersions,
chunkCount = chunkEntityCounts,
entityOffset = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
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 DisposeJobEntity2
{
chunks = chunks,
chunkVersions = chunkVersions,
chunkEntityCounts = chunkEntityCounts,
entityOffsets = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
};
world.JobScheduler.Schedule(ref disposeJob, jobHandle);
return jobHandle;
}
private struct DisposeJobEntity3 : IJob
{
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkEntityCounts;
public UnsafeList<int> entityOffsets;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public void Execute(int threadIndex)
{
chunks.Dispose();
chunkVersions.Dispose();
chunkEntityCounts.Dispose();
entityOffsets.Dispose();
offsets0.Dispose();
bitsOffsets0.Dispose();
versionindices0.Dispose();
offsets1.Dispose();
bitsOffsets1.Dispose();
versionindices1.Dispose();
offsets2.Dispose();
bitsOffsets2.Dispose();
versionindices2.Dispose();
}
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2>(TJob jobData, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntity<T0, T1, T2>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
{
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);
var offsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices2 = 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
var layout0 = arch.GetLayout(ComponentTypeID<T0>.Value)
.GetValueOrThrow();
var layout1 = arch.GetLayout(ComponentTypeID<T1>.Value)
.GetValueOrThrow();
var layout2 = arch.GetLayout(ComponentTypeID<T2>.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);
offsets0.Add(layout0.offset);
bitsOffsets0.Add(layout0.enableBitsOffset);
versionIndices0.Add(layout0.versionIndex);
offsets1.Add(layout1.offset);
bitsOffsets1.Add(layout1.enableBitsOffset);
versionIndices1.Add(layout1.versionIndex);
offsets2.Add(layout2.offset);
bitsOffsets2.Add(layout2.enableBitsOffset);
versionIndices2.Add(layout2.versionIndex);
}
}
// 2. Create the Runner
var runner = new JobEntityBatch<TJob, T0, T1, T2>
{
userJob = jobData,
chunks = chunks,
chunkVersions = chunkVersions,
chunkCount = chunkEntityCounts,
entityOffset = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
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 DisposeJobEntity3
{
chunks = chunks,
chunkVersions = chunkVersions,
chunkEntityCounts = chunkEntityCounts,
entityOffsets = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
};
world.JobScheduler.Schedule(ref disposeJob, jobHandle);
return jobHandle;
}
private struct DisposeJobEntity4 : IJob
{
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkEntityCounts;
public UnsafeList<int> entityOffsets;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public UnsafeList<int> offsets3;
public UnsafeList<int> bitsOffsets3;
public UnsafeList<int> versionindices3;
public void Execute(int threadIndex)
{
chunks.Dispose();
chunkVersions.Dispose();
chunkEntityCounts.Dispose();
entityOffsets.Dispose();
offsets0.Dispose();
bitsOffsets0.Dispose();
versionindices0.Dispose();
offsets1.Dispose();
bitsOffsets1.Dispose();
versionindices1.Dispose();
offsets2.Dispose();
bitsOffsets2.Dispose();
versionindices2.Dispose();
offsets3.Dispose();
bitsOffsets3.Dispose();
versionindices3.Dispose();
}
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2, T3>(TJob jobData, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
where T3 : unmanaged, IComponent
{
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);
var offsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices3 = 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
var layout0 = arch.GetLayout(ComponentTypeID<T0>.Value)
.GetValueOrThrow();
var layout1 = arch.GetLayout(ComponentTypeID<T1>.Value)
.GetValueOrThrow();
var layout2 = arch.GetLayout(ComponentTypeID<T2>.Value)
.GetValueOrThrow();
var layout3 = arch.GetLayout(ComponentTypeID<T3>.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);
offsets0.Add(layout0.offset);
bitsOffsets0.Add(layout0.enableBitsOffset);
versionIndices0.Add(layout0.versionIndex);
offsets1.Add(layout1.offset);
bitsOffsets1.Add(layout1.enableBitsOffset);
versionIndices1.Add(layout1.versionIndex);
offsets2.Add(layout2.offset);
bitsOffsets2.Add(layout2.enableBitsOffset);
versionIndices2.Add(layout2.versionIndex);
offsets3.Add(layout3.offset);
bitsOffsets3.Add(layout3.enableBitsOffset);
versionIndices3.Add(layout3.versionIndex);
}
}
// 2. Create the Runner
var runner = new JobEntityBatch<TJob, T0, T1, T2, T3>
{
userJob = jobData,
chunks = chunks,
chunkVersions = chunkVersions,
chunkCount = chunkEntityCounts,
entityOffset = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
offsets3 = offsets3,
bitsOffsets3 = bitsOffsets3,
versionindices3 = versionIndices3,
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 DisposeJobEntity4
{
chunks = chunks,
chunkVersions = chunkVersions,
chunkEntityCounts = chunkEntityCounts,
entityOffsets = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
offsets3 = offsets3,
bitsOffsets3 = bitsOffsets3,
versionindices3 = versionIndices3,
};
world.JobScheduler.Schedule(ref disposeJob, jobHandle);
return jobHandle;
}
private struct DisposeJobEntity5 : IJob
{
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkEntityCounts;
public UnsafeList<int> entityOffsets;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public UnsafeList<int> offsets3;
public UnsafeList<int> bitsOffsets3;
public UnsafeList<int> versionindices3;
public UnsafeList<int> offsets4;
public UnsafeList<int> bitsOffsets4;
public UnsafeList<int> versionindices4;
public void Execute(int threadIndex)
{
chunks.Dispose();
chunkVersions.Dispose();
chunkEntityCounts.Dispose();
entityOffsets.Dispose();
offsets0.Dispose();
bitsOffsets0.Dispose();
versionindices0.Dispose();
offsets1.Dispose();
bitsOffsets1.Dispose();
versionindices1.Dispose();
offsets2.Dispose();
bitsOffsets2.Dispose();
versionindices2.Dispose();
offsets3.Dispose();
bitsOffsets3.Dispose();
versionindices3.Dispose();
offsets4.Dispose();
bitsOffsets4.Dispose();
versionindices4.Dispose();
}
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2, T3, T4>(TJob jobData, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
where T3 : unmanaged, IComponent
where T4 : unmanaged, IComponent
{
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);
var offsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices4 = 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
var layout0 = arch.GetLayout(ComponentTypeID<T0>.Value)
.GetValueOrThrow();
var layout1 = arch.GetLayout(ComponentTypeID<T1>.Value)
.GetValueOrThrow();
var layout2 = arch.GetLayout(ComponentTypeID<T2>.Value)
.GetValueOrThrow();
var layout3 = arch.GetLayout(ComponentTypeID<T3>.Value)
.GetValueOrThrow();
var layout4 = arch.GetLayout(ComponentTypeID<T4>.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);
offsets0.Add(layout0.offset);
bitsOffsets0.Add(layout0.enableBitsOffset);
versionIndices0.Add(layout0.versionIndex);
offsets1.Add(layout1.offset);
bitsOffsets1.Add(layout1.enableBitsOffset);
versionIndices1.Add(layout1.versionIndex);
offsets2.Add(layout2.offset);
bitsOffsets2.Add(layout2.enableBitsOffset);
versionIndices2.Add(layout2.versionIndex);
offsets3.Add(layout3.offset);
bitsOffsets3.Add(layout3.enableBitsOffset);
versionIndices3.Add(layout3.versionIndex);
offsets4.Add(layout4.offset);
bitsOffsets4.Add(layout4.enableBitsOffset);
versionIndices4.Add(layout4.versionIndex);
}
}
// 2. Create the Runner
var runner = new JobEntityBatch<TJob, T0, T1, T2, T3, T4>
{
userJob = jobData,
chunks = chunks,
chunkVersions = chunkVersions,
chunkCount = chunkEntityCounts,
entityOffset = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
offsets3 = offsets3,
bitsOffsets3 = bitsOffsets3,
versionindices3 = versionIndices3,
offsets4 = offsets4,
bitsOffsets4 = bitsOffsets4,
versionindices4 = versionIndices4,
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 DisposeJobEntity5
{
chunks = chunks,
chunkVersions = chunkVersions,
chunkEntityCounts = chunkEntityCounts,
entityOffsets = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
offsets3 = offsets3,
bitsOffsets3 = bitsOffsets3,
versionindices3 = versionIndices3,
offsets4 = offsets4,
bitsOffsets4 = bitsOffsets4,
versionindices4 = versionIndices4,
};
world.JobScheduler.Schedule(ref disposeJob, jobHandle);
return jobHandle;
}
private struct DisposeJobEntity6 : IJob
{
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkEntityCounts;
public UnsafeList<int> entityOffsets;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public UnsafeList<int> offsets3;
public UnsafeList<int> bitsOffsets3;
public UnsafeList<int> versionindices3;
public UnsafeList<int> offsets4;
public UnsafeList<int> bitsOffsets4;
public UnsafeList<int> versionindices4;
public UnsafeList<int> offsets5;
public UnsafeList<int> bitsOffsets5;
public UnsafeList<int> versionindices5;
public void Execute(int threadIndex)
{
chunks.Dispose();
chunkVersions.Dispose();
chunkEntityCounts.Dispose();
entityOffsets.Dispose();
offsets0.Dispose();
bitsOffsets0.Dispose();
versionindices0.Dispose();
offsets1.Dispose();
bitsOffsets1.Dispose();
versionindices1.Dispose();
offsets2.Dispose();
bitsOffsets2.Dispose();
versionindices2.Dispose();
offsets3.Dispose();
bitsOffsets3.Dispose();
versionindices3.Dispose();
offsets4.Dispose();
bitsOffsets4.Dispose();
versionindices4.Dispose();
offsets5.Dispose();
bitsOffsets5.Dispose();
versionindices5.Dispose();
}
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2, T3, T4, T5>(TJob jobData, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
where T3 : unmanaged, IComponent
where T4 : unmanaged, IComponent
where T5 : unmanaged, IComponent
{
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);
var offsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets5 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets5 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices5 = 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
var layout0 = arch.GetLayout(ComponentTypeID<T0>.Value)
.GetValueOrThrow();
var layout1 = arch.GetLayout(ComponentTypeID<T1>.Value)
.GetValueOrThrow();
var layout2 = arch.GetLayout(ComponentTypeID<T2>.Value)
.GetValueOrThrow();
var layout3 = arch.GetLayout(ComponentTypeID<T3>.Value)
.GetValueOrThrow();
var layout4 = arch.GetLayout(ComponentTypeID<T4>.Value)
.GetValueOrThrow();
var layout5 = arch.GetLayout(ComponentTypeID<T5>.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);
offsets0.Add(layout0.offset);
bitsOffsets0.Add(layout0.enableBitsOffset);
versionIndices0.Add(layout0.versionIndex);
offsets1.Add(layout1.offset);
bitsOffsets1.Add(layout1.enableBitsOffset);
versionIndices1.Add(layout1.versionIndex);
offsets2.Add(layout2.offset);
bitsOffsets2.Add(layout2.enableBitsOffset);
versionIndices2.Add(layout2.versionIndex);
offsets3.Add(layout3.offset);
bitsOffsets3.Add(layout3.enableBitsOffset);
versionIndices3.Add(layout3.versionIndex);
offsets4.Add(layout4.offset);
bitsOffsets4.Add(layout4.enableBitsOffset);
versionIndices4.Add(layout4.versionIndex);
offsets5.Add(layout5.offset);
bitsOffsets5.Add(layout5.enableBitsOffset);
versionIndices5.Add(layout5.versionIndex);
}
}
// 2. Create the Runner
var runner = new JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5>
{
userJob = jobData,
chunks = chunks,
chunkVersions = chunkVersions,
chunkCount = chunkEntityCounts,
entityOffset = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
offsets3 = offsets3,
bitsOffsets3 = bitsOffsets3,
versionindices3 = versionIndices3,
offsets4 = offsets4,
bitsOffsets4 = bitsOffsets4,
versionindices4 = versionIndices4,
offsets5 = offsets5,
bitsOffsets5 = bitsOffsets5,
versionindices5 = versionIndices5,
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 DisposeJobEntity6
{
chunks = chunks,
chunkVersions = chunkVersions,
chunkEntityCounts = chunkEntityCounts,
entityOffsets = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
offsets3 = offsets3,
bitsOffsets3 = bitsOffsets3,
versionindices3 = versionIndices3,
offsets4 = offsets4,
bitsOffsets4 = bitsOffsets4,
versionindices4 = versionIndices4,
offsets5 = offsets5,
bitsOffsets5 = bitsOffsets5,
versionindices5 = versionIndices5,
};
world.JobScheduler.Schedule(ref disposeJob, jobHandle);
return jobHandle;
}
private struct DisposeJobEntity7 : IJob
{
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkEntityCounts;
public UnsafeList<int> entityOffsets;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public UnsafeList<int> offsets3;
public UnsafeList<int> bitsOffsets3;
public UnsafeList<int> versionindices3;
public UnsafeList<int> offsets4;
public UnsafeList<int> bitsOffsets4;
public UnsafeList<int> versionindices4;
public UnsafeList<int> offsets5;
public UnsafeList<int> bitsOffsets5;
public UnsafeList<int> versionindices5;
public UnsafeList<int> offsets6;
public UnsafeList<int> bitsOffsets6;
public UnsafeList<int> versionindices6;
public void Execute(int threadIndex)
{
chunks.Dispose();
chunkVersions.Dispose();
chunkEntityCounts.Dispose();
entityOffsets.Dispose();
offsets0.Dispose();
bitsOffsets0.Dispose();
versionindices0.Dispose();
offsets1.Dispose();
bitsOffsets1.Dispose();
versionindices1.Dispose();
offsets2.Dispose();
bitsOffsets2.Dispose();
versionindices2.Dispose();
offsets3.Dispose();
bitsOffsets3.Dispose();
versionindices3.Dispose();
offsets4.Dispose();
bitsOffsets4.Dispose();
versionindices4.Dispose();
offsets5.Dispose();
bitsOffsets5.Dispose();
versionindices5.Dispose();
offsets6.Dispose();
bitsOffsets6.Dispose();
versionindices6.Dispose();
}
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2, T3, T4, T5, T6>(TJob jobData, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5, T6>
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
{
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);
var offsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets5 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets5 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices5 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets6 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets6 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices6 = 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
var layout0 = arch.GetLayout(ComponentTypeID<T0>.Value)
.GetValueOrThrow();
var layout1 = arch.GetLayout(ComponentTypeID<T1>.Value)
.GetValueOrThrow();
var layout2 = arch.GetLayout(ComponentTypeID<T2>.Value)
.GetValueOrThrow();
var layout3 = arch.GetLayout(ComponentTypeID<T3>.Value)
.GetValueOrThrow();
var layout4 = arch.GetLayout(ComponentTypeID<T4>.Value)
.GetValueOrThrow();
var layout5 = arch.GetLayout(ComponentTypeID<T5>.Value)
.GetValueOrThrow();
var layout6 = arch.GetLayout(ComponentTypeID<T6>.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);
offsets0.Add(layout0.offset);
bitsOffsets0.Add(layout0.enableBitsOffset);
versionIndices0.Add(layout0.versionIndex);
offsets1.Add(layout1.offset);
bitsOffsets1.Add(layout1.enableBitsOffset);
versionIndices1.Add(layout1.versionIndex);
offsets2.Add(layout2.offset);
bitsOffsets2.Add(layout2.enableBitsOffset);
versionIndices2.Add(layout2.versionIndex);
offsets3.Add(layout3.offset);
bitsOffsets3.Add(layout3.enableBitsOffset);
versionIndices3.Add(layout3.versionIndex);
offsets4.Add(layout4.offset);
bitsOffsets4.Add(layout4.enableBitsOffset);
versionIndices4.Add(layout4.versionIndex);
offsets5.Add(layout5.offset);
bitsOffsets5.Add(layout5.enableBitsOffset);
versionIndices5.Add(layout5.versionIndex);
offsets6.Add(layout6.offset);
bitsOffsets6.Add(layout6.enableBitsOffset);
versionIndices6.Add(layout6.versionIndex);
}
}
// 2. Create the Runner
var runner = new JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5, T6>
{
userJob = jobData,
chunks = chunks,
chunkVersions = chunkVersions,
chunkCount = chunkEntityCounts,
entityOffset = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
offsets3 = offsets3,
bitsOffsets3 = bitsOffsets3,
versionindices3 = versionIndices3,
offsets4 = offsets4,
bitsOffsets4 = bitsOffsets4,
versionindices4 = versionIndices4,
offsets5 = offsets5,
bitsOffsets5 = bitsOffsets5,
versionindices5 = versionIndices5,
offsets6 = offsets6,
bitsOffsets6 = bitsOffsets6,
versionindices6 = versionIndices6,
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 DisposeJobEntity7
{
chunks = chunks,
chunkVersions = chunkVersions,
chunkEntityCounts = chunkEntityCounts,
entityOffsets = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
offsets3 = offsets3,
bitsOffsets3 = bitsOffsets3,
versionindices3 = versionIndices3,
offsets4 = offsets4,
bitsOffsets4 = bitsOffsets4,
versionindices4 = versionIndices4,
offsets5 = offsets5,
bitsOffsets5 = bitsOffsets5,
versionindices5 = versionIndices5,
offsets6 = offsets6,
bitsOffsets6 = bitsOffsets6,
versionindices6 = versionIndices6,
};
world.JobScheduler.Schedule(ref disposeJob, jobHandle);
return jobHandle;
}
private struct DisposeJobEntity8 : IJob
{
public UnsafeList<IntPtr> chunks;
public UnsafeList<IntPtr> chunkVersions;
public UnsafeList<int> chunkEntityCounts;
public UnsafeList<int> entityOffsets;
public UnsafeList<int> offsets0;
public UnsafeList<int> bitsOffsets0;
public UnsafeList<int> versionindices0;
public UnsafeList<int> offsets1;
public UnsafeList<int> bitsOffsets1;
public UnsafeList<int> versionindices1;
public UnsafeList<int> offsets2;
public UnsafeList<int> bitsOffsets2;
public UnsafeList<int> versionindices2;
public UnsafeList<int> offsets3;
public UnsafeList<int> bitsOffsets3;
public UnsafeList<int> versionindices3;
public UnsafeList<int> offsets4;
public UnsafeList<int> bitsOffsets4;
public UnsafeList<int> versionindices4;
public UnsafeList<int> offsets5;
public UnsafeList<int> bitsOffsets5;
public UnsafeList<int> versionindices5;
public UnsafeList<int> offsets6;
public UnsafeList<int> bitsOffsets6;
public UnsafeList<int> versionindices6;
public UnsafeList<int> offsets7;
public UnsafeList<int> bitsOffsets7;
public UnsafeList<int> versionindices7;
public void Execute(int threadIndex)
{
chunks.Dispose();
chunkVersions.Dispose();
chunkEntityCounts.Dispose();
entityOffsets.Dispose();
offsets0.Dispose();
bitsOffsets0.Dispose();
versionindices0.Dispose();
offsets1.Dispose();
bitsOffsets1.Dispose();
versionindices1.Dispose();
offsets2.Dispose();
bitsOffsets2.Dispose();
versionindices2.Dispose();
offsets3.Dispose();
bitsOffsets3.Dispose();
versionindices3.Dispose();
offsets4.Dispose();
bitsOffsets4.Dispose();
versionindices4.Dispose();
offsets5.Dispose();
bitsOffsets5.Dispose();
versionindices5.Dispose();
offsets6.Dispose();
bitsOffsets6.Dispose();
versionindices6.Dispose();
offsets7.Dispose();
bitsOffsets7.Dispose();
versionindices7.Dispose();
}
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2, T3, T4, T5, T6, T7>(TJob jobData, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5, T6, T7>
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
{
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);
var offsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices0 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices1 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices2 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices3 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices4 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets5 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets5 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices5 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets6 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets6 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices6 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var offsets7 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var bitsOffsets7 = new UnsafeList<int>(128, JobScheduler.TempAllocatorHandle);
var versionIndices7 = 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
var layout0 = arch.GetLayout(ComponentTypeID<T0>.Value)
.GetValueOrThrow();
var layout1 = arch.GetLayout(ComponentTypeID<T1>.Value)
.GetValueOrThrow();
var layout2 = arch.GetLayout(ComponentTypeID<T2>.Value)
.GetValueOrThrow();
var layout3 = arch.GetLayout(ComponentTypeID<T3>.Value)
.GetValueOrThrow();
var layout4 = arch.GetLayout(ComponentTypeID<T4>.Value)
.GetValueOrThrow();
var layout5 = arch.GetLayout(ComponentTypeID<T5>.Value)
.GetValueOrThrow();
var layout6 = arch.GetLayout(ComponentTypeID<T6>.Value)
.GetValueOrThrow();
var layout7 = arch.GetLayout(ComponentTypeID<T7>.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);
offsets0.Add(layout0.offset);
bitsOffsets0.Add(layout0.enableBitsOffset);
versionIndices0.Add(layout0.versionIndex);
offsets1.Add(layout1.offset);
bitsOffsets1.Add(layout1.enableBitsOffset);
versionIndices1.Add(layout1.versionIndex);
offsets2.Add(layout2.offset);
bitsOffsets2.Add(layout2.enableBitsOffset);
versionIndices2.Add(layout2.versionIndex);
offsets3.Add(layout3.offset);
bitsOffsets3.Add(layout3.enableBitsOffset);
versionIndices3.Add(layout3.versionIndex);
offsets4.Add(layout4.offset);
bitsOffsets4.Add(layout4.enableBitsOffset);
versionIndices4.Add(layout4.versionIndex);
offsets5.Add(layout5.offset);
bitsOffsets5.Add(layout5.enableBitsOffset);
versionIndices5.Add(layout5.versionIndex);
offsets6.Add(layout6.offset);
bitsOffsets6.Add(layout6.enableBitsOffset);
versionIndices6.Add(layout6.versionIndex);
offsets7.Add(layout7.offset);
bitsOffsets7.Add(layout7.enableBitsOffset);
versionIndices7.Add(layout7.versionIndex);
}
}
// 2. Create the Runner
var runner = new JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5, T6, T7>
{
userJob = jobData,
chunks = chunks,
chunkVersions = chunkVersions,
chunkCount = chunkEntityCounts,
entityOffset = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
offsets3 = offsets3,
bitsOffsets3 = bitsOffsets3,
versionindices3 = versionIndices3,
offsets4 = offsets4,
bitsOffsets4 = bitsOffsets4,
versionindices4 = versionIndices4,
offsets5 = offsets5,
bitsOffsets5 = bitsOffsets5,
versionindices5 = versionIndices5,
offsets6 = offsets6,
bitsOffsets6 = bitsOffsets6,
versionindices6 = versionIndices6,
offsets7 = offsets7,
bitsOffsets7 = bitsOffsets7,
versionindices7 = versionIndices7,
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 DisposeJobEntity8
{
chunks = chunks,
chunkVersions = chunkVersions,
chunkEntityCounts = chunkEntityCounts,
entityOffsets = entityOffsets,
offsets0 = offsets0,
bitsOffsets0 = bitsOffsets0,
versionindices0 = versionIndices0,
offsets1 = offsets1,
bitsOffsets1 = bitsOffsets1,
versionindices1 = versionIndices1,
offsets2 = offsets2,
bitsOffsets2 = bitsOffsets2,
versionindices2 = versionIndices2,
offsets3 = offsets3,
bitsOffsets3 = bitsOffsets3,
versionindices3 = versionIndices3,
offsets4 = offsets4,
bitsOffsets4 = bitsOffsets4,
versionindices4 = versionIndices4,
offsets5 = offsets5,
bitsOffsets5 = bitsOffsets5,
versionindices5 = versionIndices5,
offsets6 = offsets6,
bitsOffsets6 = bitsOffsets6,
versionindices6 = versionIndices6,
offsets7 = offsets7,
bitsOffsets7 = bitsOffsets7,
versionindices7 = versionIndices7,
};
world.JobScheduler.Schedule(ref disposeJob, jobHandle);
return jobHandle;
}
}