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

[NearbyInteraction][Xcode12] Add manual binding for NINearbyObjectDirectionNotAvailable #9346

Merged
merged 12 commits into from
Aug 12, 2020

Conversation

whitneyschmidt
Copy link
Contributor

Add manual binding for NINearbyObject NINearbyObjectDirectionNotAvailable.

This should be updated again when we have support in for https://github.com/xamarin/maccore/issues/2274

@monojenkins
Copy link
Collaborator

Build failure
Build failed or was aborted

@dalexsoto
Copy link
Member

I think we need a test for this, maybe you can inspect the native values and make sure we match those on our side

Copy link
Member

@dalexsoto dalexsoto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need this fix also I really encourage you to have a test :)

src/frameworks.sources Outdated Show resolved Hide resolved
@monojenkins
Copy link
Collaborator

Build failure
Build failed or was aborted

Build succeeded
API Diff (from stable)
⚠️ API Diff (from PR only) (🔥 breaking changes 🔥)
ℹ️ Generator Diff (please review changes)

@whitneyschmidt
Copy link
Contributor Author

I think we need a test for this, maybe you can inspect the native values and make sure we match those on our side

I did the following:

Xcode:

vector_float3 vectVals = NINearbyObjectDirectionNotAvailable; 
//vectValues = (1.28042596E-19, 4.59163468E-41, 0, 0)
Vector3 vect = NINearbyObject.NINearbyObjectDirectionNotAvailable;
// vect = {0, 0, 0} (w/ 0 for length scalar)

Do these "match" if the ObjC values are so small?

@monojenkins
Copy link
Collaborator

Build success
Build succeeded
API Diff (from stable)
⚠️ API Diff (from PR only) (🔥 breaking changes 🔥)
ℹ️ Generator Diff (please review changes)
Test run succeeded

@rolfbjarne
Copy link
Member

I think we need a test for this, maybe you can inspect the native values and make sure we match those on our side

I did the following:

Xcode:

vector_float3 vectVals = NINearbyObjectDirectionNotAvailable; 
//vectValues = (1.28042596E-19, 4.59163468E-41, 0, 0)
Vector3 vect = NINearbyObject.NINearbyObjectDirectionNotAvailable;
// vect = {0, 0, 0} (w/ 0 for length scalar)

Do these "match" if the ObjC values are so small?

Hm, no, I think we'd need to be exactly the same. Maybe printing out and comparing the memory contents?

vector_float3* v = & NINearbyObjectDirectionNotAvailable;
uint8_t* ptr = (uint8_t*) v;
for (int i = 0; i < sizeof (vector_float3); i++) {
    printf ("%.2x ", ptr [i]);
}
printf ("\n");
Vector3 vect = NINearbyObject.NINearbyObjectDirectionNotAvailable;
unsafe {
    Vector3 *v = &vect;
    byte *ptr = (byte *) v;
    for (var i = 0; i < sizeof (Vector3); i++)
        Console.WriteLine ($"{ptr [i]:X2} ");
    Console.WriteLine ();
}

Copy link
Contributor

@spouliot spouliot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since it's a manual API it should come with a unit test

// TODO: https://github.com/xamarin/maccore/issues/2274
// We do not have generator support to trampoline Vector3 -> vector_float3 for Fields
[Field ("NINearbyObjectDirectionNotAvailable", "NearbyInteraction")]
public static Vector3 NINearbyObjectDirectionNotAvailable {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove NINearbyObject prefix since it's the current type name -> ObjectDirectionNotAvailable

_NINearbyObjectDirectionNotAvailable = *pointer;
}
}
return (OpenTK.Vector3)_NINearbyObjectDirectionNotAvailable;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: that could be (Vector3)

@whitneyschmidt
Copy link
Contributor Author

I think we need a test for this, maybe you can inspect the native values and make sure we match those on our side

I did the following:
Xcode:

vector_float3 vectVals = NINearbyObjectDirectionNotAvailable; 
//vectValues = (1.28042596E-19, 4.59163468E-41, 0, 0)
Vector3 vect = NINearbyObject.NINearbyObjectDirectionNotAvailable;
// vect = {0, 0, 0} (w/ 0 for length scalar)

Do these "match" if the ObjC values are so small?

Hm, no, I think we'd need to be exactly the same. Maybe printing out and comparing the memory contents?

vector_float3* v = & NINearbyObjectDirectionNotAvailable;
uint8_t* ptr = (uint8_t*) v;
for (int i = 0; i < sizeof (vector_float3); i++) {
    printf ("%.2x ", ptr [i]);
}
printf ("\n");
Vector3 vect = NINearbyObject.NINearbyObjectDirectionNotAvailable;
unsafe {
    Vector3 *v = &vect;
    byte *ptr = (byte *) v;
    for (var i = 0; i < sizeof (Vector3); i++)
        Console.WriteLine ($"{ptr [i]:X2} ");
    Console.WriteLine ();
}

Thanks @rolfbjarne - I was able to test these out and the byte-by-byte values in memory are all 00, from VS as well as Xcode 👍

// Authors:
// Whitney Schmidt <[email protected]>
//
// Copyright 2020 Microsoft Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: it's not Inc. it's Corp. ;-)

byte* ptr = (byte*) v;
byte zero = 0;
for (var i = 0; i < sizeof (Vector3); i++)
Assert.True (ptr[i] == zero, "Expected {0} but was {1}", zero.ToString(), ptr[i].ToString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor:

  • style, missing space before ( (twice)
  • zero.ToString() allocates and it's a constant in the loop
  • the assert error will tell you a byte is not 0 but won't tell you where it is (I)
Assert.That (ptr [i], Is.EqualTo (zero), $"Position {i}");

The above assert will provide the expected and actual values (and turn them to string only if needed/failing) so the only missing part (to diagnose the failure) is the position i.

public void DirectionNotAvailable ()
{
if (!TestRuntime.CheckXcodeVersion (12, 0))
Assert.Ignore ("Requires iOS 14.0");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a special case but, since it's all 0 and C# struct are zeroized then the test should work even before iOS 14.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried running on iOS 13.2 w/o the version check and received the following error:

2020-08-11 13:55:20.518482-0400 monotouchtest[43690:16037527] [FAIL] NINearbyObjectTest.DirectionNotAvailable : System.NullReferenceException : Object reference not set to an instance of an object

Since NearbyInteraction is a new framework in Xcode12, I think this is expected.

I also tried out the following to double-check:

NSCoder coder = new NSCoder ();
NINearbyObject n = new NINearbyObject (coder);

It produced this error:
[FAIL] NINearbyObjectTest.DirectionNotAvailable : System.Exception : Could not create an native instance of the type 'NearbyInteraction.NINearbyObject': the native class hasn't been loaded.

I believe this is correct behavior since the framework isn't available < iOS 14, lmk if I'm missing something here!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NINearbyObjectTest.DirectionNotAvailable : System.NullReferenceException : Object reference not set to an instance of an object

Reading a field with dlsym does not require the field to exists - but maybe it did not like not finding the framework itself. The stack trace would show what cause the NRE.

Anyway not a huge deal, you can leave the version check there :)

NSCoder coder = new NSCoder ();
NINearbyObject n = new NINearbyObject (coder);

I believe this is correct behavior since the framework isn't available < iOS 14

Yes. You can't do as it will call code initWithCoder on a class (NINearbyObject) that has not been loaded into memory.

However the field is different since it's static (no instance has to be created) and return a type (Vector3) that already exists. Nothing in your manual code requires the framework to be loaded. In fact it should work (a managed exception is acceptable, not a crash) if someone was to put NINearbyObject.DirectionNotAvailable in a debugger watch on an older OS version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense - if there's no need to instantiate an object to access the field, then I see how it would work.

Someone tried it out on an older simulator and got this stack trace: https://gist.github.com/whitneyschmidt/e5d239d4f83473d29244c7cee86adcf3

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stack trace seems incomplete. The first frame is inside nunitlite code, nothing about the test code itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a breakpoint set on Vector3 vect = NINearbyObject.DirectionNotAvailable;. When I try and step into it, I end up with the stack trace above 🤔 Is there a better way to try and see what's going on?

@monojenkins
Copy link
Collaborator

Build failure
Build failed or was aborted

Build succeeded
API Diff (from stable)
⚠️ API Diff (from PR only) (🔥 breaking changes 🔥)
ℹ️ Generator Diff (please review changes)

Copy link
Member

@mandel-macaque mandel-macaque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 once @spouliot concerns are addressed.

@monojenkins
Copy link
Collaborator

Build failure
Build succeeded
API Diff (from stable)
⚠️ API Diff (from PR only) (🔥 breaking changes 🔥)
ℹ️ Generator Diff (please review changes)
🔥 Test run failed 🔥

Test results

8 tests failed, 68 tests passed.

Failed tests

  • monotouch-test/tvOS - simulator/Debug: BuildFailure
  • monotouch-test/tvOS - simulator/Debug (LinkSdk): BuildFailure
  • monotouch-test/tvOS - simulator/Debug (static registrar): BuildFailure
  • monotouch-test/tvOS - simulator/Release (all optimizations): BuildFailure
  • monotouch-test/watchOS 32-bits - simulator/Debug: BuildFailure
  • monotouch-test/watchOS 32-bits - simulator/Debug (LinkSdk): BuildFailure
  • monotouch-test/watchOS 32-bits - simulator/Debug (static registrar): BuildFailure
  • monotouch-test/watchOS 32-bits - simulator/Release (all optimizations): BuildFailure

Copy link
Member

@rolfbjarne rolfbjarne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines 21 to 22
if (!TestRuntime.CheckXcodeVersion (12, 0))
Assert.Ignore ("Requires iOS 14.0");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really minor, so no need to fix this, but for the future this is shorter:

Suggested change
if (!TestRuntime.CheckXcodeVersion (12, 0))
Assert.Ignore ("Requires iOS 14.0");
TestRuntime.AssertXcodeVersion (12, 0);

@spouliot
Copy link
Contributor

Tests failures are due to the new test being executed on tvOS and watchOS, both not supporting ARKit.
Wrap your source file inside #if __IOS__ and #endif to exclude other platforms.

@monojenkins
Copy link
Collaborator

Build success
Build succeeded
API Diff (from stable)
⚠️ API Diff (from PR only) (🔥 breaking changes 🔥)
ℹ️ Generator Diff (please review changes)
Test run succeeded

@whitneyschmidt whitneyschmidt merged commit fb665c8 into xamarin:xcode12 Aug 12, 2020
@spouliot spouliot mentioned this pull request Aug 12, 2020
46 tasks
@whitneyschmidt whitneyschmidt added iOS Issues affecting iOS notes-mention Deserves a mention in release notes labels Sep 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
iOS Issues affecting iOS notes-mention Deserves a mention in release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants