XNA Creators Club Online
Page 1 of 1 (10 items)
Sort Posts: Previous Next

Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

Last post 26/04/2009 5:14 by David Hunt. 9 replies.
  • 24/04/2009 14:43

    Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

    I was trying to read two composite data types that i have made in my game one after the other in an xml file , but for some reason , the Reader was only able to read the first one and ignored the second ones "ContentTypeReader" completely (I interchanged the two and tried) , on a whim , i changed the second one from (ReadObject & WriteObject pair) to (ReadRawObject & WriteRawObject) pair, now it seems to work , but  i hav eno idea why the previous form was not working and why this one is working , i tried to read the help , but the only difference i could really find was that REadObject can be used recursiveley , whereas ReadRawObject cannot, I am wondering as to what other differences exist between the two and is there any way to make the original program (no raw objects) work , as I am now quire comfortable with handling those.

    My code : Original
    The content Type reader : 
     
    public class MGameReader : ContentTypeReader<MGame> 
            { 
                protected override MGame Read(ContentReader input, MGame existingInstance) 
                { 
                    MGame temp = new MGame(); 
     
                    temp.Appearance_Param = input.ReadObject<Appearance>(); 
                    temp.Bubble_Catch = input.ReadObject<Idea_Catch>();               
     
                    return temp; 
                } 
            } 
     
    The Content Type Writer 
    [ContentTypeWriter] 
        public class MGameWriter : ContentTypeWriter<MGame> 
        { 
            protected override void Write(ContentWriter output, MGame value) 
            { 
                output.WriteObject<DataProcessors.Minigame.Appearance>(value.Appearance_Param); 
                output.WriteObject<DataProcessors.Minigame.Idea_Catch>(value.Bubble_Catch); 
            } 
     
            public override string GetRuntimeReader(TargetPlatform targetPlatform) 
            { 
                return typeof(MGame.MGameReader).AssemblyQualifiedName; 
            } 
        } 
     


    Modified :

    public class MGameReader : ContentTypeReader<MGame> 
            { 
                protected override MGame Read(ContentReader input, MGame existingInstance) 
                { 
                    MGame temp = new MGame(); 
     
                    temp.Appearance_Param = input.ReadObject<Appearance>(); 
                    temp.Bubble_Catch = input.ReadRawObject<Idea_Catch>();               
     
                    return temp; 
                } 
            } 
     
     
    [ContentTypeWriter] 
        public class MGameWriter : ContentTypeWriter<MGame> 
        { 
            protected override void Write(ContentWriter output, MGame value) 
            { 
                output.WriteObject<DataProcessors.Minigame.Appearance>(value.Appearance_Param); 
                output.WriteRawObject<DataProcessors.Minigame.Idea_Catch>(value.Bubble_Catch); 
            } 
     
            public override string GetRuntimeReader(TargetPlatform targetPlatform) 
            { 
                return typeof(MGame.MGameReader).AssemblyQualifiedName; 
            } 
        } 
     


    XML :
    <?xml version="1.0" encoding="utf-8" ?> 
    <XnaContent> 
      <!-- TODO: replace this Asset with your own XML asset data. --> 
      <Asset Type="DataProcessors.Minigame.MGame"
        <Bubble_Catch> 
          <Chat_Bubble_Color>159</Chat_Bubble_Color> 
          <Add_Time_Scale>1.9</Add_Time_Scale> 
          <Speed_Scale>1.0</Speed_Scale> 
        </Bubble_Catch> 
        <Appearance_Param> 
          <Field_Color>159</Field_Color> 
        </Appearance_Param> 
      </Asset> 
    </XnaContent> 
     

    By the way , I have implemented the proper readers and writers for Bubble_Catch Tag and the Appearance_Param tag.

    It seemed to me for some time that it is not possible to read two custom objects in succession (However that seems to be really wierd)

    I would love any help on the topic , Thanks

  • 24/04/2009 16:29 In reply to

    Re: Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

    Read/WriteRawObject literally just call into the ContentTypeReader/Writer for the type you specify. They don't write any type information first, and don't do any smart type lookups, so if you pass an instance of a derived class, but use an overload for a base class, they will only call the reader/writer for the base type. They basically trust you to know what you're doing and to be specifying the exact right type for the data you have.

    The normal Read/WriteObject methods do a type lookup and store a type header before the object data, so they can handle polymorphic types and objects that may be null.

    The type lookup is normally a good thing, but sometimes you specifically want to use the raw version if you want to do something like chaining to the writer for your base class (when you obviously want to call into the base writer in spite of the fact that the object you are passing it is an instance of a derived type).
    XNA Framework Developer - blog - homepage
  • 24/04/2009 17:29 In reply to

    Re: Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

    Shawn Hargreaves:
    Read/WriteRawObject literally just call into the ContentTypeReader/Writer for the type you specify. They don't write any type information first, and don't do any smart type lookups, so if you pass an instance of a derived class, but use an overload for a base class, they will only call the reader/writer for the base type. They basically trust you to know what you're doing and to be specifying the exact right type for the data you have.

    The normal Read/WriteObject methods do a type lookup and store a type header before the object data, so they can handle polymorphic types and objects that may be null.

    The type lookup is normally a good thing, but sometimes you specifically want to use the raw version if you want to do something like chaining to the writer for your base class (when you obviously want to call into the base writer in spite of the fact that the object you are passing it is an instance of a derived type).


    Well , I am almost never using any derived Writers or readers , but one thing that I am concerned about is the fact that your post implied that these can never be null ? In that case I would very much like to revert to the ReadObject form , if i only know why the problem is arising in the first place.
  • 24/04/2009 18:27 In reply to

    Re: Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

    Have you put a breakpoint in your content reader and stepped through the code? That might help you figure out what it's doing.
  • 24/04/2009 19:01 In reply to

    Re: Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

    David Hunt:
    Have you put a breakpoint in your content reader and stepped through the code? That might help you figure out what it's doing.


    Yes i have , here is what happens , whichever of these two tags is the first one (i have tried interchanging their order as well) is executed properly , it goes to the relevant Reader for the required type , then reads in the data , but when it comes to the second one , it just acts like it does not even know there is another content type reader that needs to be called , it directly places a null value there and moves on.
  • 25/04/2009 4:26 In reply to

    Re: Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

    That sounds like there is a problem in your "sub" readers/writers. Maybe the readers are reading more items than were written, leaving nothing in the input stream for the subsequent readers. Other than that, I can't think of anything that would cause this.
  • 25/04/2009 4:29 In reply to

    Re: Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

    Such problems normally mean that some previous reading code is wrong, so the file stream position isn't at the right point when a subsequent read operation takes place. Are you sure all your writers and readers exactly match? Can we see the code for the writers and readers of the two nested data types?
    XNA Framework Developer - blog - homepage
  • 25/04/2009 13:22 In reply to

    Re: Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

    This is exactly what I had thought before  as i had faced the same problem earlier , but i just cant seem to find any discernable differences :
    I have put in the whole class so , if you want you can even verify the data types : 
     
    public class Appearance 
        { 
            #region XML Data 
            /// <summary> 
            /// Holds the RGBA of the background playing field 
            /// </summary> 
            private Vector4 v4_field_color; 
            /// <summary> 
            /// property for "v4_field_color" 
            /// Which : Holds the RGBA values of the background playing field 
            /// </summary> 
            public Vector4 V4_Field_Color 
            { 
                get { return v4_field_color; } 
                set { v4_field_color = value; } 
            } 
            #endregion 
            #region Class Data 
            /// <summary> 
            /// Holds the Colour for the playing field 
            /// </summary> 
            private Color color_playing_field; 
            /// <summary> 
            /// Property for : color_playing_field 
            /// Which : Holds the Colour for the playing field 
            /// </summary> 
            [ContentSerializerIgnore] 
            public Color Color_Playing_Field 
            { 
                get { return color_playing_field; } 
                set { color_playing_field = value; } 
            } 
            #endregion 
            #region Content Type Reader 
     
            public class AppearanceReader : ContentTypeReader<Appearance> 
            { 
                protected override Appearance Read(ContentReader input, Appearance existingInstance) 
                { 
                  Appearance temp = new Appearance(); 
     
                  temp.V4_Field_Color = input.ReadVector4(); 
                  temp.V4_Field_Color /= 255; 
                  temp.Color_Playing_Field = new Color(temp.V4_Field_Color); 
     
                  return temp; 
                } 
            } 
            #endregion 
     
    Here is the writer for the same 
     
    [ContentTypeWriter] 
    public class AppearanceWriter : ContentTypeWriter<Appearance> 
        { 
            protected override void Write(ContentWriter output, Appearance value) 
            { 
                output.Write(value.V4_Field_Color); 
            } 
     
            public override string GetRuntimeReader(TargetPlatform targetPlatform) 
            { 
                return typeof(Appearance.AppearanceReader).AssemblyQualifiedName; 
            } 
        } 
     

    For the Idea_Catch type :
     #region XML Data 
            private bool is_active; 
            [ContentSerializer(Optional = true)] 
            public bool Is_Active 
            { 
                get { return is_active; } 
                set { is_active = value; } 
            } 
     
            /// <summary> 
            /// Holds the RGBA values for colour of the chat bubble 
            /// </summary> 
            private Vector4 v4_chat_bubble_color;        
            /// <summary> 
            /// Property for "v4_chat_bubble_color" 
            /// Holds the RGBA values for colour of the chat bubble 
            /// </summary> 
            [ContentSerializer(Optional = true)] 
            public Vector4 V4_Chat_Bubble_Color 
            { 
                get { return v4_chat_bubble_color; } 
                set { v4_chat_bubble_color = value; } 
            } 
     
            /// <summary> 
            /// Holds data about progressive difficulty in stages 
            /// </summary> 
            private List<stage_data> stages; 
            /// <summary> 
            /// Property for : stages 
            /// Which : Holds data about progressive difficulty in stages 
            /// </summary> 
            [ContentSerializer(Optional = true)] 
            public List<stage_data> Stages 
            { 
                get { return stages; } 
                set { stages = value; } 
            } 
            #endregion 
            #region Class Data 
            /// <summary> 
            /// Holds the colour of the chat bubble 
            /// </summary> 
            private Color color_chat_bubble; 
            /// <summary> 
            /// Property for : "color_chat_bubble" 
            /// Holds the colour of the chat bubble 
            /// </summary> 
            [ContentSerializerIgnore] 
            public Color Color_Chat_Bubble 
            { 
                get { return color_chat_bubble; } 
                set { color_chat_bubble = value; } 
            } 
            #endregion 
            #region Content Type Reader 
     
            public class Idea_CatchReader : ContentTypeReader<Idea_Catch> 
            { 
                protected override Idea_Catch Read(ContentReader input, Idea_Catch existingInstance) 
                { 
                   Idea_Catch temp = new Idea_Catch(); 
     
                   temp.Is_Active = input.ReadBoolean(); 
                   if (!temp.Is_Active) 
                       return null
                   temp.V4_Chat_Bubble_Color = input.ReadVector4(); 
                   temp.V4_Chat_Bubble_Color /= 255; 
                   temp.Stages = input.ReadObject<List<stage_data>>(); 
                     
                   temp.Color_Chat_Bubble = new Color(temp.V4_Chat_Bubble_Color); 
     
                   return temp; 
                                     
                } 
            } 
            #endregion 
      #region Stages 
            public class stage_data 
            { 
     
                /// <summary> 
                /// Holds the difficulty factor for time to add bubbles 
                /// </summary> 
                private double add_time_scale; 
                /// <summary> 
                /// Property for : add_time_scale 
                /// Which : Holds the difficulty factor for time to add bubbles 
                /// </summary> 
                [ContentSerializer(Optional = true)] 
                public double Add_Time 
                { 
                    get { return add_time_scale; } 
                    set { add_time_scale = value; } 
                } 
     
                /// <summary> 
                /// Holds the difficulty factor for the speed of falling bubbles 
                /// </summary> 
                private double speed_scale; 
                /// <summary> 
                /// Property for : speed_scale 
                /// Which : Holds the difficulty factor for the speed of falling bubbles 
                /// </summary> 
                [ContentSerializer(Optional = true)] 
                public double Speed 
                { 
                    get { return speed_scale; } 
                    set { speed_scale = value; } 
                } 
                #region Content Type Reader 
     
                public class stage_dataReader : ContentTypeReader<stage_data> 
                { 
                    protected override stage_data Read(ContentReader input, stage_data existingInstance) 
                    { 
                        stage_data temp = new stage_data(); 
     
                        temp.Add_Time = input.ReadDouble(); 
                        temp.Speed = input.ReadDouble(); 
     
                        return temp; 
                    } 
                } 
                #endregion 
            } 
            #endregion 
     
        } 
     
    The Writers 
    #region Idea Game Writer 
     
        /// <summary> 
        /// This class will be instantiated by the XNA Framework Content Pipeline 
        /// to write the specified data type into binary .xnb format. 
        /// 
        /// This should be part of a Content Pipeline Extension Library project. 
        /// </summary> 
        [ContentTypeWriter] 
        public class IdeaGameWriter : ContentTypeWriter<Idea_Catch> 
        { 
            protected override void Write(ContentWriter output, Idea_Catch value) 
            { 
                output.Write(value.Is_Active); 
                output.Write(value.V4_Chat_Bubble_Color); 
                output.WriteObject<List<DataProcessors.Minigame.Idea_Catch.stage_data>>(value.Stages); 
            } 
     
            public override string GetRuntimeReader(TargetPlatform targetPlatform) 
            { 
                return typeof(Idea_Catch.Idea_CatchReader).AssemblyQualifiedName; 
            } 
        } 
        
        #endregion 
        #region Stage Data Writer 
     
        /// <summary> 
        /// This class will be instantiated by the XNA Framework Content Pipeline 
        /// to write the specified data type into binary .xnb format. 
        /// 
        /// This should be part of a Content Pipeline Extension Library project. 
        /// </summary> 
        [ContentTypeWriter] 
        public class stage_dataWriter : ContentTypeWriter<stage_data> 
        { 
            protected override void Write(ContentWriter output, stage_data value) 
            { 
                output.Write(value.Add_Time);         // Write out the add time scaling factor 
                output.Write(value.Speed);            // Write out the Speed scaling factor 
            } 
     
            public override string GetRuntimeReader(TargetPlatform targetPlatform) 
            { 
                return typeof(stage_data.stage_dataReader).AssemblyQualifiedName; 
            } 
        } 
        #endregion 

    This post has gotten wayyyy out of hand , its too big for anyone to be comfortable with it , I am sorry if it seems like i am dumping my problems on the forum , but it is just something that has been eluding me for some reason (normally I am not so bad when it comes to debugging) , if this is too big for you , I can put up the few files that have this stuff on the web so you can download them and have a look .
  • 25/04/2009 17:07 In reply to

    Re: Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

    I think I'll need a project I can compile and debug into to figure this out. Nothing is jumping out at me just from reading the code, so I'll need to be able to debug it.
    XNA Framework Developer - blog - homepage
  • 26/04/2009 5:14 In reply to

    Re: Difference between ReadObject & ReadRawObject (WriteObject & WriteRawObject )

    Your Idea_Catch writer outputs a bool (Is_Active) and the rest of the fields. However, your reader reads in the Is_Active bool and, if false, returns a null and never reads the rest of the data. That's going to leave unread data in the input buffer.

Page 1 of 1 (10 items) Previous Next