LoadXNB can't find reader type

Jun 10, 2010 at 1:59 AM
Edited Jun 10, 2010 at 10:13 PM
Hello, It seems your project seems to be missing an Enum reader. I will try and add my own (and post here if i can) but an official one would be appreciated. Thanks :) Edit: If anyone needs it. Just add it to namespace Microsoft.Xna.Framework.Content. [code] internal class EnumReader<T> : ContentTypeReader<T> where T : struct, IConvertible { // Fields private ContentTypeReader underlyingTypeReader; // Methods protected internal override void Initialize(ContentTypeReaderManager manager) { Type underlyingType = Enum.GetUnderlyingType(typeof(T)); this.underlyingTypeReader = manager.GetTypeReader(underlyingType); } protected internal override T Read(ContentReader input, T existingInstance) { return (T)input.ReadRawObject<object>(this.underlyingTypeReader); } }[/code] This is not my code, so don't credit me.
Jul 2, 2010 at 9:09 PM

Hi MrMo. Thanks for the code. In order to get this to work with the latest build, ContentReader.ReadRawObject<T>() methods need to be implemented. So (with some help from .NET reflector) here they are.

 

        public T ReadRawObject<T>()
        {
            ContentTypeReader typeReader = ContentTypeReaderManager.GetTypeReader(typeof(T), this);
            return (T)typeReader.Read(this, default(T));
        }

        public T ReadRawObject<T>(ContentTypeReader typeReader)
        {
            if (typeReader == null)
            {
                throw new ArgumentNullException("typeReader");
            }
            return (T)typeReader.Read(this, default(T));
        }

        public T ReadRawObject<T>(T existingInstance)
        {
            ContentTypeReader typeReader = ContentTypeReaderManager.GetTypeReader(typeof(T), this);
            return (T)typeReader.Read(this, existingInstance);
        }

        public T ReadRawObject<T>(ContentTypeReader typeReader, T existingInstance)
        {
            if (typeReader == null)
            {
                throw new ArgumentNullException("typeReader");
            }
            return (T)typeReader.Read(this, existingInstance);
        }


I needed a dictionary too so here's a reader for that in case anyone wants it.

    internal class DictionaryReader<TKey, TValue> : ContentTypeReader<Dictionary<TKey, TValue>>
    {
        ContentTypeReader keyReader;
        ContentTypeReader valueReader;

        public DictionaryReader()
        {
        }

        protected internal override void Initialize(ContentTypeReaderManager manager)
        {
            this.keyReader = manager.GetTypeReader(typeof(TKey));
            this.valueReader = manager.GetTypeReader(typeof(TValue));
        }


        protected internal override Dictionary<TKey, TValue> Read(ContentReader input, Dictionary<TKey, TValue> existingInstance)
        {
            Dictionary<TKey, TValue> dictionary = existingInstance;
            if (dictionary == null) dictionary = new Dictionary<TKey, TValue>();

            int count = input.ReadInt32();
            for (int i = 0; i < count; i++)
            {
                dictionary.Add(input.ReadObject<TKey>(keyReader, default(TKey)), input.ReadObject<TValue>(valueReader, default(TValue)));
            }

            return dictionary;
        }
    }


Also I ran into a small bug when trying to read my level file. In ContentTypeReader<T>.Read(ContentReader, object)
sometimes the existingInstance comes in null and can't be cast to a generic type so use default(T).

protected internal override object Read(ContentReader input, object existingInstance)
        {
            if (existingInstance == null)
                return Read(input, default(T));
            else
                return Read(input, (T)existingInstance);
        }


Being new here I just want to say thanks for SilverSprite, it's awesome. I still have some bugs trying to load custom content
and I know it's still a work in process so I'll to make a new thread for it.