forked from Misaki/GhostEngine
Improve the usability of Result<T, E> and add new job schedule method to EntityQuery.
Added implicate conversion to Result<T, E> and RefResult<T, E>; Added new ScheduleChunkParallel in EntityQuery; Remove Ghost.SparseEntity from solution file. It's now completlty replaced by Ghost.Entities;
This commit is contained in:
87
Ghost.Entities/EntityQuery.JobChunk.cs
Normal file
87
Ghost.Entities/EntityQuery.JobChunk.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using Ghost.Core;
|
||||
using Misaki.HighPerformance.Jobs;
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Ghost.Entities;
|
||||
|
||||
public interface IJobChunk
|
||||
{
|
||||
void Execute(ChunkView view, int threadIndex);
|
||||
}
|
||||
|
||||
internal unsafe struct ChunkInfo
|
||||
{
|
||||
public Chunk* pChunk;
|
||||
public Archetype* pArchetype;
|
||||
}
|
||||
|
||||
internal unsafe struct JobChunkBatch<TJob> : IJobParallelFor
|
||||
where TJob : unmanaged, IJobChunk
|
||||
{
|
||||
|
||||
public TJob userJob;
|
||||
public ReadOnlyUnsafeCollection<ChunkInfo> chunkInfos;
|
||||
|
||||
public void Execute(int loopIndex, int threadIndex)
|
||||
{
|
||||
var info = chunkInfos[loopIndex];
|
||||
var view = new ChunkView(in *info.pArchetype, in *info.pChunk);
|
||||
|
||||
userJob.Execute(view, threadIndex);
|
||||
}
|
||||
}
|
||||
|
||||
internal struct DisposeJobChunk : IJob
|
||||
{
|
||||
public UnsafeList<ChunkInfo> list;
|
||||
|
||||
public void Execute(int threadIndex)
|
||||
{
|
||||
list.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe partial struct EntityQuery
|
||||
{
|
||||
public JobHandle ScheduleChunkParallel<TJob>(TJob job, int batchSize, JobHandle dependency)
|
||||
where TJob : unmanaged, IJobChunk
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
|
||||
var chunkInfos = new UnsafeList<ChunkInfo>(_matchingArchetypes.Count * 2, JobScheduler.TempAllocatorHandle);
|
||||
|
||||
foreach (var archID in _matchingArchetypes)
|
||||
{
|
||||
ref var arch = ref world.GetArchetypeReference(archID);
|
||||
|
||||
for (int i = 0; i < arch.ChunkCount; i++)
|
||||
{
|
||||
var pChunk = (Chunk*)arch._chunks.GetUnsafePtr() + i;
|
||||
|
||||
chunkInfos.Add(new ChunkInfo
|
||||
{
|
||||
pArchetype = (Archetype*)Unsafe.AsPointer(ref arch),
|
||||
pChunk = pChunk
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var batchJob = new JobChunkBatch<TJob>
|
||||
{
|
||||
userJob = job,
|
||||
chunkInfos = chunkInfos.AsReadOnly()
|
||||
};
|
||||
|
||||
var handle = world.JobScheduler.ScheduleParallel(ref batchJob, chunkInfos.Count, batchSize, dependency);
|
||||
|
||||
var disposeJob = new DisposeJobChunk
|
||||
{
|
||||
list = chunkInfos
|
||||
};
|
||||
|
||||
world.JobScheduler.Schedule(ref disposeJob, handle);
|
||||
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user