craftworkgames / MonoGame.Extended

Extensions to make MonoGame more awesome
http://www.monogameextended.net/
Other
1.44k stars 325 forks source link

MessagePack serialization error: MethodAccessException: Attempt by method X to access method Y failed #758

Closed dclipca closed 2 years ago

dclipca commented 2 years ago

Trying to serialize an instance of an Entity with MessagePack:

var testEntity = _world.CreateEntity();
var testEntityS = MessagePackSerializer.Serialize(testEntity);
var testEntityD = MessagePackSerializer.Deserialize<Entity>(testEntityS);
[MessagePackObject]
    public class Entity : IEquatable<Entity>
    {
        [Key(1)]
        public readonly EntityManager _entityManager;
        [Key(2)]
        public readonly ComponentManager _componentManager;

        [SerializationConstructor]
        internal Entity(int id, EntityManager entityManager, ComponentManager componentManager)
        {
            Id = id;

            _entityManager = entityManager;
            _componentManager = componentManager;
        }

        [Key(0)]
        public int Id { get; }

        [IgnoreMember]
        public BitVector32 ComponentBits => _entityManager.GetComponentBits(Id);

        public void Attach<T>(T component)
            where T : class 
        {
            var mapper = _componentManager.GetMapper<T>();
            mapper.Put(Id, component);
        }

        public void Detach<T>()
            where T : class
        {
            var mapper = _componentManager.GetMapper<T>();
            mapper.Delete(Id);
        }

        public T Get<T>()
            where T : class 
        {
            var mapper = _componentManager.GetMapper<T>();
            return mapper.Get(Id);
        }

        public bool Has<T>() 
            where T : class
        {
            return _componentManager.GetMapper<T>().Has(Id);
        }

        public void Destroy()
        {
            _entityManager.Destroy(Id);
        }

        public bool Equals(Entity other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Id == other.Id;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != GetType()) return false;
            return Equals((Entity) obj);
        }

        public override int GetHashCode()
        {
            // ReSharper disable once NonReadonlyMemberInGetHashCode
            return Id;
        }

        public static bool operator ==(Entity left, Entity right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(Entity left, Entity right)
        {
            return !Equals(left, right);
        }
    }
MethodAccessException: Attempt by method 'MessagePack.Formatters.MonoGame_Extended_Entities_EntityFormatter3.Deserialize(MessagePack.MessagePackReader ByRef, MessagePack.MessagePackSerializerOptions)' to access method 'MonoGame.Extended.Entities.Entity..ctor(Int32, MonoGame.Extended.Entities.EntityManager, MonoGame.Extended.Entities.ComponentManager)' failed.

I have hard time interpreting an useful meaning for this error. What does it mean and how can I fix this?

lithiumtoast commented 2 years ago

I have not used MessagePack in a long time. If I had to guess it's because the constructor is internal. Have you tried turning to to public modifier?

dclipca commented 2 years ago

I have not used MessagePack in a long time. If I had to guess it's because the constructor is internal. Have you tried turning to to public modifier?

Indeed that was it. Thank you very much!