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

Improve c sharp binding generation #3261

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

TJHeuvel
Copy link

@TJHeuvel TJHeuvel commented Feb 28, 2024

  • Enums of type byte were not implemented, only uint and ushort were recognised.
  • Added XML comments to the structs, and their fields.
  • Added default values to parameters
  • For the handles, it was not possible to have Invalid as a default parameter. Instead i emit another method without the argument, that calls the extern with an Invalid handle. This also required some overhauling for those structs, and i've also implemented some recommended fields to improve performance (https://learn.microsoft.com/en-us/visualstudio/ide/reference/generate-equals-structs?view=vs-2022). This is an internal change, any existing project will still compile.

- Enums of type byte were not implemented, only uint and ushort were recognised.
- Added XML comments to the structs, and their fields.
- Added default values to parameters
 - For the handles, it was not possible to have Invalid as a default parameter. Instead i emit another method without the argument, that calls the `extern` with an Invalid handle.
 This also required some overhauling for those structs, and i've also implemented some recommended fields to improve performance (https://learn.microsoft.com/en-us/visualstudio/ide/reference/generate-equals-structs?view=vs-2022).
@TJHeuvel
Copy link
Author

TJHeuvel commented Feb 28, 2024

There is one more change that i'd like to do, but wanted some feedback before attempting.

The bindings are now generated from the C API, with explicit this parameters. Although i do think this binding should stay very low level, this doesn't map very well to C#. Even the original C++ API just uses objects with methods.

I would like to update the binding generator to add methods to the structs, rather than the current C-style API.

[DllImport(DllName, EntryPoint="bgfx_vertex_layout_begin", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe VertexLayout* vertex_layout_begin(VertexLayout* _this, RendererType _rendererType = RendererType.Noop);

Would become private, and in VertexLayout a begin method would call it. This is however a breaking change for any existing C# projects. It would be possible to do both, however thats just adding more confusion in my opinion.

Likewise with init_ctor, which already caught me.

@bkaradzic
Copy link
Owner

For the handles, it was not possible to have Invalid as a default parameter. Instead i emit another method without the argument, that calls the extern with an Invalid handle. This also required some overhauling for those structs, and i've also implemented some recommended fields to improve performance (https://learn.microsoft.com/en-us/visualstudio/ide/reference/generate-equals-structs?view=vs-2022). This is an internal change, any existing project will still compile.

This change makes all code managed only. bgfx in C# should be unmanaged.

@TJHeuvel
Copy link
Author

TJHeuvel commented Feb 29, 2024

For the handles, it was not possible to have Invalid as a default parameter. Instead i emit another method without the argument, that calls the extern with an Invalid handle. This also required some overhauling for those structs, and i've also implemented some recommended fields to improve performance (https://learn.microsoft.com/en-us/visualstudio/ide/reference/generate-equals-structs?view=vs-2022). This is an internal change, any existing project will still compile.

This change makes all code managed only. bgfx in C# should be unmanaged.

I'd gladly change the struct additions, i'm not very attached to them. However i dont believe this makes them unmanaged, if you are referring to the C# concept.

A type is an unmanaged type if it's any of the following types:

    sbyte, byte, short, ushort, int, uint, long, ulong, nint, nuint, char, float, double, decimal, or bool
    Any enum type
    Any pointer type
    Any user-defined struct type that contains fields of unmanaged types only.

This is still satisfied since the only field is still an ushort. I'm not entirely sure how to test this, but for example the unmanaged generic type constraint is met. For the class, and a struct that fails above restrictions, it does not.

image

It does however add a whole lot of noise. There is also an entirely different strategy possible, where there is only a single handle type.


struct DynamicIndexBuffer { }

public readonly struct Handle<T>
{
    public readonly ushort idx;
}

Handle<DynamicIndexBuffer> someHandle;

This offers the same amount of type safety, a handle of one type cannot be used for another.

These caused more friction than intended. Only the `Invalid` readonly field remains, and a constructor that includes the index parameter are additions.
@TJHeuvel
Copy link
Author

TJHeuvel commented Mar 1, 2024

My latest commit undid most of the struct changes. The only changes that remain there are the static Invalid field, and a constructor to pass along the index.

	public struct DynamicVertexBufferHandle {
		public ushort idx;
		public static readonly DynamicVertexBufferHandle Invalid = new DynamicVertexBufferHandle(ushort.MaxValue);
		public DynamicVertexBufferHandle(ushort index) => idx = index;
		public bool Valid => this.idx != Invalid.idx;
	}

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.

2 participants