mirror of https://github.com/ppy/SDL3-CS.git
Allow `foreach` enumeration over SDLArray
This commit is contained in:
parent
7155c09e71
commit
080b1e571e
|
|
@ -0,0 +1,117 @@
|
||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace SDL.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSDLArray
|
||||||
|
{
|
||||||
|
private static unsafe T* CopyToSdl<T>(T[] array)
|
||||||
|
where T : unmanaged
|
||||||
|
{
|
||||||
|
UIntPtr size = (UIntPtr)(Marshal.SizeOf<T>() * array.Length);
|
||||||
|
IntPtr target = SDL3.SDL_malloc(size);
|
||||||
|
|
||||||
|
fixed (T* source = array)
|
||||||
|
{
|
||||||
|
SDL3.SDL_memcpy(target, (IntPtr)source, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (T*)target;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static unsafe T** CopyToSdl<T>(T*[] array)
|
||||||
|
where T : unmanaged
|
||||||
|
{
|
||||||
|
UIntPtr size = (UIntPtr)(sizeof(IntPtr) * array.Length);
|
||||||
|
IntPtr target = SDL3.SDL_malloc(size);
|
||||||
|
|
||||||
|
fixed (T** source = array)
|
||||||
|
{
|
||||||
|
SDL3.SDL_memcpy(target, (IntPtr)source, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (T**)target;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public unsafe void TestArrayEnumerator()
|
||||||
|
{
|
||||||
|
int[] values = [10, 20, 30, 40];
|
||||||
|
int* sdlMemory = CopyToSdl(values);
|
||||||
|
|
||||||
|
using var array = new SDLArray<int>(sdlMemory, values.Length);
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
foreach (int i in array)
|
||||||
|
{
|
||||||
|
Assert.AreEqual(values[index++], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public unsafe void TestConstOpaquePointerArrayEnumerator()
|
||||||
|
{
|
||||||
|
int a = 10, b = 20, c = 30, d = 40;
|
||||||
|
int*[] values = [&a, &b, &c, &d];
|
||||||
|
int** sdlMemory = null;
|
||||||
|
|
||||||
|
// Const pointer arrays are not freed automatically. Since the
|
||||||
|
// unit test owns the memory, this must be done at the end of the
|
||||||
|
// test.
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sdlMemory = CopyToSdl(values);
|
||||||
|
|
||||||
|
var array = new SDLConstOpaquePointerArray<int>(sdlMemory, values.Length);
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
foreach (int* i in array)
|
||||||
|
{
|
||||||
|
Assert.AreEqual((IntPtr)values[index++], (IntPtr)i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (sdlMemory != null)
|
||||||
|
SDL3.SDL_free(sdlMemory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public unsafe void TestOpaquePointerArrayEnumerator()
|
||||||
|
{
|
||||||
|
int a = 10, b = 20, c = 30, d = 40;
|
||||||
|
int*[] values = [&a, &b, &c, &d];
|
||||||
|
int** sdlMemory = CopyToSdl(values);
|
||||||
|
|
||||||
|
using var array = new SDLOpaquePointerArray<int>(sdlMemory, values.Length);
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
foreach (int* i in array)
|
||||||
|
{
|
||||||
|
Assert.AreEqual((IntPtr)values[index++], (IntPtr)i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public unsafe void TestPointerArrayEnumerator()
|
||||||
|
{
|
||||||
|
int a = 10, b = 20, c = 30, d = 40;
|
||||||
|
int*[] values = [&a, &b, &c, &d];
|
||||||
|
int** memory = CopyToSdl(values);
|
||||||
|
|
||||||
|
using var array = new SDLPointerArray<int>(memory, values.Length);
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
foreach (int i in array)
|
||||||
|
{
|
||||||
|
Assert.AreEqual(*values[index++], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -40,6 +40,24 @@ namespace SDL
|
||||||
|
|
||||||
SDL3.SDL_free(array);
|
SDL3.SDL_free(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Enumerator GetEnumerator() => new Enumerator(this);
|
||||||
|
|
||||||
|
public ref struct Enumerator
|
||||||
|
{
|
||||||
|
private readonly SDLArray<T> array;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
internal Enumerator(SDLArray<T> array)
|
||||||
|
{
|
||||||
|
this.array = array;
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext() => ++index < array.Count;
|
||||||
|
|
||||||
|
public T Current => array[index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static unsafe class SDLArray
|
internal static unsafe class SDLArray
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,23 @@ namespace SDL
|
||||||
return array[index];
|
return array[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Enumerator GetEnumerator() => new Enumerator(this);
|
||||||
|
|
||||||
|
public ref struct Enumerator
|
||||||
|
{
|
||||||
|
private readonly SDLConstOpaquePointerArray<T> array;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
internal Enumerator(SDLConstOpaquePointerArray<T> array)
|
||||||
|
{
|
||||||
|
this.array = array;
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext() => ++index < array.Count;
|
||||||
|
|
||||||
|
public T* Current => array[index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,5 +42,23 @@ namespace SDL
|
||||||
|
|
||||||
SDL3.SDL_free(array);
|
SDL3.SDL_free(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Enumerator GetEnumerator() => new Enumerator(this);
|
||||||
|
|
||||||
|
public ref struct Enumerator
|
||||||
|
{
|
||||||
|
private readonly SDLOpaquePointerArray<T> array;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
internal Enumerator(SDLOpaquePointerArray<T> array)
|
||||||
|
{
|
||||||
|
this.array = array;
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext() => ++index < array.Count;
|
||||||
|
|
||||||
|
public T* Current => array[index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,5 +43,23 @@ namespace SDL
|
||||||
|
|
||||||
SDL3.SDL_free(array);
|
SDL3.SDL_free(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Enumerator GetEnumerator() => new Enumerator(this);
|
||||||
|
|
||||||
|
public ref struct Enumerator
|
||||||
|
{
|
||||||
|
private readonly SDLPointerArray<T> array;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
internal Enumerator(SDLPointerArray<T> array)
|
||||||
|
{
|
||||||
|
this.array = array;
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext() => ++index < array.Count;
|
||||||
|
|
||||||
|
public T Current => array[index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue