is it possible to use EntityCommandBuffer with IJobParallelFor ?

Hello Everyone,

Can anyone give an example of using an EntityCommandBuffer with an IJobParallelFor type?
im using a Job of Type IJobParallelFor to process chunks in parallel, but strangely it seems that the EntityCommandBuffer is not compatible with this job type.

it is simply impossible to use the concurrent version of EntityCommandBuffer because there is no way to get a JobIndex value from the IJobParallelFor.Execute function.

The IJobParallelFor requires a ReadOnly EntityCommandBuffer and writing to it throws an error.

Note: I was using the IJobChunk interface but I want to control the number of Chunks processed by each worker thread.

        [BurstCompile]
        private struct EnableVisibleInRangeChunksV2 : IJobParallelFor
        {
            [ReadOnly] public int2 CurrentRegion;
            [ReadOnly] public ArchetypeChunkComponentType<WorldMapRegionChunk> WorldMapRegionChunkType;

            [DeallocateOnJobCompletion]
            [ReadOnly] public NativeArray<ArchetypeChunk> Chunks;

            [ReadOnly] public EntityCommandBuffer CommandBuffer;

            [ReadOnly] public EntityArchetype entityArchetype;
            [ReadOnly] public ArchetypeChunkEntityType ArchetypeChunkEntityType;
            [ReadOnly] public int EntitySize;

            public void Execute(int index)
            {
                var chunk = Chunks[index];

                var wmrValue = chunk.GetChunkComponentData(WorldMapRegionChunkType).value;

                if (math.abs(CurrentRegion.x - wmrValue.x) > 1 || (math.abs(CurrentRegion.y - wmrValue.y) > 1))
                    return;

                Debug.Log("Chunk Included!");

                //Chunk Included
                var enableEntityRequest = CommandBuffer.CreateEntity(entityArchetype);

                var entities = chunk.GetNativeArray(ArchetypeChunkEntityType);

                BlobBuilder blobBuilder = new BlobBuilder(Allocator.Temp);

                ref EntitiesArray entitiesArray = ref blobBuilder.ConstructRoot<EntitiesArray>();

                BlobBuilderArray<Entity> entitiesArrayBlob = blobBuilder.Allocate(ref entitiesArray.Entities, entities.Length);
                unsafe
                {
                    UnsafeUtility.MemCpy(entitiesArrayBlob.GetUnsafePtr(), entities.GetUnsafeReadOnlyPtr(), entities.Length * EntitySize);
                }
                var blob = blobBuilder.CreateBlobAssetReference<EntitiesArray>(Allocator.TempJob);

                blobBuilder.Dispose();

                var chunkStateRequest = new ChunkStateRequest
                {
                    EntitiesArray = blob,
                    Enabled = true
                };

                CommandBuffer.SetComponent(enableEntityRequest, chunkStateRequest);
            }
        }

In any parallel job (IJobChunk, IJobParallelFor etc) you need to use its parallel version

EntityCommandBuffer.ParallelWriter

this.bufferSystem.CreateCommandBuffer().AsParallelWriter();

(in earlier versions it was called concurrent)

2 Likes

the parallel version requires a JobIndex how can i get it from an IJobParallelFor ?

You can just use index. All you need is a value that would be unique across threads.

3 Likes

i got it :slight_smile:
Thanks!!