// SPDX-FileCopyrightText: 2025 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
{
///
/// Wraps a managed TIn[] in a NativeArray<TOut>without copying memory.
/// Use for internal development instead.
///
/// Type of items in an input array.
/// Type of items in output NativeArray (might differ from input type TIn).
[Obsolete("This is going to be removed from the public API in a future release. " +
"For internal development, refer to ReadOnlyNativeArrayFromManagedArray.")]
public sealed 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()
{
if (m_Pinned)
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckDeallocateAndThrow(m_SafetyHandle);
AtomicSafetyHandle.Release(m_SafetyHandle);
#endif
m_BufferHandle.Free();
}
}
}
}