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

universal serializer?

Last post 05-12-2008 1:35 PM by JohnDoe. 5 replies.
  • 05-09-2008 2:31 PM

    universal serializer?

    I do not own an XBox (yet), so I cannot do a cross platform test, but as far as I can tell, the .NET framework on the XBox supports enough reflection, so that a universal serializer for the content pipeline could work or am I wrong here?

    It could look like this:

    public class XNASerializable : Attribute { ... }

    public class MyCustomContent
    {
       [XNASerializable]
       public bool BoolProperty { get { ... } set { ... } }
       [XNASerializable]
       public string StringProperty { get { ... } set { ... } }
    }

     

    in the ContentWriter (pseudocode):

    // figure out how many properties to write
    int counter = 0;
    foreach (PropertyInfo propertyInfo in valueType.GetProperties())
    {
       if (propertyInfo.GetCustomAttributes(typeof(XNASerializable), true).Length > 0)
          counter++;
    }
    output.Write(counter);

    // write the properties
    Type valueType = value.GetType();
    foreach (PropertyInfo propertyInfo in valueType.GetProperties())
    {
       if (propertyInfo.GetCustomAttributes(typeof(XNASerializable), true).Length > 0)
       {
          output.Write(propertyInfo.PropertyName);
          output.Write(propertyInfo.PropertyType.AssemblyQualifiedName);
          output.Write(propertyInfo.GetValue(value, null));
       }
    }

     

    in the ContentReader (pseudocode):

    int count = input.ReadInt32();
    for (int i=0; i<count; i++)
    {
       PropertyInfo propertyInfo = value.GetType().GetProperty(input.ReadString());
       string propertyTypeName = input.ReadString();
       switch (typeName)
       {
          case "System.Boolean":
             propertyInfo.SetValue(value, input.ReadBoolean(), null);
             break;
          case "System.String":
             propertyInfo.SetValue(value, input.ReadString(), null);
             break;
          case ...
             break;
          default:
             object propertyValue = Activator.CreateInstance(propertyInfo.PropertyType);
             ...
             break;
       }  
    }

     

    Well, you get the idea...
    Arrays would be easy, too, but you would probably have to jump through some hoops for complex types as the MakeGenericType and so forth is missing in the framework, so the whole serialization/deserialization can be recursive, but cannot call any of the input.ReadObject<...> methods, instead it has to rely on the Activator.CreateInstance and then a recursive call to the same deserialization/serialization routine. The requirements for this to work are exactly the same as for XML serialization, the properties must be read/write and there must be a parameterless default constructor.

    Writing one method like this would kind of support our laziness ;) Is there any particular reason this would not work on the XBox?

  • 05-09-2008 2:51 PM In reply to

    Re: universal serializer?

    That would certainly be possible, and in fact I'd love to get something like that built into the framework if we ever have time. It would be slow compared to explicit manual serialization, but certainly very convenient.

    I'm not sure what you mean about MakeGenericType not being supported, btw?
    XNA Framework Developer - blog - homepage
  • 05-09-2008 2:56 PM In reply to

    Re: universal serializer?

    I do something similar, and it works. It's not super fast, but for things like level load, where the big data is textures and meshes that are already efficiently implemented, it's OK.
    Jon Watte, Direct3D MVP kW X-port 3ds Max .X exporter kW Animation source code
  • 05-09-2008 3:00 PM In reply to

    Re: universal serializer?

    Shawn Hargreaves:
    I'm not sure what you mean about MakeGenericType not being supported, btw?

    I meant the Type.MakeGenericType, but you are right, it IS supported, while writing the post, I was just browsing through the MSDN2 pages to see which methods are missing in the XNA framework and I must have missed that little "X" there.

  • 05-11-2008 7:07 PM In reply to

    Re: universal serializer?

    Well, I wrote a little serializer, and wrote the first blog entry of my life about it...

    http://the-john-doe.spaces.live.com

    I am sure it won't cover every scenario, but it has capabilities similar to an XmlSerializer and is extensible in several ways. Maybe it helps someone during development a little bit.

  • 05-12-2008 1:35 PM In reply to

    Re: universal serializer?

    Just one additional post to this, to make clear what it does - well, as my first blog post is probably far too long...

    The ContentReader and ContentWriter for a class using the serializer would be reduced to this:

    public class MyCustomDataReader : ContentTypeReader<MyCustomData>    
    {
    protected override MyCustomData Read(ContentReader input,
    MyCustomData existingInstance)
    {
    XNADeserializer xnaDeserializer = new XNADeserializer();
    return xnaDeserializer.Deserialize(input, existingInstance)
    as MyCustomData;
    }
    }
     
    [ContentTypeWriter]    
    public class MyCustomDataWriter :
    ContentTypeWriter<SerializationSampleContent.MyCustomData>
    {
    protected override void Write(ContentWriter output,
    SerializationSampleContent.MyCustomData value)
    {
    XNASerializer xnaSerializer = new XNASerializer();
    xnaSerializer.Serialize(output, value);
    }
    public override string GetRuntimeReader(TargetPlatform targetPlatform)
    {
    return typeof(SerializationSampleContent.MyCustomDataReader).AssemblyQualifiedName;
    }
    }

    Well, how robust it is, still needs to be proven, it handles public properties with getter/setter, arrays, collections, nested classes with existing ContentReader/ContentWriter, SharedResources and in some way ExternalReferences, also I included detection for an IXNASerializable interface, so that a class can implement similar to the IXmlSerializable interface for custom serialization.

    The source code is there, so if someone wants to extend it, e.g. to support public fields, feel free.

Page 1 of 1 (6 items) Previous Next