-
Notifications
You must be signed in to change notification settings - Fork 203
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
[SwiftBindings] prototype for SwiftOptional #2896
base: feature/swift-bindings
Are you sure you want to change the base?
Conversation
/// <summary> | ||
/// Marshals this object to a Swift destination | ||
/// </summary> | ||
unsafe IntPtr MarshalToSwift(IntPtr swiftDest); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this has to be unsafe
/// <summary> | ||
/// Creates a new Swift object from a given payload | ||
/// </summary> | ||
public static abstract ISwiftObject NewFromPayload(IntPtr payload); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with you that SwiftHandle
would feel better
|
||
namespace Swift.Runtime; | ||
|
||
#nullable enable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a broader discussion, should we enable nullable on all Swft.Runtime code?
public bool HasValue => Case == SwiftOptionalCases.Some; | ||
} | ||
|
||
internal static class PInvokesForSwiftOptional { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
internal static class PInvokesForSwiftOptional { | |
internal static class PInvokesForSwiftOptional { |
/// <summary> | ||
/// Represents a class for marshaling data to and from Swift | ||
/// </summary> | ||
public static class SwiftMarshal { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: Sometimes a new line is used before a curly brace and sometimes not
|
||
internal static class PInvokesForSwiftOptional { | ||
[DllImport(KnownLibraries.SwiftCore, EntryPoint = "$sSqMa")] | ||
public static extern TypeMetadata _MetadataAccessor(MetadataRequest request, TypeMetadata typeMetadata); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: I'm not sure about the naming convention. In the generated code I think we use the "PInvoke" prefix. I dont have strong opinion what convention should we use, just want to be consistent.
This is a prototype of SwiftOptional. It's meant to flesh out issues that we will encounter in binding enums and binding generic types.
What to expect here:
What this is missing:
ISwiftEquatable and ISwiftHashable implementations for SwiftOptional. Mostly because those interface definitions and the necessary proxies aren't here (yet).
No memory management. This type should implement
IDisposable
.What I like:
What I don't like:
SwiftObjectHelper<SwiftOptional<T>>.GetTypeMetadata()
to get the metadata within a class, but I understand that it's the cost of the explicit interface and static methods and keeping only one copy of the type metadata.SwiftOptional<T>
. This is an important point for discussion. What we need is a constructor that has a unique signature that is unpronounceable in Swift so that there will never be conflicts in the bindings. In BTfS I used an enum that was unique to BTfS. We could make the ctor do all the marshaling and take a SwiftHandle (which also shouldn't be pronounceable in Swift).Why MarshalToSwift returns a different pointer:
For generic arguments to functions, Swift uses a pointer to value types. For heap allocated types, the actual pointer is used NOT a pointer to a pointer. Because of this, a binding to a class will have something that looks like this for the marshaling:
Other notes:
I added
HasValue
andValue
as those will feel better to C# programmers. In general for binding, we should consider binding types that are represented as classes as partial classes so we can add convenience methods to them that have access to the internals.The pattern I used for enums follows the documentation that I wrote for binding enums in that:
[TYPE]Cases
New[CASENAME]
Case
[CASENAME]
Given C#'s lack of discriminated unions, this seemed reasonable.