public void *GetUnsafePtr() { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckExistsAndThrow(m_Safety); #endif return(m_Ptr); }
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)); }); }
private WorldUnmanagedImpl *GetImpl() { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckExistsAndThrow(m_Safety); #endif return(m_Impl); }
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); }
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); } }
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; }
/// <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<int> list; /// /// public void Execute() /// { /// for (int i = list.Length; i < list.Capacity; i++) /// { /// list.Add(i); /// } /// } /// } /// /// public struct ArraySummerJob : IJob /// { /// [ReadOnly] public NativeArray<int> deferredArray; /// public NativeArray<int> sum; /// /// public void Execute() /// { /// sum[0] = 0; /// for (int i = 0; i < deferredArray.Length; i++) /// { /// sum[0] += deferredArray[i]; /// } /// } /// } /// /// void Start() /// { /// var deferredList = new NativeList<int>(100, Allocator.TempJob); /// /// var populateJob = new ListPopulatorJob() /// { /// list = deferredList /// }; /// /// var output = new NativeArray<int>(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); } }
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; } }
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)); }