// SPDX-FileCopyrightText: 2024 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 using System; using System.Runtime.InteropServices; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using UnityEngine; namespace GLTFast.Export { /// /// Wraps a managed TIn[] in a NativeArray<TOut>without copying memory. /// /// Type of items in the input array. /// Type of items in output NativeArray (might differ from input type TIn). [Obsolete("This class is going to get sealed or removed from the public API in a future release.")] public class ManagedNativeArray : IDisposable where TIn : unmanaged where TOut : unmanaged { NativeArray m_NativeArray; GCHandle m_BufferHandle; #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle m_SafetyHandle; #endif readonly bool m_Pinned; /// /// Wraps a managed TIn[] in a NativeArray<TOut>without copying memory. /// /// The original TIn[] to convert into a NativeArray<TOut> public unsafe ManagedNativeArray(TIn[] original) { if (original != null) { m_BufferHandle = GCHandle.Alloc(original, GCHandleType.Pinned); fixed (void* bufferAddress = &original[0]) { m_NativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray(bufferAddress, original.Length, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS m_SafetyHandle = AtomicSafetyHandle.Create(); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(array: ref m_NativeArray, m_SafetyHandle); #endif } m_Pinned = true; } else { m_NativeArray = new NativeArray(); } } /// /// Points to the managed NativeArray<TOut>. /// public NativeArray nativeArray => m_NativeArray; /// /// Disposes the managed NativeArray<TOut>. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Disposes the managed NativeArray<TOut> and unpins the underlying managed array. /// /// Indicates whether the method call comes from a Dispose method (its value is true) /// or from a finalizer (its value is false). protected virtual void Dispose(bool disposing) { if (disposing && m_Pinned) { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckDeallocateAndThrow(m_SafetyHandle); AtomicSafetyHandle.Release(m_SafetyHandle); #endif m_BufferHandle.Free(); } } } }