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

Bug on IOS device`s #47

Closed
xICELIFEx opened this issue Nov 16, 2017 · 2 comments
Closed

Bug on IOS device`s #47

xICELIFEx opened this issue Nov 16, 2017 · 2 comments

Comments

@xICELIFEx
Copy link

xICELIFEx commented Nov 16, 2017

Hello,

found an issue on iOS device.

Here is a code from the file IFormatterResolver.cs:

public static IMessagePackFormatter<T> GetFormatterWithVerify<T>(this IFormatterResolver resolver)
        {
            IMessagePackFormatter<T> formatter;
            try
            {
                formatter = resolver.GetFormatter<T>();
            }
            catch (TypeInitializationException ex)
            {
                Exception inner = ex;
                while (inner.InnerException != null)
                {
                    inner = inner.InnerException;
                }

                throw inner;
            }

            if (formatter == null)
            {
                throw new FormatterNotRegisteredException(typeof(T).FullName + " is not registered in this resolver. resolver:" + resolver.GetType().Name);
            }

            return formatter;
        }
That calls an exception when trying to get an object from server response:

if (formatter == null)
            {
                throw new FormatterNotRegisteredException(typeof(T).FullName + " is not registered in this resolver. resolver:" + resolver.GetType().Name);
            }

On other platforms everything works fine though.

@neuecc
Copy link
Member

neuecc commented Nov 16, 2017

This is about MessagePack for C# and you need pre code generation.
https://github.com/neuecc/MessagePack-CSharp/#pre-code-generationunityxamarin-supports

@xICELIFEx
Copy link
Author

xICELIFEx commented Nov 16, 2017

For code generation I’m using moc.exe (https://github.com/neuecc/MagicOnion#unity-supports) That generates the following:
#pragma warning disable 618
#pragma warning disable 612
#pragma warning disable 414
#pragma warning disable 168

namespace MagicOnion.Resolvers
{
using System;
using MessagePack;

public class MagicOnionResolver : global::MessagePack.IFormatterResolver
{
    public static readonly global::MessagePack.IFormatterResolver Instance = new MagicOnionResolver();

    MagicOnionResolver()
    {

    }

    public global::MessagePack.Formatters.IMessagePackFormatter<T> GetFormatter<T>()
    {
        return FormatterCache<T>.formatter;
    }

    static class FormatterCache<T>
    {
        public static readonly global::MessagePack.Formatters.IMessagePackFormatter<T> formatter;

        static FormatterCache()
        {
            var f = MagicOnionResolverGetFormatterHelper.GetFormatter(typeof(T));
            if (f != null)
            {
                formatter = (global::MessagePack.Formatters.IMessagePackFormatter<T>)f;
            }
        }
    }
}

internal static class MagicOnionResolverGetFormatterHelper
{
    static readonly global::System.Collections.Generic.Dictionary<Type, int> lookup;

    static MagicOnionResolverGetFormatterHelper()
    {
        lookup = new global::System.Collections.Generic.Dictionary<Type, int>(4)
        {
            {typeof(global::MagicOnion.DynamicArgumentTuple<int, int[]>), 0 },
            {typeof(global::MagicOnion.DynamicArgumentTuple<string, string, string, string>), 1 },
            {typeof(global::MagicOnion.DynamicArgumentTuple<string, string>), 2 },
            {typeof(global::Definitions.Shared.SumType), 3 },
        };
    }

    internal static object GetFormatter(Type t)
    {
        int key;
        if (!lookup.TryGetValue(t, out key))
        {
            if (t == typeof(UniRx.Unit))
            {
                return MagicOnion.Resolvers.UniRxIntegrate.UnitFormatter.Instance;
            }
            else if (t == typeof(Nullable<UniRx.Unit>))
            {
                return MagicOnion.Resolvers.UniRxIntegrate.NullableUnitFormatter.Instance;
            }
            return null;
        }

        switch (key)
        {
            case 0: return new global::MagicOnion.DynamicArgumentTupleFormatter<int, int[]>(default(int), default(int[]));
            case 1: return new global::MagicOnion.DynamicArgumentTupleFormatter<string, string, string, string>(default(string), default(string), default(string), default(string));
            case 2: return new global::MagicOnion.DynamicArgumentTupleFormatter<string, string>(default(string), default(string));
            case 3: return new MagicOnion.Formatters.Sumwcl.Definitions.Shared.SumTypeFormatter();
            default: return null;
        }
    }
}

}

namespace MagicOnion.Resolvers.UniRxIntegrate
{
using System;
using UniRx;
using MessagePack;
using MessagePack.Formatters;

public class UnitFormatter : IMessagePackFormatter<Unit>
{
    public static readonly IMessagePackFormatter<Unit> Instance = new UnitFormatter();

    UnitFormatter()
    {

    }

    public int Serialize(ref byte[] bytes, int offset, Unit value, IFormatterResolver typeResolver)
    {
        return MessagePackBinary.WriteNil(ref bytes, offset);
    }

    public Unit Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
    {
        if (bytes[offset] == MessagePackCode.Nil)
        {
            readSize = 1;
            return Unit.Default;
        }
        else
        {
            throw new InvalidOperationException(string.Format("code is invalid. code:{0} format:{1}", bytes[offset], MessagePackCode.ToFormatName(bytes[offset])));
        }
    }
}

public class NullableUnitFormatter : IMessagePackFormatter<Unit?>
{
    public static readonly IMessagePackFormatter<Unit?> Instance = new NullableUnitFormatter();

    NullableUnitFormatter()
    {

    }

    public int Serialize(ref byte[] bytes, int offset, Unit? value, IFormatterResolver typeResolver)
    {
        return MessagePackBinary.WriteNil(ref bytes, offset);
    }

    public Unit? Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
    {
        if (bytes[offset] == MessagePackCode.Nil)
        {
            readSize = 1;
            return Unit.Default;
        }
        else
        {
            throw new InvalidOperationException(string.Format("code is invalid. code:{0} format:{1}", bytes[offset], MessagePackCode.ToFormatName(bytes[offset])));
        }
    }
}

}

#pragma warning disable 168
#pragma warning restore 414
#pragma warning restore 618
#pragma warning restore 612

As a result, the following code appears on all platforms (PC(Editor), Mac(Editor), Android(Device)):

public static IMessagePackFormatter GetFormatterWithVerify(this IFormatterResolver resolver)
{
IMessagePackFormatter formatter;
try
{
formatter = resolver.GetFormatter();
}
catch (TypeInitializationException ex)
{
Exception inner = ex;
while (inner.InnerException != null)
{
inner = inner.InnerException;
}

            throw inner;
        }
        
        if (formatter == null)
        {
            throw new FormatterNotRegisteredException(typeof(T).FullName + " is not registered in this resolver. resolver:" + resolver.GetType().Name);
        }

        return formatter;
    }

**For my model (Definitions.Models.MyModel), from the resolver (CompositeResolver)
It returns the formatter Definitions_Models_MyModelFormatter .

But on IOS device, it returns null for the same model (Definitions.Models.MyModel) from the same resolver (CompositeResolver).**

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants