Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SDL3 bindings for C headers with support for all platforms #1

Merged
merged 37 commits into from Apr 7, 2024

Conversation

Susko3
Copy link
Member

@Susko3 Susko3 commented Apr 6, 2024

osu!framework changes: https://github.com/ppy/osu-framework/compare/master...Susko3:osu-framework:wip-SDL3?expand=1 (osu! framework changes include async mouse+keyboard, which is really nice for latency and should fix ppy/osu-framework#6181)
osu! changes: https://github.com/ppy/osu/compare/master...Susko3:osu:wip-SDL3?expand=1
iOS might not work: libsdl-org/SDL#9430.

Bindings generated with ClangSharp on SDL commit libsdl-org/SDL@6ad390f.

These bindings should be bit-perfect and cross-generate all platform definitions on windows (it should be simple to get this generating on Linux as well, just need to undefine the main platfom macro 72353a8).

They also include:

  • automatically generated (source generation) friendly overloads for string? + ReadOnlySpan<byte> (for UTF-8 string literals) (c5e3181, 91cef07)
  • manually written macro function definitions (42b1966)
  • type-friendly properties/getters on some structs (9a5d2e4)
  • memory safe arrays (75db9b1)
  • a custom SDL patch so the C# bindings have proper types (e85349e) (this can't be applied upstream due to various reasons)
  • and more minor changes that make the bindings nicer to use

The whole binding generation process is driven by a python script. If that is unacceptable, I can rewrite it as a C# console application.

I've made the commits go step-by-step, showing the changes to the generated files along the way. This should be useful for git blaming; to know why/what each line does in the python file.

To test this, you can run the SDL3-CS.Tests project, but you'll need to bring your own SDL3 library. Adding github actions/nuget packing for native will come later.

Susko3 added 30 commits April 5, 2024 23:59
The bindings don't yet compile. There are errors in SDL_pixels.g.cs, SDL_stdinc.g.cs and SDL_thread.g.cs,
a bunch of warnings about "Function like macro definition records are not supported",
and a few "Info: Potential missing remapping".

Built on SDL commit:
libsdl-org/SDL@6ad390f
Probably needs similar undefines on Linux and macOS.

Notice that the signatures of `SDL_CreateThread` and `SDL_CreateThreadWithStackSize`
have changed.
There are warnings for platform-specific functions.
Doesn't compile because of duplicate `_XEvent` definitions.
Linux fails crossgen on Windows due to missing `endian.h`
The win32 types are kinda cursed, but it makes it easy to copy&paste and check.
These map to 16-bit `ushort` on windows, but are 32-bit on Unix.
This matches .NET's UTF-8 `ReadOnlySpan<byte>` (see `SDL_hints.g.cs`).
Produces a lot of noise about unused remappings (as we're processing a header at a time).
All remappings (except `SDL_JoystickGUID`) have been added.

`SDL_JoystickGUID` is a remapping of a struct, so it's harded to do programatically.
This doesn't compile as ClangSharp fails to emit `unchecked`
in `SDL_pen.g.cs` and `SDL_touch.g.cs`.
And `(SDL_bool)` casts in `SDL_rect.g.cs`.
This doesn't compile because of duplicate `SDL_Keycode` definition
All of these get "Function like macro definition records are not supported: [...] Generated bindings may be incomplete."
warnings when running ClangSharp.
Useful as any pointer type can implicitly covert to void *.
This could be done with a source generator, but this is simpler.
Susko3 and others added 7 commits April 6, 2024 14:24
This is done by adding a `Unsafe_` prefix to `(const) char *` (C# `byte*`) functions.
I am using `string?` instead of `ReadOnlyMemory<byte>?` because the returned pointer can
get invalidated and cause memory-safety issues.

The returned pointer is automatically freed if the return type is `char *`.
I've checked that the documentation for all functions (except in SDL_stdinc.h)
requires calling `SDL_free()` on the pointer.
This helps consumers avoid having to do ugly casts
as was previously done in `SDL_quit.cs`.

It's very important that the underlying type doesn't change
as that might break ABI compat.
Just a playground to see how the string/type/array friendly overloads work.
You'll have to provide the SDL3 library manually.
@smoogipoo
Copy link
Contributor

smoogipoo commented Apr 7, 2024

Well done 👏. For the time being I've manually gone through every file (including generated ones) just to ensure nothing's weird, and applied a few fixes.

I think this is fine for the time being, leaving to future PRs (in order of importance):

  • Compiling + embedding of native library (Add native build workflow #2).
  • Nupkg generation + deploy (Add deploy workflow #3).
  • Hopefully automatic binding generation.
  • macOS/Linux binding generation (haven't tried yet, as I said I've gone through every file manually for now).

@smoogipoo smoogipoo merged commit 07a8cd9 into ppy:master Apr 7, 2024
1 check passed
@Susko3 Susko3 deleted the initial branch April 7, 2024 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Input thread blocking causes mouse handling stutters on windows
2 participants