xamarin / xamarin-macios

.NET for iOS, Mac Catalyst, macOS, and tvOS provide open-source bindings of the Apple SDKs for use with .NET managed languages such as C#
Other
2.49k stars 515 forks source link

Setting SCNAction.TimingFunction to null does not read back as null #5072

Open spouliot opened 6 years ago

spouliot commented 6 years ago

Steps to Reproduce

  1. Uncomment part of ActionTest.cs
diff --git a/tests/monotouch-test/SceneKit/ActionTest.cs b/tests/monotouch-test/SceneKit/ActionTest.cs
index 76c6b808..026cc487 100644
--- a/tests/monotouch-test/SceneKit/ActionTest.cs
+++ b/tests/monotouch-test/SceneKit/ActionTest.cs
@@ -35,9 +35,10 @@ namespace MonoTouchFixtures.SceneKit {
                        Assert.That (timeFunctionValue, Is.NaN, "TimingFunction assigned from TimingFunction2");
 #endif
                        a.TimingFunction2 = null;
-                       Assert.Null (a.TimingFunction2, "TimingFunction2-end");
+                       // 
+                       // Assert.Null (a.TimingFunction2, "TimingFunction2-end");
 #if !XAMCORE_4_0
-                       Assert.Null (a.TimingFunction, "TimingFunction-end");
+                       // Assert.Null (a.TimingFunction, "TimingFunction-end");
 #endif
                }
        }
  1. Run monotouch-test

Expected Behavior

After setting TimingFunction to null we should read the delegate as null.

Actual Behavior

It's non null

Environment

xamarin-macios/master

spouliot commented 6 years ago

Note that it's internally null but it's not exposed as such. E.g. trying to call a.TimingFunction2 (Single.NaN) after setting it to null gives us the NullReferenceException we expect but not where we expect it.

2018-11-01 15:33:54.770072-0400 monotouchtest[86026:2587998]    [FAIL] ActionTest.TimingFunction_5058 : System.NullReferenceException : Object reference not set to an instance of an object
2018-11-01 15:33:54.770341-0400 monotouchtest[86026:2587998]          at ObjCRuntime.Trampolines+SDFuncArity2V5.Invoke (System.IntPtr block, System.Single arg) [0x00012] in /Users/poupou/git/master/xamarin-macios/src/build/ios/native/ObjCRuntime/Trampolines.g.cs:33921
2018-11-01 15:33:54.770543-0400 monotouchtest[86026:2587998]          at (wrapper delegate-invoke) <Module>.invoke_single_intptr_single(intptr,single)
2018-11-01 15:33:54.770729-0400 monotouchtest[86026:2587998]          at ObjCRuntime.Trampolines+NIDFuncArity2V5.Invoke (System.Single arg) [0x00000] in /Users/poupou/git/master/xamarin-macios/src/build/ios/native/ObjCRuntime/Trampolines.g.cs:33963
2018-11-01 15:33:54.770901-0400 monotouchtest[86026:2587998]          at MonoTouchFixtures.SceneKit.ActionTest.TimingFunction_5058 () [0x00095] in /Users/poupou/git/master/xamarin-macios/tests/monotouch-test/SceneKit/ActionTest.cs:38
2018-11-01 15:33:54.771061-0400 monotouchtest[86026:2587998]          at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
2018-11-01 15:33:54.771224-0400 monotouchtest[86026:2587998]          at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0003b] in /Users/poupou/git/master/xamarin-macios/external/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:305
rolfbjarne commented 2 years ago

Looks like this is a bug in the generator, the generated code doesn't consider that the value parameter in the setter can be null:

[Export ("setTimingFunction:", ArgumentSemantic.UnsafeUnretained)]
set {
    BlockLiteral *block_ptr_value;
    BlockLiteral block_value;
    block_value = new BlockLiteral ();
    block_ptr_value = &block_value;
    block_value.SetupBlockUnsafe (Trampolines.SDFuncArity2V6.Handler, value);
    if (IsDirectBinding) {
        global::ObjCRuntime.Messaging.void_objc_msgSend_NativeHandle (this.Handle, Selector.GetHandle ("setTimingFunction:"), (IntPtr) block_ptr_value);
    } else {
        global::ObjCRuntime.Messaging.void_objc_msgSendSuper_NativeHandle (this.SuperHandle, Selector.GetHandle ("setTimingFunction:"), (IntPtr) block_ptr_value);
    }
    block_ptr_value->CleanupBlock ();
}