我正在尝试序列化/反序列化游戏场景,以便网络发送/接收和从/向磁盘保存/加载。
我的游戏引擎使用节点和组件,因此这些是唯一需要序列化的对象。场景可能如下所示:
Root Node
- Node
- SpecializedComponent
- SpecializedComponent
- Node
- Node
- Node
- Node
- Node
- Node
- Node
- SpecializedComponent
- Node
节点基本上是这样的:
class Node {
map<String, Node> mChildren;
map<String, Component> mComponents;
uuid_t mId;
Node* mParent;
};
SpecializedComponent基本上是这样的:
class SpecializedComponent : public Component {
uuid_t mId;
Node* mNode;
};
我想使用YAML或JSON作为我的文本表示。我有Qt,Boost和我想要的任何其他库,因此依赖性不是问题。实际上,节点已经是Q_OBJECTS所以我有反射。
尽管有反思,但将其正确地反序列化回C ++树结构似乎也是一个问题。
最理想的是,我想要一个优雅而有效的解决方案,将这样的结构序列化/反序列化为二进制或文本格式。
答案 0 :(得分:3)
下降递归解析器通常是处理重建部分的更简单且功能更强大的选项。我可以尝试设置一些代码以具体的方式显示,在伪代码中有一些这样的东西:
Node *parse(stream s) {
content = new Node;
s >> content >> nsons;
for (int c = 0; c < nsons; ++c)
content->addChild(parse(s));
return content;
}
当然,当读取组件时,我们必须检查类型。
答案 1 :(得分:2)
我建议您使用protocol buffers library。由于您将C ++数据序列化以便在网络上发送,因此您将对此库提供的内容非常有帮助。
答案 2 :(得分:1)
序列化节点属性 序列化此节点的组件。 IE序列化子组件的数量,然后是每个组件。
为了序列化组件,您应该将An Id(int或字符串)属性化为每个组件类型(这样您就可以确定如何对hs类型的特定组件进行反序列化) 序列化子节点的数量 序列化子节点(递归调用相同的函数)
然后反序列化就是精确的镜像。 反序列化,节点属性,然后是组件数。 对于每个组件获取组件类型,根据此类型对其进行反序列化) 等等...
如果您使用Qt,QTextStream / QDataStream是最简单的选项。 二进制格式在反序列化时必须是众所周知的,因此您应该在序列化内容的生成中添加版本号或Id,以便稍后添加或更改内容。
此外,如果你必须与其他语言(如java)兼容,请注意Qt不使用与字符串类型相同的规范
答案 3 :(得分:1)
我猜你可以用Boost Serialization做到这一点。它支持所有STL容器的序列化,包括std::map
。