diff --git a/src/Generation/Generator/Renderer/Internal/OpaqueTypedRecordHandle.cs b/src/Generation/Generator/Renderer/Internal/OpaqueTypedRecordHandle.cs index 43dcf9b74..f29e01a95 100644 --- a/src/Generation/Generator/Renderer/Internal/OpaqueTypedRecordHandle.cs +++ b/src/Generation/Generator/Renderer/Internal/OpaqueTypedRecordHandle.cs @@ -9,7 +9,6 @@ public static string Render(GirModel.Record record) var typeName = Model.OpaqueTypedRecord.GetInternalHandle(record); var unownedHandleTypeName = Model.OpaqueTypedRecord.GetInternalUnownedHandle(record); var ownedHandleTypeName = Model.OpaqueTypedRecord.GetInternalOwnedHandle(record); - var getGType = $"{Model.OpaqueTypedRecord.GetFullyQualifiedInternalClassName(record)}.{Function.GetGType}()"; return $@"using System; using GObject; @@ -29,15 +28,17 @@ public abstract class {typeName} : SafeHandle, IEquatable<{typeName}> protected {typeName}(bool ownsHandle) : base(IntPtr.Zero, ownsHandle) {{ }} + {RenderCopyFunction(record)} + public {ownedHandleTypeName} OwnedCopy() {{ - var ptr = GObject.Internal.Functions.BoxedCopy({getGType}, handle); + {RenderCopyStatement(record, "ptr", "handle")} return new {ownedHandleTypeName}(ptr); }} - + public {unownedHandleTypeName} UnownedCopy() {{ - var ptr = GObject.Internal.Functions.BoxedCopy({getGType}, handle); + {RenderCopyStatement(record, "ptr", "handle")} return new {unownedHandleTypeName}(ptr); }} @@ -102,6 +103,8 @@ public class {ownedHandleTypeName} : {typeName} SetHandle(ptr); }} + {RenderFreeFunction(record)} + /// /// Create a {ownedHandleTypeName} from a pointer that is assumed unowned. To do so a /// boxed copy is created of the given pointer to be used as the handle. @@ -110,15 +113,53 @@ public class {ownedHandleTypeName} : {typeName} /// A {ownedHandleTypeName} public static {ownedHandleTypeName} FromUnowned(IntPtr ptr) {{ - var ownedPtr = GObject.Internal.Functions.BoxedCopy({getGType}, ptr); - return new {ownedHandleTypeName}(ownedPtr); + {RenderCopyStatement(record, "ownedPtr", "ptr")} + return new {ownedHandleTypeName}(ownedPtr); }} protected override bool ReleaseHandle() {{ - GObject.Internal.Functions.BoxedFree({getGType}, handle); - return true; + {RenderFreeStatement(record, "handle")} + return true; }} }}"; } + + private static string RenderCopyFunction(GirModel.Record record) + { + return record.CopyFunction is null || !Method.IsValidCopyFunction(record.CopyFunction) + ? string.Empty + : $""" + [DllImport(ImportResolver.Library, EntryPoint = "{record.CopyFunction}")] + protected static extern IntPtr Copy(IntPtr handle); + """; + } + + private static string RenderFreeFunction(GirModel.Record record) + { + return record.FreeFunction is null || !Method.IsValidFreeFunction(record.FreeFunction) + ? string.Empty + : $""" + [DllImport(ImportResolver.Library, EntryPoint = "{record.FreeFunction}")] + private static extern void Free(IntPtr handle); + """; + } + + private static string RenderCopyStatement(GirModel.Record record, string resultVariable, string parameterVariable) + { + var getGType = $"{Model.OpaqueTypedRecord.GetFullyQualifiedInternalClassName(record)}.{Function.GetGType}()"; + + return record.CopyFunction is null || !Method.IsValidCopyFunction(record.CopyFunction) + ? $"var {resultVariable} = GObject.Internal.Functions.BoxedCopy({getGType}, {parameterVariable});" + : $"var {resultVariable} = Copy({parameterVariable});"; + } + + private static string RenderFreeStatement(GirModel.Record record, string parameterVariable) + { + var getGType = $"{Model.OpaqueTypedRecord.GetFullyQualifiedInternalClassName(record)}.{Function.GetGType}()"; + + return record.FreeFunction is null || !Method.IsValidFreeFunction(record.FreeFunction) + ? $"GObject.Internal.Functions.BoxedFree({getGType}, {parameterVariable});" + : $"Free({parameterVariable});"; + } } diff --git a/src/Generation/Generator/Renderer/Public/OpaqueTypedRecord.cs b/src/Generation/Generator/Renderer/Public/OpaqueTypedRecord.cs index ff21f56ad..c2123ac09 100644 --- a/src/Generation/Generator/Renderer/Public/OpaqueTypedRecord.cs +++ b/src/Generation/Generator/Renderer/Public/OpaqueTypedRecord.cs @@ -8,6 +8,12 @@ internal static class OpaqueTypedRecord { public static string Render(GirModel.Record record) { + if (record.FreeFunction is null) + Log.Information($"Record {record.Name}: Has no free-func annotation. Define it upstream to improve performance for this type."); + + if (record.CopyFunction is null) + Log.Information($"Record {record.Name}: Has no copy-func annotation. Define it upstream to improve performance for this type."); + var name = Model.OpaqueTypedRecord.GetPublicClassName(record); var internalHandleName = Model.OpaqueTypedRecord.GetFullyQuallifiedOwnedHandle(record); @@ -24,7 +30,7 @@ namespace {Namespace.GetPublicName(record.Namespace)}; // AUTOGENERATED FILE - DO NOT MODIFY {PlatformSupportAttribute.Render(record as GirModel.PlatformDependent)} -public sealed partial class {name} : GLib.BoxedRecord, IEquatable<{name}> +public sealed partial class {name} : GLib.BoxedRecord, IEquatable<{name}>, IDisposable {{ public {internalHandleName} Handle {{ get; }} @@ -83,6 +89,14 @@ public override int GetHashCode() {{ return Handle.GetHashCode(); }} + + partial void OnDispose(); + + public void Dispose() + {{ + OnDispose(); + Handle.Dispose(); + }} }}"; } } diff --git a/src/Libs/GLib-2.0/Public/Bytes.cs b/src/Libs/GLib-2.0/Public/Bytes.cs index e3bbb4402..9de294f1d 100644 --- a/src/Libs/GLib-2.0/Public/Bytes.cs +++ b/src/Libs/GLib-2.0/Public/Bytes.cs @@ -1,9 +1,8 @@ using System; -using System.Runtime.InteropServices; namespace GLib; -public sealed partial class Bytes : IDisposable +public sealed partial class Bytes { private long _size; @@ -13,9 +12,8 @@ partial void Initialize() GC.AddMemoryPressure(_size); } - public void Dispose() + partial void OnDispose() { - Handle.Dispose(); GC.RemoveMemoryPressure(_size); } } diff --git a/src/Libs/GLib-2.0/Public/Dir.cs b/src/Libs/GLib-2.0/Public/Dir.cs deleted file mode 100644 index c09007d98..000000000 --- a/src/Libs/GLib-2.0/Public/Dir.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace GLib; - -public partial class Dir : IDisposable -{ - public void Dispose() - { - Handle.Dispose(); - } -} diff --git a/src/Libs/GLib-2.0/Public/VariantType.cs b/src/Libs/GLib-2.0/Public/VariantType.cs index a7fdb4335..25b53deaa 100644 --- a/src/Libs/GLib-2.0/Public/VariantType.cs +++ b/src/Libs/GLib-2.0/Public/VariantType.cs @@ -1,15 +1,7 @@ -using System; -using System.Runtime.InteropServices; +namespace GLib; -namespace GLib; - -public partial class VariantType : IDisposable +public partial class VariantType { public static readonly VariantType String = New("s"); public static readonly VariantType Variant = New("v"); - - public void Dispose() - { - Handle.Dispose(); - } } diff --git a/src/Native/GirTestLib/girtest-opaque-typed-record-copy-annotation-tester.c b/src/Native/GirTestLib/girtest-opaque-typed-record-copy-annotation-tester.c new file mode 100644 index 000000000..290bad567 --- /dev/null +++ b/src/Native/GirTestLib/girtest-opaque-typed-record-copy-annotation-tester.c @@ -0,0 +1,206 @@ +#include "girtest-opaque-typed-record-copy-annotation-tester.h" + +/** + * GirTestOpaqueTypedRecordCopyAnnotationTester: + * (copy-func girtest_opaque_typed_record_copy_annotation_tester_ref) + * (free-func girtest_opaque_typed_record_copy_annotation_tester_unref) + * + * Just an opaque record. + */ +struct _GirTestOpaqueTypedRecordCopyAnnotationTester +{ + int ref_count; +}; + +G_DEFINE_BOXED_TYPE (GirTestOpaqueTypedRecordCopyAnnotationTester, girtest_opaque_typed_record_copy_annotation_tester, girtest_opaque_typed_record_copy_annotation_tester_ref, girtest_opaque_typed_record_copy_annotation_tester_unref) + +/** + * girtest_opaque_typed_record_copy_annotation_tester_new: (constructor) + * + * Returns: (transfer full): a new `GirTestOpaqueTypedRecordCopyAnnotationTester` + **/ +GirTestOpaqueTypedRecordCopyAnnotationTester * +girtest_opaque_typed_record_copy_annotation_tester_new () +{ + GirTestOpaqueTypedRecordCopyAnnotationTester *result; + result = g_new0 (GirTestOpaqueTypedRecordCopyAnnotationTester, 1); + result->ref_count = 1; + return result; +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_ref: + * @self: a `GirTestRecordTester` + * + * Increments the reference count on `data`. + * + * Returns: (transfer full): the data. + **/ +GirTestOpaqueTypedRecordCopyAnnotationTester * +girtest_opaque_typed_record_copy_annotation_tester_ref (GirTestOpaqueTypedRecordCopyAnnotationTester *self) +{ + g_return_val_if_fail (self != NULL, NULL); + self->ref_count += 1; + return self; +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_mirror: + * @data: a `GirTestRecordTester` + * + * Mirrors the given data as the return value. Ownership is not transferred. + * + * Returns: (transfer none): the mirrored data. + **/ +GirTestOpaqueTypedRecordCopyAnnotationTester * +girtest_opaque_typed_record_copy_annotation_tester_mirror(GirTestOpaqueTypedRecordCopyAnnotationTester *data) +{ + return data; +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_nullable_mirror: + * @data: a `GirTestRecordTester` + * @mirror: true to mirror data, false to return NULL + * + * Mirrors the given data as the return value if @mirror is true. Ownership is not transferred. + * + * Returns: (transfer none) (nullable): the mirrored data or NULL. + **/ +GirTestOpaqueTypedRecordCopyAnnotationTester * +girtest_opaque_typed_record_copy_annotation_tester_nullable_mirror(GirTestOpaqueTypedRecordCopyAnnotationTester *data, gboolean mirror) +{ + if(!mirror) + return NULL; + + return data; +} + +/** + * girtrest_opaque_typed_record_copy_annotation_tester_unref: + * @self: (transfer full): a `GirTestOpaqueTypedRecordCopyAnnotationTester` + * + * Decrements the reference count on `data` and frees the + * data if the reference count is 0. + **/ +void +girtest_opaque_typed_record_copy_annotation_tester_unref (GirTestOpaqueTypedRecordCopyAnnotationTester *self) +{ + g_return_if_fail (self != NULL); + + self->ref_count -= 1; + if (self->ref_count > 0) + return; + + g_free (self); +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_get_ref_count: + * @self: a `GirTestOpaqueTypedRecordCopyAnnotationTester` + * + * Returns: The current ref count of the opaque record. + **/ +int +girtest_opaque_typed_record_copy_annotation_tester_get_ref_count(GirTestOpaqueTypedRecordCopyAnnotationTester *self) +{ + g_return_val_if_fail (self != NULL, -1); + return self->ref_count; +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_take_and_unref: + * @self: (transfer full): a `GirTestOpaqueTypedRecordCopyAnnotationTester` + * + * Takes ownership and decrements the reference count on `data` and frees the + * data if the reference count is 0. + **/ +void +girtest_opaque_typed_record_copy_annotation_tester_take_and_unref(GirTestOpaqueTypedRecordCopyAnnotationTester *self) +{ + girtest_opaque_typed_record_copy_annotation_tester_unref(self); +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_take_and_unref_func: + * @dummy: Just an unused dummy value + * @data: (transfer full): a `GirTestOpaqueTypedRecordCopyAnnotationTester` + * + * Takes ownership and decrements the reference count on `data` and frees the + * data if the reference count is 0. + **/ +void +girtest_opaque_typed_record_copy_annotation_tester_take_and_unref_func(int dummy, GirTestOpaqueTypedRecordCopyAnnotationTester *data) +{ + girtest_opaque_typed_record_copy_annotation_tester_take_and_unref(data); +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_take_and_unref_func_nullable: + * @dummy: Just an unused dummy value + * @data: (transfer full) (nullable): a `GirTestOpaqueTypedRecordCopyAnnotationTester` + * + * Takes ownership and decrements the reference count on `data` and frees the + * data if the reference count is 0. + **/ +void +girtest_opaque_typed_record_copy_annotation_tester_take_and_unref_func_nullable(int dummy, GirTestOpaqueTypedRecordCopyAnnotationTester *data) +{ + if(data == NULL) + return; + + girtest_opaque_typed_record_copy_annotation_tester_take_and_unref(data); +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_run_callback_return_no_ownership_transfer: + * @callback: (scope call): a callback + * + * Calls the callback and returns the newly created instance. + * + * Returns: (transfer none): a GirTestOpaqueTypedRecordCopyAnnotationTester + **/ +GirTestOpaqueTypedRecordCopyAnnotationTester * +girtest_opaque_typed_record_copy_annotation_tester_run_callback_return_no_ownership_transfer(GirTestCreateOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransfer callback) +{ + return callback(); +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_run_callback_return_no_ownership_transfer_nullable: + * @callback: (scope call): a callback + * + * Calls the callback and returns the newly created instance or NULL + * + * Returns: (transfer none) (nullable): a GirTestOpaqueTypedRecordCopyAnnotationTester + **/ +GirTestOpaqueTypedRecordCopyAnnotationTester * girtest_opaque_typed_record_copy_annotation_tester_run_callback_return_no_ownership_transfer_nullable(GirTestCreateOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransferNullable callback) +{ + return callback(); +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_run_callback_parameter_no_ownership_transfer: + * @callback: (scope call): a callback + * @data: (transfer none): A GirTestOpaqueTypedRecordCopyAnnotationTester + * + * Calls the callback and supplies the given OpaqueTypedRecordTester. + **/ +void +girtest_opaque_typed_record_copy_annotation_tester_run_callback_parameter_no_ownership_transfer(GirTestGetOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransfer callback, GirTestOpaqueTypedRecordCopyAnnotationTester *data) +{ + callback(data); +} + +/** + * girtest_opaque_typed_record_copy_annotation_tester_run_callback_parameter_no_ownership_transfer_nullable: + * @callback: (scope call): a callback + * @data: (transfer none) (nullable): A GirTestOpaqueTypedRecordCopyAnnotationTester + * + * Calls the callback and supplies the given OpaqueTypedRecordTester. + **/ +void +girtest_opaque_typed_record_copy_annotation_tester_run_callback_parameter_no_ownership_transfer_nullable(GirTestGetOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransferNullable callback, GirTestOpaqueTypedRecordCopyAnnotationTester *data) +{ + callback(data); +} \ No newline at end of file diff --git a/src/Native/GirTestLib/girtest-opaque-typed-record-copy-annotation-tester.h b/src/Native/GirTestLib/girtest-opaque-typed-record-copy-annotation-tester.h new file mode 100644 index 000000000..e016b2394 --- /dev/null +++ b/src/Native/GirTestLib/girtest-opaque-typed-record-copy-annotation-tester.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +G_BEGIN_DECLS + +typedef struct _GirTestOpaqueTypedRecordCopyAnnotationTester GirTestOpaqueTypedRecordCopyAnnotationTester; +#define GIRTEST_TYPE_OPAQUE_TYPED_RECORD_COPY_ANNOTATION_TESTER (girtest_opaque_typed_record_copy_annotation_tester_get_type()) + +GType girtest_opaque_typed_record_copy_annotation_tester_get_type (void) G_GNUC_CONST; + +/** + * GirTestCreateOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransfer: + * + * Returns: (transfer none): a new OpaqueRecordTester. + */ +typedef GirTestOpaqueTypedRecordCopyAnnotationTester* (*GirTestCreateOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransfer) (); + +/** + * GirTestCreateOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransferNullable: + * + * Returns: (transfer none) (nullable): a new OpaqueRecordTester or NULL. + */ +typedef GirTestOpaqueTypedRecordCopyAnnotationTester* (*GirTestCreateOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransferNullable) (); + +/** + * GirTestGetOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransfer: + * @data: (transfer none): An OpaqueTypedRecordTester + */ +typedef void (*GirTestGetOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransfer) (GirTestOpaqueTypedRecordCopyAnnotationTester *data); + +/** + * GirTestGetOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransferNullable: + * @data: (transfer none) (nullable): An OpaqueTypedRecordTester + */ +typedef void (*GirTestGetOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransferNullable) (GirTestOpaqueTypedRecordCopyAnnotationTester *data); + +GirTestOpaqueTypedRecordCopyAnnotationTester * girtest_opaque_typed_record_copy_annotation_tester_new (); +GirTestOpaqueTypedRecordCopyAnnotationTester * girtest_opaque_typed_record_copy_annotation_tester_ref (GirTestOpaqueTypedRecordCopyAnnotationTester *self); +void girtest_opaque_typed_record_copy_annotation_tester_unref (GirTestOpaqueTypedRecordCopyAnnotationTester *self); +GirTestOpaqueTypedRecordCopyAnnotationTester * girtest_opaque_typed_record_copy_annotation_tester_mirror(GirTestOpaqueTypedRecordCopyAnnotationTester *data); +GirTestOpaqueTypedRecordCopyAnnotationTester * girtest_opaque_typed_record_copy_annotation_tester_nullable_mirror(GirTestOpaqueTypedRecordCopyAnnotationTester *data, gboolean mirror); +int girtest_opaque_typed_record_copy_annotation_tester_get_ref_count(GirTestOpaqueTypedRecordCopyAnnotationTester *self); +void girtest_opaque_typed_record_copy_annotation_tester_take_and_unref(GirTestOpaqueTypedRecordCopyAnnotationTester *self); +void girtest_opaque_typed_record_copy_annotation_tester_take_and_unref_func(int dummy, GirTestOpaqueTypedRecordCopyAnnotationTester *data); +void girtest_opaque_typed_record_copy_annotation_tester_take_and_unref_func_nullable(int dummy, GirTestOpaqueTypedRecordCopyAnnotationTester *data); +GirTestOpaqueTypedRecordCopyAnnotationTester * girtest_opaque_typed_record_copy_annotation_tester_run_callback_return_no_ownership_transfer(GirTestCreateOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransfer callback); +GirTestOpaqueTypedRecordCopyAnnotationTester * girtest_opaque_typed_record_copy_annotation_tester_run_callback_return_no_ownership_transfer_nullable(GirTestCreateOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransferNullable callback); +void girtest_opaque_typed_record_copy_annotation_tester_run_callback_parameter_no_ownership_transfer(GirTestGetOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransfer callback, GirTestOpaqueTypedRecordCopyAnnotationTester *data); +void girtest_opaque_typed_record_copy_annotation_tester_run_callback_parameter_no_ownership_transfer_nullable(GirTestGetOpaqueTypedRecordCopyAnnotationTesterNoOwnershipTransferNullable callback, GirTestOpaqueTypedRecordCopyAnnotationTester *data); +G_END_DECLS diff --git a/src/Native/GirTestLib/girtest.h b/src/Native/GirTestLib/girtest.h index 28592e425..b61b1d47e 100644 --- a/src/Native/GirTestLib/girtest.h +++ b/src/Native/GirTestLib/girtest.h @@ -11,6 +11,7 @@ #include "girtest-error-tester.h" #include "girtest-integer-array-tester.h" #include "girtest-long-tester.h" +#include "girtest-opaque-typed-record-copy-annotation-tester.h" #include "girtest-opaque-typed-record-tester.h" #include "girtest-opaque-untyped-record-tester.h" #include "girtest-platform-string-array-null-terminated-tester.h" diff --git a/src/Native/GirTestLib/meson.build b/src/Native/GirTestLib/meson.build index 3c2a0e9f9..e6785dc24 100644 --- a/src/Native/GirTestLib/meson.build +++ b/src/Native/GirTestLib/meson.build @@ -14,6 +14,7 @@ header_files = [ 'girtest-error-tester.h', 'girtest-integer-array-tester.h', 'girtest-long-tester.h', + 'girtest-opaque-typed-record-copy-annotation-tester.h', 'girtest-opaque-typed-record-tester.h', 'girtest-opaque-untyped-record-tester.h', 'girtest-platform-string-array-null-terminated-tester.h', @@ -42,6 +43,7 @@ source_files = [ 'girtest-error-tester.c', 'girtest-integer-array-tester.c', 'girtest-long-tester.c', + 'girtest-opaque-typed-record-copy-annotation-tester.c', 'girtest-opaque-typed-record-tester.c', 'girtest-opaque-untyped-record-tester.c', 'girtest-platform-string-array-null-terminated-tester.c', diff --git a/src/Tests/Libs/GirTest-0.1.Tests/OpaqueTypedRecordCopyAnnotationTest.cs b/src/Tests/Libs/GirTest-0.1.Tests/OpaqueTypedRecordCopyAnnotationTest.cs new file mode 100644 index 000000000..45146f19c --- /dev/null +++ b/src/Tests/Libs/GirTest-0.1.Tests/OpaqueTypedRecordCopyAnnotationTest.cs @@ -0,0 +1,146 @@ +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace GirTest.Tests; + +[TestClass, TestCategory("BindingTest")] +public class OpaqueTypedRecordCopyAnnotationTest : Test +{ + [TestMethod] + public void ImplementsIDisposable() + { + var recordTester = OpaqueTypedRecordCopyAnnotationTester.New(); + recordTester.Dispose(); + } + + [TestMethod] + public void SupportsReturnValueTransferNone() + { + var recordTester = OpaqueTypedRecordCopyAnnotationTester.New(); + var recordTester2 = recordTester.Mirror(); + + recordTester.GetRefCount().Should().Be(2); + recordTester2.GetRefCount().Should().Be(2); + + recordTester.Handle.DangerousGetHandle().Should().Be(recordTester2.Handle.DangerousGetHandle()); + } + + [TestMethod] + public void SupportsReturnValueNullableTransferNone() + { + var recordTester = OpaqueTypedRecordCopyAnnotationTester.New(); + var recordTester2 = recordTester.NullableMirror(true); + + recordTester.GetRefCount().Should().Be(2); + recordTester2!.GetRefCount().Should().Be(2); + + recordTester.Handle.DangerousGetHandle().Should().Be(recordTester2.Handle.DangerousGetHandle()); + + var recordTester3 = recordTester.NullableMirror(false); + recordTester3.Should().BeNull(); + } + + [TestMethod] + public void SupportsInstanceParameterTransferFull() + { + var recordTester = OpaqueTypedRecordCopyAnnotationTester.New(); + recordTester.GetRefCount().Should().Be(1); + recordTester.TakeAndUnref(); + recordTester.GetRefCount().Should().Be(1); + } + + [TestMethod] + public void SupportsParameterTransferFull() + { + var recordTester = OpaqueTypedRecordCopyAnnotationTester.New(); + recordTester.GetRefCount().Should().Be(1); + OpaqueTypedRecordCopyAnnotationTester.TakeAndUnrefFunc(0, recordTester); + recordTester.GetRefCount().Should().Be(1); + } + + [TestMethod] + public void SupportsParameterNullableTransferFull() + { + var recordTester = OpaqueTypedRecordCopyAnnotationTester.New(); + recordTester.GetRefCount().Should().Be(1); + OpaqueTypedRecordCopyAnnotationTester.TakeAndUnrefFuncNullable(0, recordTester); + recordTester.GetRefCount().Should().Be(1); + + OpaqueTypedRecordCopyAnnotationTester.TakeAndUnrefFuncNullable(0, null); + } + + [TestMethod] + public void SupportsCallbackReturnNoOwnershipTransfer() + { + var recordTester = OpaqueTypedRecordCopyAnnotationTester.New(); + + OpaqueTypedRecordCopyAnnotationTester Create() + { + return recordTester; + } + + var recordTester2 = OpaqueTypedRecordCopyAnnotationTester.RunCallbackReturnNoOwnershipTransfer(Create); + + recordTester.GetRefCount().Should().Be(2); + recordTester2.GetRefCount().Should().Be(2); + recordTester.Handle.DangerousGetHandle().Should().Be(recordTester2.Handle.DangerousGetHandle()); + } + + [DataTestMethod] + [DataRow(true)] + [DataRow(false)] + public void SupportsCallbackReturnNoOwnershipTransferNullable(bool useNull) + { + OpaqueTypedRecordCopyAnnotationTester? Create() + { + return useNull ? null : OpaqueTypedRecordCopyAnnotationTester.New(); + } + + var recordTester2 = OpaqueTypedRecordCopyAnnotationTester.RunCallbackReturnNoOwnershipTransferNullable(Create); + if (useNull) + recordTester2.Should().BeNull(); + else + recordTester2.Should().NotBeNull(); + } + + [TestMethod] + public void SupportsCallbackParameterNoOwnershipTransfer() + { + var recordTester = OpaqueTypedRecordCopyAnnotationTester.New(); + var called = false; + + void Callback(OpaqueTypedRecordCopyAnnotationTester obj) + { + obj.GetRefCount().Should().Be(2); + obj.Handle.DangerousGetHandle().Should().Be(recordTester.Handle.DangerousGetHandle()); + called = true; + } + + OpaqueTypedRecordCopyAnnotationTester.RunCallbackParameterNoOwnershipTransfer(Callback, recordTester); + + called.Should().BeTrue(); + } + + [DataTestMethod] + [DataRow(true)] + [DataRow(false)] + public void SupportsCallbackParameterNoOwnershipTransferNullable(bool useNull) + { + var recordTester = useNull ? null : OpaqueTypedRecordCopyAnnotationTester.New(); + var called = false; + + void Callback(OpaqueTypedRecordCopyAnnotationTester? obj) + { + (obj is null).Should().Be(useNull); + + if (!useNull) + obj!.GetRefCount().Should().Be(2); + + called = true; + } + + OpaqueTypedRecordCopyAnnotationTester.RunCallbackParameterNoOwnershipTransferNullable(Callback, recordTester); + + called.Should().BeTrue(); + } +} diff --git a/src/Tests/Libs/GirTest-0.1.Tests/OpaqueTypedRecordTest.cs b/src/Tests/Libs/GirTest-0.1.Tests/OpaqueTypedRecordTest.cs index e4f73fdcc..070a57275 100644 --- a/src/Tests/Libs/GirTest-0.1.Tests/OpaqueTypedRecordTest.cs +++ b/src/Tests/Libs/GirTest-0.1.Tests/OpaqueTypedRecordTest.cs @@ -7,6 +7,13 @@ namespace GirTest.Tests; [TestClass, TestCategory("BindingTest")] public class OpaqueTypedRecordTest : Test { + [TestMethod] + public void ImplementsIDisposable() + { + var recordTester = OpaqueTypedRecordCopyAnnotationTester.New(); + recordTester.Dispose(); + } + [TestMethod] public void SupportsConstructorTransferFull() {