forked from mirror/DotRecast
added RcRentedArray (#41)
This commit is contained in:
parent
f1ecd37f4d
commit
675ca8ea4b
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace DotRecast.Core.Buffers
|
||||||
|
{
|
||||||
|
public static class RcRentedArray
|
||||||
|
{
|
||||||
|
public static RcRentedArray<T> RentDisposableArray<T>(int minimumLength)
|
||||||
|
{
|
||||||
|
var array = ArrayPool<T>.Shared.Rent(minimumLength);
|
||||||
|
return new RcRentedArray<T>(ArrayPool<T>.Shared, array, minimumLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RcRentedArray<T> : IDisposable
|
||||||
|
{
|
||||||
|
private ArrayPool<T> _owner;
|
||||||
|
private T[] _array;
|
||||||
|
private readonly RcAtomicInteger _disposed;
|
||||||
|
|
||||||
|
public int Length { get; }
|
||||||
|
|
||||||
|
internal RcRentedArray(ArrayPool<T> owner, T[] array, int length)
|
||||||
|
{
|
||||||
|
_owner = owner;
|
||||||
|
_array = array;
|
||||||
|
Length = length;
|
||||||
|
_disposed = new RcAtomicInteger(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T this[int index]
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
return _array[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
_array[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (1 != _disposed.IncrementAndGet())
|
||||||
|
return;
|
||||||
|
|
||||||
|
_owner?.Return(_array, true);
|
||||||
|
_array = null;
|
||||||
|
_owner = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -139,21 +139,12 @@ namespace DotRecast.Core.Collections
|
||||||
public T V126;
|
public T V126;
|
||||||
public T V127;
|
public T V127;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void ThrowExceptionIfIndexOutOfRange(int index)
|
|
||||||
{
|
|
||||||
if (0 > index || index >= Size)
|
|
||||||
{
|
|
||||||
throw new IndexOutOfRangeException($"{index}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public T this[int index]
|
public T this[int index]
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
return index switch
|
return index switch
|
||||||
{
|
{
|
||||||
|
@ -291,7 +282,7 @@ namespace DotRecast.Core.Collections
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,22 +27,12 @@ namespace DotRecast.Core.Collections
|
||||||
public T V14;
|
public T V14;
|
||||||
public T V15;
|
public T V15;
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void ThrowExceptionIfIndexOutOfRange(int index)
|
|
||||||
{
|
|
||||||
if (0 > index || index >= Size)
|
|
||||||
{
|
|
||||||
throw new IndexOutOfRangeException($"{index}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public T this[int index]
|
public T this[int index]
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
return index switch
|
return index switch
|
||||||
{
|
{
|
||||||
|
@ -68,7 +58,7 @@ namespace DotRecast.Core.Collections
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -267,21 +267,12 @@ namespace DotRecast.Core.Collections
|
||||||
public T V254;
|
public T V254;
|
||||||
public T V255;
|
public T V255;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void ThrowExceptionIfIndexOutOfRange(int index)
|
|
||||||
{
|
|
||||||
if (0 > index || index >= Size)
|
|
||||||
{
|
|
||||||
throw new IndexOutOfRangeException($"{index}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public T this[int index]
|
public T this[int index]
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
return index switch
|
return index switch
|
||||||
{
|
{
|
||||||
|
@ -547,7 +538,7 @@ namespace DotRecast.Core.Collections
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,21 +43,12 @@ namespace DotRecast.Core.Collections
|
||||||
public T V30;
|
public T V30;
|
||||||
public T V31;
|
public T V31;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void ThrowExceptionIfIndexOutOfRange(int index)
|
|
||||||
{
|
|
||||||
if (0 > index || index >= Size)
|
|
||||||
{
|
|
||||||
throw new IndexOutOfRangeException($"{index}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public T this[int index]
|
public T this[int index]
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
return index switch
|
return index switch
|
||||||
{
|
{
|
||||||
|
@ -99,7 +90,7 @@ namespace DotRecast.Core.Collections
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -523,21 +523,12 @@ namespace DotRecast.Core.Collections
|
||||||
public T V510;
|
public T V510;
|
||||||
public T V511;
|
public T V511;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void ThrowExceptionIfIndexOutOfRange(int index)
|
|
||||||
{
|
|
||||||
if (0 > index || index >= Size)
|
|
||||||
{
|
|
||||||
throw new IndexOutOfRangeException($"{index}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public T this[int index]
|
public T this[int index]
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
return index switch
|
return index switch
|
||||||
{
|
{
|
||||||
|
@ -1060,7 +1051,7 @@ namespace DotRecast.Core.Collections
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
|
@ -1576,7 +1567,6 @@ namespace DotRecast.Core.Collections
|
||||||
case 509: V509 = value; break;
|
case 509: V509 = value; break;
|
||||||
case 510: V510 = value; break;
|
case 510: V510 = value; break;
|
||||||
case 511: V511 = value; break;
|
case 511: V511 = value; break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,21 +75,12 @@ namespace DotRecast.Core.Collections
|
||||||
public T V62;
|
public T V62;
|
||||||
public T V63;
|
public T V63;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void ThrowExceptionIfIndexOutOfRange(int index)
|
|
||||||
{
|
|
||||||
if (0 > index || index >= Size)
|
|
||||||
{
|
|
||||||
throw new IndexOutOfRangeException($"{index}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public T this[int index]
|
public T this[int index]
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
return index switch
|
return index switch
|
||||||
{
|
{
|
||||||
|
@ -163,7 +154,7 @@ namespace DotRecast.Core.Collections
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
ThrowExceptionIfIndexOutOfRange(index);
|
ThrowHelper.ThrowExceptionIfIndexOutOfRange(index, Length);
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using DotRecast.Core.Buffers;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace DotRecast.Core.Test;
|
||||||
|
|
||||||
|
public class RcRentedArrayTest
|
||||||
|
{
|
||||||
|
public List<int> RandomValues(int length)
|
||||||
|
{
|
||||||
|
var rand = new RcRand();
|
||||||
|
|
||||||
|
// excepted values
|
||||||
|
var list = new List<int>();
|
||||||
|
for (int i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
list.Add(rand.NextInt32());
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test()
|
||||||
|
{
|
||||||
|
var rand = new RcRand();
|
||||||
|
for (int loop = 0; loop < 1024; ++loop)
|
||||||
|
{
|
||||||
|
int length = (int)(rand.Next() * 2048);
|
||||||
|
var values = RandomValues(length);
|
||||||
|
using var array = RcRentedArray.RentDisposableArray<float>(length);
|
||||||
|
|
||||||
|
for (int i = 0; i < array.Length; ++i)
|
||||||
|
{
|
||||||
|
array[i] = values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < array.Length; ++i)
|
||||||
|
{
|
||||||
|
Assert.That(array[i], Is.EqualTo(values[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.That(array[^1], Is.EqualTo(values[^1]));
|
||||||
|
|
||||||
|
Assert.Throws<IndexOutOfRangeException>(() => array[-1] = 0);
|
||||||
|
Assert.Throws<IndexOutOfRangeException>(() => array[array.Length + 1] = 0);
|
||||||
|
Assert.Throws<IndexOutOfRangeException>(() => _ = array[-1]);
|
||||||
|
Assert.Throws<IndexOutOfRangeException>(() => _ = array[array.Length + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue