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:
2025-12-09 21:43:12 +09:00
parent 97d1118caa
commit 99c1a1980e
29 changed files with 646 additions and 553 deletions

View 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;
}
}