public static unsafe void RunJobChunk <T>(ref T jobData, EntityQuery query, JobChunkRunWithoutJobSystemDelegate functionPointer) where T : unmanaged, IJobChunk, IJobBase { var myIterator = query.GetArchetypeChunkIterator(); try { query._GetImpl()->_Access->DependencyManager->IsInForEachDisallowStructuralChange++; var managedJobDataPtr = UnsafeUtility.AddressOf(ref jobData); var unmanagedSize = jobData.GetUnmanagedJobSize_Gen(); if (unmanagedSize != -1) { const int kAlignment = 16; int alignedSize = (unmanagedSize + kAlignment - 1) & ~(kAlignment - 1); byte * unmanagedJobData = stackalloc byte[alignedSize]; byte * alignedUnmanagedJobData = (byte *)((UInt64)(unmanagedJobData + kAlignment - 1) & ~(UInt64)(kAlignment - 1)); // DOTS Runtime job marshalling code assumes the job is wrapped so create the wrapper and assign the jobData JobChunkExtensions.JobChunkWrapper <T> jobChunkWrapper = default; jobChunkWrapper.JobData = jobData; byte *jobChunkDataPtr = (byte *)UnsafeUtility.AddressOf(ref jobChunkWrapper); byte *dst = (byte *)alignedUnmanagedJobData; byte *src = (byte *)jobChunkDataPtr; var marshalToBurstFnPtr = JobMarshalFnLookup <T> .GetMarshalToBurstFn(); UnsafeUtility.EnterTempScope(); UnsafeUtility.CallFunctionPtr_pp(marshalToBurstFnPtr.ToPointer(), dst, src); // Since we are running inline, normally the outer job scheduling code would // reference jobWrapper.Data however we can't do that since if we are in this code it means // we are dealing with a job/jobwrapper that is burst compiled and is non-blittable. Thus any // type-safe offset we calculate here will be based on the managed data layout which is not useful. // Instead we can at least know that for a sequential layout (which is what we know we must be using // since we are burst compiled) our JobChunkData contains a safety field as its first member. Skipping over this will // provide the necessary offset to jobChunkData.Data var DataOffset = UnsafeUtility.SizeOf <JobChunkExtensions.EntitySafetyHandle>(); Assertions.Assert.AreEqual(jobChunkWrapper.safety.GetType(), typeof(JobChunkExtensions.EntitySafetyHandle)); functionPointer(&myIterator, alignedUnmanagedJobData + DataOffset); // Since Run can capture locals for write back, we must write back the marshalled jobData after the job executes var marshalFromBurstFnPtr = JobMarshalFnLookup <T> .GetMarshalFromBurstFn(); UnsafeUtility.CallFunctionPtr_pp(marshalFromBurstFnPtr.ToPointer(), src, dst); UnsafeUtility.ExitTempScope(); jobData = jobChunkWrapper.JobData; } else { functionPointer(&myIterator, managedJobDataPtr); } } finally { query._GetImpl()->_Access->DependencyManager->IsInForEachDisallowStructuralChange--; } }
public static unsafe void RunJobChunk <T>(ref T jobData, EntityQuery query, JobChunkRunWithoutJobSystemDelegate functionPointer) where T : unmanaged, IJobChunk { var myIterator = query.GetArchetypeChunkIterator(); #if ENABLE_UNITY_COLLECTIONS_CHECKS var access = query._GetImpl()->_Access; try { access->DependencyManager->IsInForEachDisallowStructuralChange++; functionPointer(&myIterator, UnsafeUtility.AddressOf(ref jobData)); } finally { access->DependencyManager->IsInForEachDisallowStructuralChange--; } #else functionPointer(&myIterator, UnsafeUtility.AddressOf(ref jobData)); #endif }
public static unsafe void UnsafeRunJobEntityBatch(void *jobPtr, EntityQuery query, JobChunkRunWithoutJobSystemDelegate functionPointer) { var myIterator = query.GetArchetypeChunkIterator(); #if ENABLE_UNITY_COLLECTIONS_CHECKS var access = query._GetImpl()->_Access; try { access->DependencyManager->IsInForEachDisallowStructuralChange++; functionPointer(&myIterator, jobPtr); } finally { access->DependencyManager->IsInForEachDisallowStructuralChange--; } #else functionPointer(&myIterator, jobPtr); #endif }
/// <summary> /// Runs the job without using the jobs API. /// </summary> /// <param name="jobData">The job to execute.</param> /// <param name="query">The EntityQuery to run over.</param> /// <typeparam name="T">The specific IJobEntityBatch implementation type.</typeparam> unsafe public static void RunWithoutJobs <T>(ref T jobData, EntityQuery query) where T : struct, IJobEntityBatch { var myIterator = query.GetArchetypeChunkIterator(); #if ENABLE_UNITY_COLLECTIONS_CHECKS var access = query._GetImpl()->_Access; try { access->DependencyManager->IsInForEachDisallowStructuralChange++; RunWithoutJobsInternal(ref jobData, ref myIterator); } finally { access->DependencyManager->IsInForEachDisallowStructuralChange--; } #else RunWithoutJobsInternal(ref jobData, ref myIterator); #endif }
public static T[] ToComponentArray <T>(this EntityQuery group) where T : Component { int entityCount = group.CalculateEntityCount(); var arr = new T[entityCount]; var iterator = group.GetArchetypeChunkIterator(); var indexInEntityQuery = group.GetIndexInEntityQuery(TypeManager.GetTypeIndex <T>()); var entityCounter = 0; while (iterator.MoveNext()) { var chunk = iterator.CurrentArchetypeChunk; for (int entityIndex = 0; entityIndex < chunk.Count; ++entityIndex) { arr[entityCounter++] = (T)iterator.GetManagedObject(group.ManagedComponentStore, indexInEntityQuery, entityIndex); } } return(arr); }