273 lines
8.8 KiB
C#
273 lines
8.8 KiB
C#
|
using System;
|
||
|
using NUnit.Framework;
|
||
|
using Unity.Burst;
|
||
|
using Unity.Collections;
|
||
|
using Unity.Collections.Tests;
|
||
|
using Unity.Jobs;
|
||
|
using Unity.Collections.LowLevel.Unsafe;
|
||
|
|
||
|
internal class NativeArrayTests : CollectionsTestFixture
|
||
|
{
|
||
|
[Test]
|
||
|
public unsafe void NativeArray_IndexOf_Int()
|
||
|
{
|
||
|
var container = new NativeArray<int>(10, Allocator.Persistent);
|
||
|
container[0] = 123;
|
||
|
container[1] = 789;
|
||
|
|
||
|
bool r0 = false, r1 = false, r2 = false;
|
||
|
|
||
|
GCAllocRecorder.ValidateNoGCAllocs(() =>
|
||
|
{
|
||
|
r0 = -1 != container.IndexOf(456);
|
||
|
r1 = container.Contains(123);
|
||
|
r2 = container.Contains(789);
|
||
|
});
|
||
|
|
||
|
Assert.False(r0);
|
||
|
Assert.False(-1 != NativeArrayExtensions.IndexOf<int, int>(container.GetUnsafePtr(), container.Length, 456));
|
||
|
|
||
|
Assert.True(r1);
|
||
|
Assert.True(NativeArrayExtensions.Contains<int, int>(container.GetUnsafePtr(), container.Length, 123));
|
||
|
|
||
|
Assert.True(r2);
|
||
|
Assert.True(NativeArrayExtensions.Contains<int, int>(container.GetUnsafePtr(), container.Length, 789));
|
||
|
|
||
|
container.Dispose();
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public unsafe void NativeArray_IndexOf_FixedString128()
|
||
|
{
|
||
|
var container = new NativeArray<FixedString128Bytes>(10, Allocator.Persistent);
|
||
|
container[0] = new FixedString128Bytes("123");
|
||
|
container[1] = new FixedString128Bytes("789");
|
||
|
|
||
|
bool r0 = false, r1 = false, r2 = false;
|
||
|
|
||
|
GCAllocRecorder.ValidateNoGCAllocs(() =>
|
||
|
{
|
||
|
r0 = -1 != container.IndexOf(new FixedString128Bytes("456"));
|
||
|
r1 = container.Contains(new FixedString128Bytes("123"));
|
||
|
r2 = container.Contains(new FixedString128Bytes("789"));
|
||
|
});
|
||
|
|
||
|
Assert.False(r0);
|
||
|
Assert.False(-1 != NativeArrayExtensions.IndexOf<FixedString128Bytes, FixedString128Bytes>(container.GetUnsafePtr(), container.Length, new FixedString128Bytes("456")));
|
||
|
|
||
|
Assert.True(r1);
|
||
|
Assert.True(NativeArrayExtensions.Contains<FixedString128Bytes, FixedString128Bytes>(container.GetUnsafePtr(), container.Length, new FixedString128Bytes("123")));
|
||
|
|
||
|
Assert.True(r2);
|
||
|
Assert.True(NativeArrayExtensions.Contains<FixedString128Bytes, FixedString128Bytes>(container.GetUnsafePtr(), container.Length, new FixedString128Bytes("789")));
|
||
|
|
||
|
container.Dispose();
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void NativeArray_DisposeJob()
|
||
|
{
|
||
|
var container = new NativeArray<int>(1, Allocator.Persistent);
|
||
|
Assert.True(container.IsCreated);
|
||
|
Assert.DoesNotThrow(() => { container[0] = 1; });
|
||
|
|
||
|
var disposeJob = container.Dispose(default);
|
||
|
Assert.False(container.IsCreated);
|
||
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
||
|
Assert.Throws<ObjectDisposedException>(
|
||
|
() => { container[0] = 2; });
|
||
|
#endif
|
||
|
|
||
|
disposeJob.Complete();
|
||
|
}
|
||
|
|
||
|
[BurstCompile(CompileSynchronously = true)]
|
||
|
struct NativeArrayPokeJob : IJob
|
||
|
{
|
||
|
NativeArray<int> array;
|
||
|
|
||
|
public NativeArrayPokeJob(NativeArray<int> array) { this.array = array; }
|
||
|
|
||
|
public void Execute()
|
||
|
{
|
||
|
array[0] = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
[TestRequiresCollectionChecks]
|
||
|
public void NativeArray_DisposeJobWithMissingDependencyThrows()
|
||
|
{
|
||
|
var array = new NativeArray<int>(1, Allocator.Persistent);
|
||
|
var deps = new NativeArrayPokeJob(array).Schedule();
|
||
|
Assert.Throws<InvalidOperationException>(() => { array.Dispose(default); });
|
||
|
deps.Complete();
|
||
|
array.Dispose();
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
[TestRequiresCollectionChecks]
|
||
|
public void NativeArray_DisposeJobCantBeScheduled()
|
||
|
{
|
||
|
var array = new NativeArray<int>(1, Allocator.Persistent);
|
||
|
var deps = array.Dispose(default);
|
||
|
Assert.Throws<InvalidOperationException>(() => { new NativeArrayPokeJob(array).Schedule(deps); });
|
||
|
deps.Complete();
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
unsafe public void NativeArray_ConvertExistingDataToNativeArray()
|
||
|
{
|
||
|
AllocatorManager.Initialize();
|
||
|
var allocatorHelper = new AllocatorHelper<RewindableAllocator>(AllocatorManager.Persistent);
|
||
|
allocatorHelper.Allocator.Initialize(64 * 1024);
|
||
|
|
||
|
var nativeList = new NativeList<int>(allocatorHelper.Allocator.Handle);
|
||
|
for(int i = 0; i < 20; i++)
|
||
|
{
|
||
|
nativeList.Add(i);
|
||
|
}
|
||
|
|
||
|
var nativeArray = CollectionHelper.ConvertExistingDataToNativeArray<int>(nativeList.GetUnsafePtr(), nativeList.Length, allocatorHelper.Allocator.Handle);
|
||
|
|
||
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
||
|
var listSafety = NativeListUnsafeUtility.GetAtomicSafetyHandle(ref nativeList);
|
||
|
NativeArrayUnsafeUtility.SetAtomicSafetyHandle<int>(ref nativeArray, listSafety);
|
||
|
#endif
|
||
|
|
||
|
for (int i = 0; i < 20; i++)
|
||
|
{
|
||
|
Assert.AreEqual(nativeArray[i], i);
|
||
|
}
|
||
|
|
||
|
nativeArray.Dispose();
|
||
|
|
||
|
allocatorHelper.Allocator.Dispose();
|
||
|
allocatorHelper.Dispose();
|
||
|
AllocatorManager.Shutdown();
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
unsafe public void NativeArray_ConvertExistingDataToNativeArray_SetTempMemoryHandle()
|
||
|
{
|
||
|
var nativeList = new NativeList<int>(Allocator.Temp);
|
||
|
for (int i = 0; i < 20; i++)
|
||
|
{
|
||
|
nativeList.Add(i);
|
||
|
}
|
||
|
|
||
|
var nativeArray = CollectionHelper.ConvertExistingDataToNativeArray<int>(nativeList.GetUnsafePtr(), nativeList.Length, Allocator.Temp, true);
|
||
|
|
||
|
for (int i = 0; i < 20; i++)
|
||
|
{
|
||
|
Assert.AreEqual(nativeArray[i], i);
|
||
|
}
|
||
|
|
||
|
nativeArray.Dispose();
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
unsafe public void NativeArray_ConvertExistingNativeListToNativeArray()
|
||
|
{
|
||
|
AllocatorManager.Initialize();
|
||
|
var allocatorHelper = new AllocatorHelper<RewindableAllocator>(AllocatorManager.Persistent);
|
||
|
allocatorHelper.Allocator.Initialize(64 * 1024);
|
||
|
|
||
|
var nativeList = new NativeList<int>(allocatorHelper.Allocator.Handle);
|
||
|
for (int i = 0; i < 20; i++)
|
||
|
{
|
||
|
nativeList.Add(i);
|
||
|
}
|
||
|
|
||
|
var nativeArray = CollectionHelper.ConvertExistingNativeListToNativeArray<int>(ref nativeList, nativeList.Length, allocatorHelper.Allocator.Handle);
|
||
|
|
||
|
for (int i = 0; i < 20; i++)
|
||
|
{
|
||
|
Assert.AreEqual(nativeArray[i], i);
|
||
|
}
|
||
|
|
||
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
||
|
var listSafety = NativeListUnsafeUtility.GetAtomicSafetyHandle(ref nativeList);
|
||
|
var arraySafety = CollectionHelper.GetNativeArraySafetyHandle(ref nativeArray);
|
||
|
Assert.AreEqual(listSafety, arraySafety);
|
||
|
#endif
|
||
|
|
||
|
nativeArray.Dispose();
|
||
|
|
||
|
allocatorHelper.Allocator.Dispose();
|
||
|
allocatorHelper.Dispose();
|
||
|
AllocatorManager.Shutdown();
|
||
|
}
|
||
|
|
||
|
[Ignore("Wait for DOTS-7576 trunk PR in")]
|
||
|
[Test]
|
||
|
public void NativeArray_CustomAllocator_DisposeException()
|
||
|
{
|
||
|
AllocatorManager.Initialize();
|
||
|
var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
|
||
|
ref var allocator = ref allocatorHelper.Allocator;
|
||
|
allocator.Initialize();
|
||
|
|
||
|
var nativeArray = CollectionHelper.CreateNativeArray<int>(100, allocator.ToAllocator, NativeArrayOptions.UninitializedMemory);
|
||
|
nativeArray[0] = 0xFE;
|
||
|
|
||
|
var nativeList = new NativeList<int>(allocator.ToAllocator);
|
||
|
for (int i = 0; i < 50; i++)
|
||
|
{
|
||
|
nativeList.Add(i);
|
||
|
}
|
||
|
|
||
|
Assert.IsTrue(allocator.WasUsed);
|
||
|
|
||
|
Assert.Throws<InvalidOperationException>(() => nativeArray.Dispose());
|
||
|
|
||
|
CollectionHelper.Dispose(nativeArray);
|
||
|
nativeList.Dispose();
|
||
|
allocator.Dispose();
|
||
|
allocatorHelper.Dispose();
|
||
|
AllocatorManager.Shutdown();
|
||
|
}
|
||
|
|
||
|
public struct SimpleTestJob : IJob
|
||
|
{
|
||
|
public int ElementValue;
|
||
|
|
||
|
[WriteOnly]
|
||
|
public NativeArray<int> Result;
|
||
|
|
||
|
public void Execute()
|
||
|
{
|
||
|
for (int i = 0; i < Result.Length; ++i)
|
||
|
Result[i] = ElementValue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Ignore("Wait for DOTS-7576 trunk PR in")]
|
||
|
[Test]
|
||
|
public void NativeArray_CustomAllocator_DisposeHandleException()
|
||
|
{
|
||
|
AllocatorManager.Initialize();
|
||
|
var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
|
||
|
ref var allocator = ref allocatorHelper.Allocator;
|
||
|
allocator.Initialize();
|
||
|
|
||
|
var nativeArray = CollectionHelper.CreateNativeArray<int>(100, allocator.ToAllocator, NativeArrayOptions.UninitializedMemory);
|
||
|
|
||
|
SimpleTestJob job = new SimpleTestJob()
|
||
|
{
|
||
|
ElementValue = 0xFE,
|
||
|
Result = nativeArray
|
||
|
};
|
||
|
|
||
|
var jobHandle = job.Schedule();
|
||
|
jobHandle.Complete();
|
||
|
Assert.IsTrue(allocator.WasUsed);
|
||
|
Assert.Throws<InvalidOperationException>(() => nativeArray.Dispose(jobHandle));
|
||
|
|
||
|
CollectionHelper.Dispose(nativeArray);
|
||
|
allocator.Dispose();
|
||
|
allocatorHelper.Dispose();
|
||
|
AllocatorManager.Shutdown();
|
||
|
}
|
||
|
}
|