我想在我的游戏引擎中使用protobuf-net,我遇到了这个任务 - 如何有效地区分存储和运行时类型?
基本上,数据存储在磁盘上的方式将具有不同的格式,然后使用在运行时加载的格式。
简化示例:我使用类似这样的类将一些GPU相关数据序列化为byte []:
[ProtoContract(UseProtoMembersOnly=true)]
public sealed class StoredData
{
[ProtoMember(1)]
public byte[] GpuData;
}
然后我将有一个这个类的运行时实现,我将该字节缓冲区上传到图形卡,因此将具有完全不同的类型,如“类GraphicsBuffer”而不是“byte []”。
此外,在序列化运行时类型'GraphicsBuffer'时,我还希望序列化完全不同的消息 - 例如磁盘上的路径或要反序列化的StoredData名称。
这一切归结为:
我如何交换用于序列化的类型,同时能够定义回调以在这些类型之间进行转换?所以(例如)
1.当我序列化SoredData时,会写入一个StoredData
2.当我反序列化GraphicsBuffer时,StoredData被反序列化并转换为GraphicsBuffer
3.当我序列化GraphicsBuffer时,该缓冲区的'缓冲路径消息'被序列化
4.当我反序列化'缓冲路径消息'时,'缓冲路径消息'被反序列化,然后使用该消息找到并反序列化StoredData,而StoredData的反序列化产生根据StoredData中的信息创建的GraphicsBuffer。
我希望这有点道理!
答案 0 :(得分:1)
我认为所有这些问题的答案都是“代理人”。例如:
// needs to be done once only, before any serialization/deserialization is done
RuntimeTypeModel.Default.Add(typeof(GraphicsBuffer), false)
.SetSurrogate(typeof(StoredData));
使用:
[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");
}
}
自我注意:我应该通过属性实现这一点,这样您就不需要在运行时操作模型。
现在,只要模型遇到GraphicsBuffer
,它就会使用转换运算符来自StoredData
,并在StoredData
实例上运行序列化/反序列化代码。