Esempio n. 1
0
        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--;
            }
        }
Esempio n. 2
0
        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
        }
Esempio n. 3
0
        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);
        }