Customizing IntermediateSerializer, part 1

Customizing IntermediateSerializer, part 1

  • Comments 1

So, you are using IntermediateSerializer to import XML data into your content build process. Excellent!

Having read my previous post, you understand how to control the formatting of your XML via attributes. Even better!!

Lets say you want to serialize this data:

    class TestClass
{
public int elf = 23;
}

No problem, IntermediateSerializer can do that!!!

"But wait", I hear you cry. "It just so happens that today is a Tuesday, and on Tuesdays I like my elves to be serialized in base 16, not that boring default decimal format."

Oh. Hmm... There is no serializer attribute for specifying the number base. What a drag!!!!

This is a perfect place to apply the Serialization Helper Property pattern:

  • Tell the serializer to ignore the public member which holds your data
  • Create a private helper property with a different name
  • Tell the serializer to include this private property
  • Tell the serializer to give it the same element name as your original public member
  • Implement the private property to access the same data as the public member
  • Use the private getter and setter to format the data in whatever way you see fit

An example:

    class TestClass
{
[ContentSerializerIgnore]
public int elf = 23;


[ContentSerializer(ElementName = "elf")]
private string ElfSerializationHelper
{
get
{
return "0x" + elf.ToString("X8");
}

set
{
if (value.StartsWith("0x"))
value = value.Substring(2);

elf = int.Parse(value, NumberStyles.HexNumber);
}
}
}

This produces the following XML:

    <XnaContent>
<Asset Type="TestClass">
<elf>0x00000017</elf>
</Asset>
</XnaContent>

The helper property is private, so people using your class need never be aware of it, but IntermediateSerializer has no trouble including private properties as long as you decorate them with the necessary attributes.

The helper property shown above returns a string, but this can be any type you like. For more complicated formatting tasks, it can even return a temporary instance of a private helper class. For instance this version will split the number into three separate XML elements, dividing the value into hundreds, tens, and ones:

    class TestClass
{
[ContentSerializerIgnore]
public int elf = 23;


[ContentSerializer(ElementName = "elf")]
private DecimalSerializationHelper ElfSerializationHelper
{
get
{
DecimalSerializationHelper helper = new DecimalSerializationHelper();

helper.Hundreds = elf / 100;
helper.Tens = (elf / 10) % 10;
helper.Ones = elf % 10;

return helper;
}

set
{
elf = (value.Hundreds * 100) +
(value.Tens * 10) +
(value.Ones);
}
}


private class DecimalSerializationHelper
{
public int Hundreds;
public int Tens;
public int Ones;
}
}

Resulting XML:

    <XnaContent>
<Asset Type="TestClass">
<elf>
<Hundreds>0</Hundreds>
<Tens>2</Tens>
<Ones>3</Ones>
</elf>
</Asset>
</XnaContent>

I used this pattern inside the Content Pipeline itself, for a few of our more gnarly types that needed to be serialized in specific ways. It can also be useful to add special XML-only validation logic to the helper property setter.

  • What were some of those more gnarly types? Do tell :-)

Page 1 of 1 (1 items)
Leave a Comment
  • Please add 3 and 7 and type the answer here:
  • Post