예제 #1
0
        public void *GetUnsafePtr()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckExistsAndThrow(m_Safety);
#endif
            return(m_Ptr);
        }
예제 #2
0
        public void TestNestedDeallocateOnJobCompletion()
        {
            var tempNativeArray = new NativeArray <int>(10, Allocator.TempJob);
            var outNativeArray  = new NativeArray <int>(10, Allocator.TempJob);

            for (int i = 0; i < 10; i++)
            {
                tempNativeArray[i] = i;
            }

            var job = new TestNestedDeallocate
            {
                nested = new NestedDeallocateStruct()
                {
                    input = tempNativeArray
                },
                output = outNativeArray
            };

            var handle = job.Schedule();

            handle.Complete();

            outNativeArray.Dispose();

            // Ensure released safety handle indicating invalid buffer
            Assert.Throws <InvalidOperationException>(() => { AtomicSafetyHandle.CheckExistsAndThrow(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(tempNativeArray)); });
            Assert.Throws <InvalidOperationException>(() => { AtomicSafetyHandle.CheckExistsAndThrow(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(job.nested.input)); });
        }
예제 #3
0
        private WorldUnmanagedImpl *GetImpl()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckExistsAndThrow(m_Safety);
#endif
            return(m_Impl);
        }
예제 #4
0
        public void Retain()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckExistsAndThrow(m_Safety);
#endif
            var header = (BlobAssetHeader *)m_Ptr;
            header -= 1;
            Interlocked.Increment(ref header->Refcount);
        }
예제 #5
0
        public void ReleaseShouldThrow()
        {
            AtomicSafetyHandle handle = AtomicSafetyHandle.Create();

            AtomicSafetyHandle.Release(handle);
            Assert.Throws <InvalidOperationException>(() => AtomicSafetyHandle.CheckReadAndThrow(handle));
            Assert.Throws <InvalidOperationException>(() => AtomicSafetyHandle.CheckWriteAndThrow(handle));
            Assert.Throws <InvalidOperationException>(() => AtomicSafetyHandle.CheckExistsAndThrow(handle));
        }
        internal void Validate()
        {
            if (m_Ptr.ToInt64() == 0)
            {
                throw new InvalidOperationException($"The {nameof(ScriptableRenderContext)} instance is invalid. This can happen if you construct an instance using the default constructor.");
            }

            try
            {
                AtomicSafetyHandle.CheckExistsAndThrow(m_Safety);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"The {nameof(ScriptableRenderContext)} instance is no longer valid. This can happen if you re-use it across multiple frames.", e);
            }
        }
예제 #7
0
        internal void Validate()
        {
            if (ptr == IntPtr.Zero)
            {
                throw new InvalidOperationException($"The {nameof(CullingResults)} instance is invalid. This can happen if you construct an instance using the default constructor.");
            }

            try
            {
                AtomicSafetyHandle.CheckExistsAndThrow(m_Safety);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"The {nameof(CullingResults)} instance is no longer valid. This can happen if you re-use it across multiple frames.", e);
            }
        }
        /// <summary>
        /// Ends an exclusive entity transaction.
        /// </summary>
        /// <seealso cref="ExclusiveEntityTransaction"/>
        /// <seealso cref="BeginExclusiveEntityTransaction()"/>
        public void EndExclusiveEntityTransaction()
        {
        #if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (m_IsInExclusiveTransaction == 1)
            {
                throw new InvalidOperationException("Transactions can only be ended from the main thread");
            }
            AtomicSafetyHandle.CheckExistsAndThrow(m_Safety);
        #endif

            m_EntityDataAccess->DependencyManager->PreEndExclusiveTransaction();
        #if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
        #endif
            m_EntityDataAccess->DependencyManager->EndExclusiveTransaction();
            m_EntityDataAccess->m_IsInExclusiveTransaction = 0;
        }
예제 #9
0
        /// <summary>
        /// Provides a NativeArray that you can pass into a job whose contents can be modified by a previous job.
        /// </summary>
        /// <remarks>Pass a deferred array to a job when the list is populated or modified by a previous job. Using a
        /// deferred array allows you to schedule both jobs at the same time. (Without a deferred array, you would
        /// have to wait for the results of the first job before you scheduling the second.)</remarks>
        /// <returns>A [NativeArray](https://docs.unity3d.com/ScriptReference/Unity.Collections.NativeArray_1.html) that
        /// can be passed to one job as a "promise" that is fulfilled by a previous job.</returns>
        /// <example>
        /// The following example populates a list with integers in one job and passes that data to a second job as
        /// a deferred array. If you tried to pass the list directly to the second job, that job would get the contents
        /// of the list at the time you schedule the job and would not see any modifications made to the list by the
        /// first job.
        /// <code>
        /// using UnityEngine;
        /// using Unity.Jobs;
        /// using Unity.Collections;
        ///
        /// public class DeferredArraySum : MonoBehaviour
        ///{
        ///    public struct ListPopulatorJob : IJob
        ///    {
        ///        public NativeList&lt;int&gt; list;
        ///
        ///        public void Execute()
        ///        {
        ///            for (int i = list.Length; i &lt; list.Capacity; i++)
        ///            {
        ///                list.Add(i);
        ///            }
        ///        }
        ///    }
        ///
        ///    public struct ArraySummerJob : IJob
        ///    {
        ///        [ReadOnly] public NativeArray&lt;int&gt; deferredArray;
        ///        public NativeArray&lt;int&gt; sum;
        ///
        ///        public void Execute()
        ///        {
        ///            sum[0] = 0;
        ///            for (int i = 0; i &lt; deferredArray.Length; i++)
        ///            {
        ///                sum[0] += deferredArray[i];
        ///            }
        ///        }
        ///    }
        ///
        ///    void Start()
        ///    {
        ///        var deferredList = new NativeList&lt;int&gt;(100, Allocator.TempJob);
        ///
        ///        var populateJob = new ListPopulatorJob()
        ///        {
        ///            list = deferredList
        ///        };
        ///
        ///        var output = new NativeArray&lt;int&gt;(1, Allocator.TempJob);
        ///        var sumJob = new ArraySummerJob()
        ///        {
        ///            deferredArray = deferredList.AsDeferredJobArray(),
        ///            sum = output
        ///        };
        ///
        ///        var populateJobHandle = populateJob.Schedule();
        ///        var sumJobHandle = sumJob.Schedule(populateJobHandle);
        ///
        ///        sumJobHandle.Complete();
        ///
        ///        Debug.Log("Result: " + output[0]);
        ///
        ///        deferredList.Dispose();
        ///        output.Dispose();
        ///    }
        /// }
        /// </code>
        /// </example>
        public unsafe NativeArray <T> AsDeferredJobArray()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckExistsAndThrow(m_Safety);
#endif
            byte *buffer = (byte *)m_ListData;
            // We use the first bit of the pointer to infer that the array is in list mode
            // Thus the job scheduling code will need to patch it.
            buffer += 1;
            var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(buffer, 0, Allocator.Invalid);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, m_Safety);
#endif

            return(array);
        }
        internal void Validate()
        {
            bool flag = this.ptr == IntPtr.Zero;

            if (flag)
            {
                throw new InvalidOperationException("The CullingResults instance is invalid. This can happen if you construct an instance using the default constructor.");
            }
            try
            {
                AtomicSafetyHandle.CheckExistsAndThrow(this.m_Safety);
            }
            catch (Exception innerException)
            {
                throw new InvalidOperationException("The CullingResults instance is no longer valid. This can happen if you re-use it across multiple frames.", innerException);
            }
        }
        internal void Validate()
        {
            bool flag = this.m_Ptr.ToInt64() == 0L;

            if (flag)
            {
                throw new InvalidOperationException("The ScriptableRenderContext instance is invalid. This can happen if you construct an instance using the default constructor.");
            }
            try
            {
                AtomicSafetyHandle.CheckExistsAndThrow(this.m_Safety);
            }
            catch (Exception innerException)
            {
                throw new InvalidOperationException("The ScriptableRenderContext instance is no longer valid. This can happen if you re-use it across multiple frames.", innerException);
            }
        }
예제 #12
0
        public void Release()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AtomicSafetyHandle.CheckExistsAndThrow(m_Safety);
#endif

            var header = (BlobAssetHeader *)m_Ptr;
            header -= 1;

            if (Interlocked.Decrement(ref header->Refcount) == 0)
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                AtomicSafetyHandle.Release(m_Safety);
#endif

                UnsafeUtility.Free(header, header->Allocator);
                m_Ptr = null;
            }
        }
예제 #13
0
        public void TestJobProducerCleansUp()
        {
            var tempNativeArray  = new NativeArray <int>(10, Allocator.TempJob);
            var tempNativeArray2 = new NativeArray <byte>(16, Allocator.TempJob);

            var job = new TestJobProducerJob
            {
                jobStructData = tempNativeArray,
            };

            var handle = job.ScheduleTest(tempNativeArray2);

            handle.Complete();

            // Check job data
            Assert.Throws <InvalidOperationException>(() => { AtomicSafetyHandle.CheckExistsAndThrow(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(tempNativeArray)); });
            Assert.Throws <InvalidOperationException>(() => { AtomicSafetyHandle.CheckExistsAndThrow(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(job.jobStructData)); });
            // Check job producer
            Assert.Throws <InvalidOperationException>(() => { AtomicSafetyHandle.CheckExistsAndThrow(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(tempNativeArray2)); });
        }
        public void ReleaseShouldThrow()
        {
            AtomicSafetyHandle handle = AtomicSafetyHandle.Create();

            AtomicSafetyHandle.Release(handle);
#if UNITY_2020_2_OR_NEWER
            Assert.Throws <ObjectDisposedException>(
#else
            Assert.Throws <InvalidOperationException>(
#endif
                () => AtomicSafetyHandle.CheckReadAndThrow(handle));

#if UNITY_2020_2_OR_NEWER
            Assert.Throws <ObjectDisposedException>(
#else
            Assert.Throws <InvalidOperationException>(
#endif
                () => AtomicSafetyHandle.CheckWriteAndThrow(handle));

            Assert.Throws <InvalidOperationException>(() => AtomicSafetyHandle.CheckExistsAndThrow(handle));
        }