Skip to main content
gamedev.net
🔒 Locked

[C#] Loading XML settings with polymorphic classes?

Started by Spa8nky 0 replies 950+ views
Original Post
Spa8nky
Spa8nky
Reading through Shawn Hargreaves blog on XML he shows a useful method for dealing with polymorphic classes and XML:

Quote:

One advantage of IntermediateSerializer over XmlSerializer is that it supports arbitrary polymorphic data without requiring all the possible subtypes to be predeclared. Let's look at an example:


    class A    {        public bool Value = true;    }    class B : A { }    class C : A { }    class TestClass    {        public object Hello = "World";        public object Elf = 23;        public A[] PolymorphicArray = { new A(), new B(), new C() };    }Resulting XML:    <?xml version="1.0" encoding="utf-8"?>    <XnaContent>      <Asset Type="TestClass">        <Hello Type="string">World</Hello>        <Elf Type="int">23</Elf>        <PolymorphicArray>          <Item>            <Value>true</Value>          </Item>          <Item Type="B">            <Value>true</Value>          </Item>          <Item Type="C">            <Value>true</Value>          </Item>        </PolymorphicArray>      </Asset>    </XnaContent>


The problem I having trouble understanding is how can the correct inherited classes be loaded from such an XML file?

At the moment I am loading using the following:

                    if ((stream = openFileDialog.OpenFile()) != null)                    {                        XmlReaderSettings settings = new XmlReaderSettings();                        settings.IgnoreComments = true;                        using (XmlReader reader = XmlReader.Create(stream, settings))                        {                            // - Create new entities/actors from settings                            SaveData saveData = IntermediateSerializer.Deserialize<SaveData>(reader, null);                            // Load Camera                            Game1.Instance.camera = new Camera_FreeLook(saveData.cameraSettings);                        }


If the SaveData would contain an array of the base class, how would I make sure the inherited classes were loaded correctly after deserializing the XML file and creating the original array?
Spa8nky
Spa8nky
Taking my polymorphic camera class as an example, I can try and keep it simple and just have one settings class for all derived cameras. However, this does not allow the computer to know which type of camera has been saved. Therefore, when the computer loads the camera from the settings the derived camera class is unknown.

I've thought about creating a base class for all settings of all objects:

    abstract class Settings    {        public abstract object LoadFrom();    }


This way when loading camera settings I can create the type of camera required:

    [Serializable]    public class CameraFreeLookSettings : Settings    {        public float FarClip = 1000.0f;        public bool IsIgnoreInput = false;        public float NearClip = 0.1f;        public Quaternion Orientation = Quaternion.Identity;        public Vector3 Position = Vector3.Zero;        public float Sensitivity = 0.3f;        public override object LoadFrom()        {            return new CameraFreeLook(this);        }    }


I can also grab a camera from a pool instead of creating a new instance in the settings LoadFrom() method.

I have been told that I might be over thinking this before now, but how else is it possible to load polymorphic classes correctly?

[Edited by - Spa8nky on June 16, 2010 8:29:55 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.