I think that the answer to all of these questions is "surrogates". For example:
// needs to be done once only, before any serialization/deserialization is done
RuntimeTypeModel.Default.Add(typeof(GraphicsBuffer), false)
.SetSurrogate(typeof(StoredData));
with:
[ProtoContract(UseProtoMembersOnly= true)]
public sealed class StoredData
{
[ProtoMember(1)]
public byte[] GpuData;
public static explicit operator GraphicsBuffer(StoredData value)
{
if (value == null) return null;
throw new NotImplementedException("Your conversion code here");
}
public static explicit operator StoredData(GraphicsBuffer value)
{
if (value == null) return null;
throw new NotImplementedException("Your conversion code here");
}
}
Note to self: I should make this possible via attributes so you don't need to manipulate the model at runtime.
Now, whenever the model encounters a GraphicsBuffer
, it will use the conversion operators to/from StoredData
, and run the serialization/deserialization code on the StoredData
instance.