static unsafe JobHandle Schedule <T>(ref T jobData, IntPtr arrayLengthPtr, int innerloopBatchCount, JobHandle dependsOn) where T : struct, IJobParallelForDefer { #if UNITY_SINGLETHREADED_JOBS var arrayLength = UnsafeUtility.AsRef <int>(arrayLengthPtr.ToPointer()); for (var i = 0; i < arrayLength; ++i) { jobData.Execute(i); } DoDeallocateOnJobCompletion(jobData); return(new JobHandle()); #else // Protect against garbage collection if (!JobStructDefer <T> .ExecuteHandle.IsAllocated) { JobStructDefer <T> .ExecuteDelegate = JobStructDefer <T> .Execute; JobStructDefer <T> .ExecuteHandle = GCHandle.Alloc(JobStructDefer <T> .ExecuteDelegate); JobStructDefer <T> .ExecuteFunctionPtr = Marshal.GetFunctionPointerForDelegate(JobStructDefer <T> .ExecuteDelegate); } // Protect against garbage collection if (!JobStructDefer <T> .CleanupHandle.IsAllocated) { JobStructDefer <T> .CleanupDelegate = JobStructDefer <T> .Cleanup; JobStructDefer <T> .CleanupHandle = GCHandle.Alloc(JobStructDefer <T> .CleanupDelegate); JobStructDefer <T> .CleanupFunctionPtr = Marshal.GetFunctionPointerForDelegate(JobStructDefer <T> .CleanupDelegate); } var jobFunctionPtr = JobStructDefer <T> .ExecuteFunctionPtr; var completionFuncPtr = JobStructDefer <T> .CleanupFunctionPtr; var jobStruct = new JobStructDefer <T>() { JobData = jobData, ArrayLengthPtr = arrayLengthPtr, }; var jobDataPtr = UnsafeUtility.Malloc(UnsafeUtility.SizeOf <JobStructDefer <T> >(), UnsafeUtility.AlignOf <JobStructDefer <T> >(), Allocator.TempJob); UnsafeUtility.CopyStructureToPtr(ref jobStruct, jobDataPtr); return(JobsUtility.ScheduleJobForEach(jobFunctionPtr, completionFuncPtr, new IntPtr(jobDataPtr), JobsUtility.JobQueueThreadCount, innerloopBatchCount, dependsOn)); #endif }
public static unsafe JobHandle ScheduleBatch <T>(this T jobData, int arrayLength, int minIndicesPerJobCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelForBatch { #if UNITY_AVOID_REFLECTION // Protect against garbage collection if (!ParallelForBatchJobStruct <T> .ExecuteHandle.IsAllocated) { ParallelForBatchJobStruct <T> .ExecuteDelegate = ParallelForBatchJobStruct <T> .Execute; ParallelForBatchJobStruct <T> .ExecuteHandle = GCHandle.Alloc(ParallelForBatchJobStruct <T> .ExecuteDelegate); ParallelForBatchJobStruct <T> .ExecuteFunctionPtr = Marshal.GetFunctionPointerForDelegate(ParallelForBatchJobStruct <T> .ExecuteDelegate); } // Protect against garbage collection if (!ParallelForBatchJobStruct <T> .CleanupHandle.IsAllocated) { ParallelForBatchJobStruct <T> .CleanupDelegate = ParallelForBatchJobStruct <T> .Cleanup; ParallelForBatchJobStruct <T> .CleanupHandle = GCHandle.Alloc(ParallelForBatchJobStruct <T> .CleanupDelegate); ParallelForBatchJobStruct <T> .CleanupFunctionPtr = Marshal.GetFunctionPointerForDelegate(ParallelForBatchJobStruct <T> .CleanupDelegate); } var jobFunctionPtr = ParallelForBatchJobStruct <T> .ExecuteFunctionPtr; var completionFuncPtr = ParallelForBatchJobStruct <T> .CleanupFunctionPtr; var jobStruct = new ParallelForBatchJobStruct <T>() { JobData = jobData, Ranges = new JobRanges() { ArrayLength = arrayLength, IndicesPerPhase = JobsUtility.GetDefaultIndicesPerPhase(arrayLength) }, }; var jobDataPtr = UnsafeUtility.Malloc(UnsafeUtility.SizeOf <ParallelForBatchJobStruct <T> >(), UnsafeUtility.AlignOf <ParallelForBatchJobStruct <T> >(), Allocator.TempJob); UnsafeUtility.CopyStructureToPtr(ref jobStruct, jobDataPtr); return(JobsUtility.ScheduleJobForEach(jobFunctionPtr, completionFuncPtr, new IntPtr(jobDataPtr), arrayLength, minIndicesPerJobCount, dependsOn)); #else var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), ParallelForBatchJobStruct <T> .Initialize(), dependsOn, ScheduleMode.Batched); return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, minIndicesPerJobCount)); #endif }