mirror of https://github.com/ppy/SDL3-CS.git
Add memory safe IDisposable overloads to array-returning functions
This could be done with a source generator, but this is simpler.
This commit is contained in:
parent
9a5d2e4dbc
commit
75db9b16c1
|
|
@ -58,5 +58,19 @@ namespace SDL
|
|||
|
||||
[Macro]
|
||||
public static int SDL_AUDIO_FRAMESIZE(SDL_AudioSpec x) => SDL_AUDIO_BYTESIZE((x).format) * (x).channels;
|
||||
|
||||
public static unsafe SDLArray<SDL_AudioDeviceID>? SDL_GetAudioOutputDevices()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetAudioOutputDevices(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
|
||||
public static unsafe SDLArray<SDL_AudioDeviceID>? SDL_GetAudioCaptureDevices()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetAudioCaptureDevices(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,21 @@ namespace SDL
|
|||
{
|
||||
[Typedef]
|
||||
public enum SDL_CameraDeviceID : UInt32;
|
||||
|
||||
public static partial class SDL3
|
||||
{
|
||||
public static unsafe SDLArray<SDL_CameraDeviceID>? SDL_GetCameraDevices()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetCameraDevices(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
|
||||
public static unsafe SDLArray<SDL_CameraSpec>? SDL_GetCameraDeviceSupportedFormats(SDL_CameraDeviceID devid)
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetCameraDeviceSupportedFormats(devid, &count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
// 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;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SDL
|
||||
{
|
||||
public static partial class SDL3
|
||||
{
|
||||
/// <returns>
|
||||
/// An array of <see cref="nint"/> that can be passed to <see cref="Marshal.PtrToStringUTF8(System.IntPtr)"/>.
|
||||
/// </returns>
|
||||
public static unsafe SDLArray<IntPtr>? SDL_GetGamepadMappings()
|
||||
{
|
||||
int count;
|
||||
IntPtr* array = (IntPtr*)SDL_GetGamepadMappings(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
|
||||
public static unsafe SDLArray<SDL_JoystickID>? SDL_GetGamepads()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetGamepads(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
|
||||
public static unsafe SDLPointerArray<SDL_GamepadBinding>? SDL_GetGamepadBindings(SDL_Gamepad* gamepad)
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetGamepadBindings(gamepad, &count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,4 +7,14 @@ namespace SDL
|
|||
{
|
||||
[Typedef]
|
||||
public enum SDL_HapticID : UInt32;
|
||||
|
||||
public static partial class SDL3
|
||||
{
|
||||
public static unsafe SDLArray<SDL_HapticID>? SDL_GetHaptics()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetHaptics(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,14 @@ namespace SDL
|
|||
{
|
||||
[Typedef]
|
||||
public enum SDL_JoystickID : UInt32;
|
||||
|
||||
public static partial class SDL3
|
||||
{
|
||||
public static unsafe SDLArray<SDL_JoystickID>? SDL_GetJoysticks()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetJoysticks(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,4 +12,14 @@ namespace SDL
|
|||
{
|
||||
public SDL_Keymod Mod => (SDL_Keymod)mod;
|
||||
}
|
||||
|
||||
public static partial class SDL3
|
||||
{
|
||||
public static unsafe SDLArray<SDL_KeyboardID>? SDL_GetKeyboards()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetKeyboards(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,5 +31,12 @@ namespace SDL
|
|||
{
|
||||
[Macro]
|
||||
public static SDLButtonMask SDL_BUTTON(SDLButton button) => (SDLButtonMask)(1 << ((int)button - 1));
|
||||
|
||||
public static unsafe SDLArray<SDL_MouseID>? SDL_GetMice()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetMice(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,5 +33,12 @@ namespace SDL
|
|||
|
||||
[Macro]
|
||||
public static SDL_PEN_CAPABILITIES SDL_PEN_AXIS_CAPABILITY(SDL_PenAxis axis) => SDL_PEN_CAPABILITY((int)axis + SDL_PEN_FLAG_AXIS_BIT_OFFSET);
|
||||
|
||||
public static unsafe SDLArray<SDL_PenID>? SDL_GetPens()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetPens(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,14 @@ namespace SDL
|
|||
{
|
||||
[Typedef]
|
||||
public enum SDL_SensorID : UInt32;
|
||||
|
||||
public static partial class SDL3
|
||||
{
|
||||
public static unsafe SDLArray<SDL_SensorID>? SDL_GetSensors()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetSensors(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,5 +18,12 @@ namespace SDL
|
|||
|
||||
[Constant]
|
||||
public const SDL_TouchID SDL_MOUSE_TOUCHID = unchecked((SDL_TouchID)(-1));
|
||||
|
||||
public static unsafe SDLArray<SDL_TouchID>? SDL_GetTouchDevices()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetTouchDevices(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,5 +53,19 @@ namespace SDL
|
|||
|
||||
[Macro]
|
||||
public static bool SDL_WINDOWPOS_ISCENTERED(int X) => (((X) & 0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK);
|
||||
|
||||
public static unsafe SDLArray<SDL_DisplayID>? SDL_GetDisplays()
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetDisplays(&count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
|
||||
public static unsafe SDLPointerArray<SDL_DisplayMode>? SDL_GetFullscreenDisplayModes(SDL_DisplayID displayID)
|
||||
{
|
||||
int count;
|
||||
var array = SDL_GetFullscreenDisplayModes(displayID, &count);
|
||||
return SDLArray.Create(array, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
// 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;
|
||||
|
||||
namespace SDL
|
||||
{
|
||||
public sealed unsafe class SDLArray<T> : IDisposable
|
||||
where T : unmanaged
|
||||
{
|
||||
private readonly T* array;
|
||||
public readonly int Count;
|
||||
private bool isDisposed;
|
||||
|
||||
internal SDLArray(T* array, int count)
|
||||
{
|
||||
this.array = array;
|
||||
Count = count;
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(isDisposed, this);
|
||||
ArgumentOutOfRangeException.ThrowIfNegative(index);
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(index, Count);
|
||||
return array[index];
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (isDisposed)
|
||||
return;
|
||||
|
||||
isDisposed = true;
|
||||
SDL3.SDL_free(array);
|
||||
}
|
||||
}
|
||||
|
||||
internal static unsafe class SDLArray
|
||||
{
|
||||
internal static SDLArray<T>? Create<T>(T* array, int count)
|
||||
where T : unmanaged
|
||||
{
|
||||
if (array == null)
|
||||
return null;
|
||||
|
||||
return new SDLArray<T>(array, count);
|
||||
}
|
||||
|
||||
internal static SDLPointerArray<T>? Create<T>(T** array, int count)
|
||||
where T : unmanaged
|
||||
{
|
||||
if (array == null)
|
||||
return null;
|
||||
|
||||
return new SDLPointerArray<T>(array, count);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// 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;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SDL
|
||||
{
|
||||
// T* can't be used as a type parameter, so this has to be a separate class
|
||||
public sealed unsafe class SDLPointerArray<T> : IDisposable
|
||||
where T : unmanaged
|
||||
{
|
||||
private readonly T** array;
|
||||
public readonly int Count;
|
||||
private bool isDisposed;
|
||||
|
||||
internal SDLPointerArray(T** array, int count)
|
||||
{
|
||||
this.array = array;
|
||||
Count = count;
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(isDisposed, this);
|
||||
ArgumentOutOfRangeException.ThrowIfNegative(index);
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(index, Count);
|
||||
Debug.Assert(array[index] != null);
|
||||
return *array[index];
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (isDisposed)
|
||||
return;
|
||||
|
||||
isDisposed = true;
|
||||
SDL3.SDL_free(array);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue