// Magica Cloth.
// Copyright (c) MagicaSoft, 2020-2022.
// https://magicasoft.jp
using Unity.Collections;
#if UNITY_2020_1_OR_NEWER
using Unity.Collections.LowLevel.Unsafe;
#elif MAGICACLOTH_UNSAFE
using Unity.Collections.LowLevel.Unsafe;
#else
using System.Runtime.CompilerServices;
#endif
namespace MagicaCloth
{
///
/// NativeArray拡張メソッド
///
public static class NativeArrayExtension
{
#if !MAGICACLOTH_UNSAFE
///
/// 高速なCopyTo
/// nativeArrayのstartIndexからのデータをarrayに書き出す
///
///
///
///
public static void CopyToFast(this NativeArray nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct
{
#if UNITY_2020_1_OR_NEWER
T[] ar = UnsafeUtility.As(ref array);
#else
T[] ar = Unsafe.As(ref array);
#endif
NativeArray.Copy(nativeArray, startIndex, ar, 0, array.Length);
}
///
/// 高速なCopyTo
/// nativeArrayのstartIndexからのデータをnativeArrayに書き出す
///
///
///
///
public static void CopyToFast(this NativeArray nativeArray, int startIndex, NativeArray array) where T : struct
{
NativeArray.Copy(nativeArray, startIndex, array, 0, array.Length);
}
///
/// 高速なCopyTo
/// nativeArrayのsourceIndexからcountのデータをdestinationIndexにコピーする
///
///
///
///
///
///
public static void CopyBlock(this NativeArray nativeArray, int sourceIndex, int destinationIndex, int count) where T : struct
{
NativeArray.Copy(nativeArray, sourceIndex, nativeArray, destinationIndex, count);
}
///
/// 高速なCopyFrom
///
///
///
///
public static void CopyFromFast(this NativeArray nativeArray, NativeArray array) where T : struct
{
NativeArray.Copy(array, 0, nativeArray, 0, array.Length);
}
///
/// 高速なCopyFrom
/// arrayの内容をnativeArrayのstartIndex位置にコピーする
///
///
///
///
public static void CopyFromFast(this NativeArray nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct
{
#if UNITY_2020_1_OR_NEWER
T[] ar = UnsafeUtility.As(ref array);
#else
T[] ar = Unsafe.As(ref array);
#endif
NativeArray.Copy(ar, 0, nativeArray, startIndex, array.Length);
}
///
/// 高速なデータ書き込み
///
///
///
///
///
///
public static void SetValue(this NativeArray nativeArray, int startIndex, int count, T value) where T : struct
{
for (int i = 0; i < count; i++, startIndex++)
{
nativeArray[startIndex] = value;
}
}
#else
///
/// 高速なCopyTo
///
///
///
///
public static unsafe void CopyToFast(this NativeArray nativeArray, T2[] array) where T : struct where T2 : struct
{
int byteLength = nativeArray.Length * UnsafeUtility.SizeOf();
void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]);
void* nativeBuffer = nativeArray.GetUnsafePtr();
UnsafeUtility.MemCpy(managedBuffer, nativeBuffer, byteLength);
}
///
/// 高速なCopyTo
/// nativeArrayのstartIndexからのデータをarrayに書き出す
///
///
///
///
public static unsafe void CopyToFast(this NativeArray nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct
{
int stride = UnsafeUtility.SizeOf();
int byteLength = array.Length * stride;
void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]);
byte* p = (byte*)nativeArray.GetUnsafePtr();
p += startIndex * stride;
UnsafeUtility.MemCpy(managedBuffer, (void*)p, byteLength);
}
///
/// 高速なCopyTo
/// nativeArrayのstartIndexからのデータをnativeArrayに書き出す
///
///
///
///
public static unsafe void CopyToFast(this NativeArray nativeArray, int startIndex, NativeArray array) where T : struct
{
int stride = UnsafeUtility.SizeOf();
int byteLength = array.Length * stride;
byte* p = (byte*)nativeArray.GetUnsafePtr();
p += startIndex * stride;
UnsafeUtility.MemCpy(array.GetUnsafePtr(), (void*)p, byteLength);
}
///
/// 高速なCopyTo
/// nativeArrayのsourceIndexからcountのデータをdestinationIndexにコピーする
///
///
///
///
///
///
public static unsafe void CopyBlock(this NativeArray nativeArray, int sourceIndex, int destinationIndex, int count) where T : struct
{
int stride = UnsafeUtility.SizeOf();
int byteLength = count * stride;
byte* p = (byte*)nativeArray.GetUnsafePtr();
UnsafeUtility.MemCpy((void*)(p + destinationIndex * stride), (void*)(p + sourceIndex * stride), byteLength);
}
///
/// 高速なCopyFrom
///
///
///
///
public static unsafe void CopyFromFast(this NativeArray nativeArray, T2[] array) where T : struct where T2 : struct
{
int byteLength = nativeArray.Length * UnsafeUtility.SizeOf();
void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]);
void* nativeBuffer = nativeArray.GetUnsafePtr();
UnsafeUtility.MemCpy(nativeBuffer, managedBuffer, byteLength);
}
///
/// 高速なCopyFrom
///
///
///
///
public static unsafe void CopyFromFast(this NativeArray nativeArray, NativeArray array) where T : struct
{
int byteLength = array.Length * UnsafeUtility.SizeOf();
void* managedBuffer = array.GetUnsafePtr();
void* nativeBuffer = nativeArray.GetUnsafePtr();
UnsafeUtility.MemCpy(nativeBuffer, managedBuffer, byteLength);
}
///
/// 高速なCopyFrom
/// arrayの内容をnativeArrayのstartIndex位置にコピーする
///
///
///
///
public static unsafe void CopyFromFast(this NativeArray nativeArray, int startIndex, T2[] array) where T : struct where T2 : struct
{
int stride = UnsafeUtility.SizeOf();
int byteLength = array.Length * stride;
void* managedBuffer = UnsafeUtility.AddressOf(ref array[0]);
byte* p = (byte*)nativeArray.GetUnsafePtr();
p += startIndex * stride;
UnsafeUtility.MemCpy((void*)p, managedBuffer, byteLength);
}
///
/// 高速なデータ書き込み
///
///
///
///
///
///
public static unsafe void SetValue(this NativeArray nativeArray, int startIndex, int count, T value) where T : struct
{
void* nativeBuffer = nativeArray.GetUnsafePtr();
for (int i = 0; i < count; i++)
{
UnsafeUtility.WriteArrayElement(nativeBuffer, startIndex + i, value);
}
}
#endif
}
}