2010-10-21

Problems Deploying to iPhone

Sorry for the brief hiatus, I was on a business trip to Beijing for 1 week, but I'm back now and hope to get back into the swing of developing.

In my last post I discussed how I got OpenAL working on Windows. After that I wanted to confirm that all my platform independent abstractions worked correctly on the iPhone but going back to my Mac and building and deploying there. Unfortunately, when I did that, I ran into a few issues. This post discusses that experience.

The first error I received was mtouch failed with no output (1). After a bit of searching on the web I found a few hints about not allowing spaces in the output assembly name. I changed some settings to correct this, but the problem persisted.

I looked at the command being from by MonoTouch and noticed other areas in the command were not escaping or quoting some paths. Initially I was accessing my project over a Samba share directly to my Windows Documents directory. This meant that I was opening the project on my Mac from Documents\visual studio 2010\Projects\Zoing. Notice the spaces in "visual studio 2010".

To fix this I changed how I mounted the Samba share to directly mount the Zoing directory, thus skipping the areas with spaces. After doing this I could deploy to my iPhone. Joy!

Well, no, actually not. As soon as I ran the program I got this:
Tue Sep 28 23:46:25 unknown kernel[0] <Debug>: launchd[9744] Builtin profile: container (sandbox) Tue Sep 28 23:46:25 unknown kernel[0] <Debug>: launchd[9744] Container: /private/var/mobile/Applications/478863D8-A953-4D5A-84FD-AF8C096DC363 [69] (sandbox) Tue Sep 28 23:46:27 unknown UIKitApplication:launcher[0x114c][9744] <Notice>: Unhandled Exception: System.TypeInitializationException: An exception was thrown by the type initializer for System.Collections.Generic.EqualityComparer`1 ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ExecutionEngineException: Attempting to JIT compile method 'System.Collections.Generic.GenericEqualityComparer`1<OpenTK.Vector2>:.ctor ()' while running with --aot-only.
Tue Sep 28 23:46:27 unknown UIKitApplication:launcher[0x114c][9744] <Notice>: at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
Tue Sep 28 23:46:27 unknown UIKitApplication:launcher[0x114c][9744] <Notice>: --- End of inner exception stack trace ---

The highlighted areas point to the important part. Basically, for some reason, MonoTouch, on the actual iPhone (it works fine in the simulator) does not support default EqualityComparers properly. Fortunately, I can pass in a IEqualityComparer<T> to the Dictionary constructor, like so:
_diagonals = new Dictionary<Vector2, Diagonal>(VectorComparer.Singleton);

And, my VectorComparer implementation is:
private class VectorComparer : IEqualityComparer<Vector2>
{
    private static VectorComparer _singleton = new VectorComparer();
    public static VectorComparer Singleton
    {
        get
        {
            return _singleton;
        }
    }
    public bool Equals(Vector2 x, Vector2 y)
    {
        return x.Equals(y);
    }
    public int GetHashCode(Vector2 obj)
    {
        return obj.GetHashCode();
    }
}

Currently, for my purposes, this implementation is fine because I know I'm only putting in Vector2 objects with values that are precise as a float. If I expect to want to compare Vector2 objects where, because of math rounding, the values may not be so precise I could adjust my comparisons to have some level of necessary precision to consider the values equal.

Next time: Optimizing .NET on the iPhone.

No comments:

Post a Comment