using Ghost.Core; using Misaki.HighPerformance.Jobs; using Misaki.HighPerformance.LowLevel.Collections; namespace Ghost.Entities; public interface IJobEntity where T0 : unmanaged, IComponent { void Execute(Entity entity, ref T0 component0, int threadIndex); } internal unsafe struct JobEntityBatch : IJobParallelFor where TJob : unmanaged, IJobEntity where T0 : unmanaged, IComponent { public fixed int componentIDs[1]; public fixed bool componentRW[1]; public TJob userJob; public UnsafeList chunks; public UnsafeList chunkVersions; public UnsafeList chunkCount; public UnsafeList entityOffset; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList 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 where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent { void Execute(Entity entity, ref T0 component0, ref T1 component1, int threadIndex); } internal unsafe struct JobEntityBatch : IJobParallelFor where TJob : unmanaged, IJobEntity where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent { public fixed int componentIDs[2]; public fixed bool componentRW[2]; public TJob userJob; public UnsafeList chunks; public UnsafeList chunkVersions; public UnsafeList chunkCount; public UnsafeList entityOffset; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList 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 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 : IJobParallelFor where TJob : unmanaged, IJobEntity 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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkCount; public UnsafeList entityOffset; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList 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 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 : IJobParallelFor where TJob : unmanaged, IJobEntity 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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkCount; public UnsafeList entityOffset; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList versionindices2; public UnsafeList offsets3; public UnsafeList bitsOffsets3; public UnsafeList 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 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 : IJobParallelFor where TJob : unmanaged, IJobEntity 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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkCount; public UnsafeList entityOffset; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList versionindices2; public UnsafeList offsets3; public UnsafeList bitsOffsets3; public UnsafeList versionindices3; public UnsafeList offsets4; public UnsafeList bitsOffsets4; public UnsafeList 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 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 : IJobParallelFor where TJob : unmanaged, IJobEntity 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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkCount; public UnsafeList entityOffset; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList versionindices2; public UnsafeList offsets3; public UnsafeList bitsOffsets3; public UnsafeList versionindices3; public UnsafeList offsets4; public UnsafeList bitsOffsets4; public UnsafeList versionindices4; public UnsafeList offsets5; public UnsafeList bitsOffsets5; public UnsafeList 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 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 : IJobParallelFor where TJob : unmanaged, IJobEntity 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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkCount; public UnsafeList entityOffset; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList versionindices2; public UnsafeList offsets3; public UnsafeList bitsOffsets3; public UnsafeList versionindices3; public UnsafeList offsets4; public UnsafeList bitsOffsets4; public UnsafeList versionindices4; public UnsafeList offsets5; public UnsafeList bitsOffsets5; public UnsafeList versionindices5; public UnsafeList offsets6; public UnsafeList bitsOffsets6; public UnsafeList 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 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 : IJobParallelFor where TJob : unmanaged, IJobEntity 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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkCount; public UnsafeList entityOffset; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList versionindices2; public UnsafeList offsets3; public UnsafeList bitsOffsets3; public UnsafeList versionindices3; public UnsafeList offsets4; public UnsafeList bitsOffsets4; public UnsafeList versionindices4; public UnsafeList offsets5; public UnsafeList bitsOffsets5; public UnsafeList versionindices5; public UnsafeList offsets6; public UnsafeList bitsOffsets6; public UnsafeList versionindices6; public UnsafeList offsets7; public UnsafeList bitsOffsets7; public UnsafeList 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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkEntityCounts; public UnsafeList entityOffsets; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public void Execute(int threadIndex) { chunks.Dispose(); chunkVersions.Dispose(); chunkEntityCounts.Dispose(); entityOffsets.Dispose(); offsets0.Dispose(); bitsOffsets0.Dispose(); versionindices0.Dispose(); } } public JobHandle ScheduleEntityParallel(TJob jobData, int batchSize, JobHandle dependency) where TJob : unmanaged, IJobEntity where T0 : unmanaged, IComponent { var world = World.GetWorld(_worldID).GetValueOrThrow(); if (world.JobScheduler == null) { throw new InvalidOperationException("The World has no JobScheduler assigned."); } // 1. Flatten the World var chunks = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkVersions = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkEntityCounts = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var entityOffsets = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices0 = new UnsafeList(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.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 { userJob = jobData, chunks = chunks, chunkVersions = chunkVersions, chunkCount = chunkEntityCounts, entityOffset = entityOffsets, offsets0 = offsets0, bitsOffsets0 = bitsOffsets0, versionindices0 = versionIndices0, version = world.Version, }; runner.componentIDs[0] = ComponentTypeID.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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkEntityCounts; public UnsafeList entityOffsets; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList 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 jobData, int batchSize, JobHandle dependency) where TJob : unmanaged, IJobEntity where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent { var world = World.GetWorld(_worldID).GetValueOrThrow(); if (world.JobScheduler == null) { throw new InvalidOperationException("The World has no JobScheduler assigned."); } // 1. Flatten the World var chunks = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkVersions = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkEntityCounts = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var entityOffsets = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices1 = new UnsafeList(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.Value) .GetValueOrThrow(); var layout1 = arch.GetLayout(ComponentTypeID.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 { 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.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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkEntityCounts; public UnsafeList entityOffsets; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList 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 jobData, int batchSize, JobHandle dependency) where TJob : unmanaged, IJobEntity where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent { var world = World.GetWorld(_worldID).GetValueOrThrow(); if (world.JobScheduler == null) { throw new InvalidOperationException("The World has no JobScheduler assigned."); } // 1. Flatten the World var chunks = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkVersions = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkEntityCounts = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var entityOffsets = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices2 = new UnsafeList(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.Value) .GetValueOrThrow(); var layout1 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout2 = arch.GetLayout(ComponentTypeID.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 { 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.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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkEntityCounts; public UnsafeList entityOffsets; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList versionindices2; public UnsafeList offsets3; public UnsafeList bitsOffsets3; public UnsafeList 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 jobData, int batchSize, JobHandle dependency) where TJob : unmanaged, IJobEntity where T0 : unmanaged, IComponent where T1 : unmanaged, IComponent where T2 : unmanaged, IComponent where T3 : unmanaged, IComponent { var world = World.GetWorld(_worldID).GetValueOrThrow(); if (world.JobScheduler == null) { throw new InvalidOperationException("The World has no JobScheduler assigned."); } // 1. Flatten the World var chunks = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkVersions = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkEntityCounts = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var entityOffsets = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices3 = new UnsafeList(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.Value) .GetValueOrThrow(); var layout1 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout2 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout3 = arch.GetLayout(ComponentTypeID.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 { 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.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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkEntityCounts; public UnsafeList entityOffsets; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList versionindices2; public UnsafeList offsets3; public UnsafeList bitsOffsets3; public UnsafeList versionindices3; public UnsafeList offsets4; public UnsafeList bitsOffsets4; public UnsafeList 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 jobData, int batchSize, JobHandle dependency) where TJob : unmanaged, IJobEntity 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).GetValueOrThrow(); if (world.JobScheduler == null) { throw new InvalidOperationException("The World has no JobScheduler assigned."); } // 1. Flatten the World var chunks = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkVersions = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkEntityCounts = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var entityOffsets = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices4 = new UnsafeList(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.Value) .GetValueOrThrow(); var layout1 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout2 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout3 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout4 = arch.GetLayout(ComponentTypeID.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 { 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.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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkEntityCounts; public UnsafeList entityOffsets; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList versionindices2; public UnsafeList offsets3; public UnsafeList bitsOffsets3; public UnsafeList versionindices3; public UnsafeList offsets4; public UnsafeList bitsOffsets4; public UnsafeList versionindices4; public UnsafeList offsets5; public UnsafeList bitsOffsets5; public UnsafeList 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 jobData, int batchSize, JobHandle dependency) where TJob : unmanaged, IJobEntity 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).GetValueOrThrow(); if (world.JobScheduler == null) { throw new InvalidOperationException("The World has no JobScheduler assigned."); } // 1. Flatten the World var chunks = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkVersions = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkEntityCounts = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var entityOffsets = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets5 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets5 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices5 = new UnsafeList(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.Value) .GetValueOrThrow(); var layout1 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout2 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout3 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout4 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout5 = arch.GetLayout(ComponentTypeID.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 { 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.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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkEntityCounts; public UnsafeList entityOffsets; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList versionindices2; public UnsafeList offsets3; public UnsafeList bitsOffsets3; public UnsafeList versionindices3; public UnsafeList offsets4; public UnsafeList bitsOffsets4; public UnsafeList versionindices4; public UnsafeList offsets5; public UnsafeList bitsOffsets5; public UnsafeList versionindices5; public UnsafeList offsets6; public UnsafeList bitsOffsets6; public UnsafeList 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 jobData, int batchSize, JobHandle dependency) where TJob : unmanaged, IJobEntity 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).GetValueOrThrow(); if (world.JobScheduler == null) { throw new InvalidOperationException("The World has no JobScheduler assigned."); } // 1. Flatten the World var chunks = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkVersions = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkEntityCounts = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var entityOffsets = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets5 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets5 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices5 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets6 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets6 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices6 = new UnsafeList(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.Value) .GetValueOrThrow(); var layout1 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout2 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout3 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout4 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout5 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout6 = arch.GetLayout(ComponentTypeID.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 { 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.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 chunks; public UnsafeList chunkVersions; public UnsafeList chunkEntityCounts; public UnsafeList entityOffsets; public UnsafeList offsets0; public UnsafeList bitsOffsets0; public UnsafeList versionindices0; public UnsafeList offsets1; public UnsafeList bitsOffsets1; public UnsafeList versionindices1; public UnsafeList offsets2; public UnsafeList bitsOffsets2; public UnsafeList versionindices2; public UnsafeList offsets3; public UnsafeList bitsOffsets3; public UnsafeList versionindices3; public UnsafeList offsets4; public UnsafeList bitsOffsets4; public UnsafeList versionindices4; public UnsafeList offsets5; public UnsafeList bitsOffsets5; public UnsafeList versionindices5; public UnsafeList offsets6; public UnsafeList bitsOffsets6; public UnsafeList versionindices6; public UnsafeList offsets7; public UnsafeList bitsOffsets7; public UnsafeList 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 jobData, int batchSize, JobHandle dependency) where TJob : unmanaged, IJobEntity 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).GetValueOrThrow(); if (world.JobScheduler == null) { throw new InvalidOperationException("The World has no JobScheduler assigned."); } // 1. Flatten the World var chunks = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkVersions = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var chunkEntityCounts = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var entityOffsets = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices0 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices1 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices2 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices3 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices4 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets5 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets5 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices5 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets6 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets6 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices6 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var offsets7 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var bitsOffsets7 = new UnsafeList(128, JobScheduler.TempAllocatorHandle); var versionIndices7 = new UnsafeList(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.Value) .GetValueOrThrow(); var layout1 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout2 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout3 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout4 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout5 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout6 = arch.GetLayout(ComponentTypeID.Value) .GetValueOrThrow(); var layout7 = arch.GetLayout(ComponentTypeID.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 { 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.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; } }