diff --git a/SDL3-CS.Tests/Program.cs b/SDL3-CS.Tests/Program.cs index 8e44865..acfa9bb 100644 --- a/SDL3-CS.Tests/Program.cs +++ b/SDL3-CS.Tests/Program.cs @@ -32,6 +32,8 @@ namespace SDL.Tests window.Setup(); window.Create(); + printWindows(); + const SDL_Keymod state = SDL_Keymod.SDL_KMOD_CAPS | SDL_Keymod.SDL_KMOD_ALT; SDL_SetModState(state); Debug.Assert(SDL_GetModState() == state); @@ -64,5 +66,17 @@ namespace SDL.Tests } } } + + private static unsafe void printWindows() + { + using var windows = SDL_GetWindows(); + if (windows == null) + return; + + for (int i = 0; i < windows.Count; i++) + { + Console.WriteLine($"Window {i} title: {SDL_GetWindowTitle(windows[i])}"); + } + } } } diff --git a/SDL3-CS/SDL3/SDL_video.cs b/SDL3-CS/SDL3/SDL_video.cs index 0b952ab..2641bb6 100644 --- a/SDL3-CS/SDL3/SDL_video.cs +++ b/SDL3-CS/SDL3/SDL_video.cs @@ -107,11 +107,11 @@ namespace SDL } [MustDisposeResource] - public static unsafe SDLPointerArray? SDL_GetWindows() + public static unsafe SDLOpaquePointerArray? SDL_GetWindows() { int count; var array = SDL_GetWindows(&count); - return SDLArray.Create(array, count); + return SDLArray.CreateOpaque(array, count); } } } diff --git a/SDL3-CS/SDLArray.cs b/SDL3-CS/SDLArray.cs index 91f1d60..1494025 100644 --- a/SDL3-CS/SDLArray.cs +++ b/SDL3-CS/SDLArray.cs @@ -63,5 +63,15 @@ namespace SDL return new SDLPointerArray(array, count); } + + [MustDisposeResource] + internal static SDLOpaquePointerArray? CreateOpaque(T** array, int count) + where T : unmanaged + { + if (array == null) + return null; + + return new SDLOpaquePointerArray(array, count); + } } } diff --git a/SDL3-CS/SDLOpaquePointerArray.cs b/SDL3-CS/SDLOpaquePointerArray.cs new file mode 100644 index 0000000..4123e91 --- /dev/null +++ b/SDL3-CS/SDLOpaquePointerArray.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Diagnostics; +using JetBrains.Annotations; + +namespace SDL +{ + [MustDisposeResource] + public sealed unsafe class SDLOpaquePointerArray : IDisposable + where T : unmanaged + { + private readonly T** array; + public readonly int Count; + private bool isDisposed; + + internal SDLOpaquePointerArray(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); + } + } +}