【发布时间】:2011-10-23 12:47:11
【问题描述】:
我正在尝试序列化/反序列化游戏场景以进行网络发送/接收以及从磁盘保存/加载。
我的游戏引擎使用节点和组件,因此它们是唯一需要序列化的对象。场景可能如下所示:
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++ 树结构似乎是一个问题。
最理想的情况是,我想要一个优雅而高效的解决方案,将这样的结构序列化/反序列化为二进制或文本格式。
【问题讨论】:
-
对于 JSON 来说似乎是一个合理的工作,并且有几个可用的包,而且您可以在不到 1000 行的源代码中编写自己的包。
-
您的输入文件看起来很像 YAML。检查这个:stackoverflow.com/questions/365155/parse-yaml-files-in-c-c
-
您的主要问题是:
mComponents可以NOT 持有任何SpecializedComponent对象。容器保存实际值。因此,如果您将派生类型分配(或推送/插入)到容器中,您将遭受The Slicing Problem的影响。这是将对象的一个Component部分复制到容器中并切掉SpecializedComponent的额外部分的地方。要拥有异构容器,您需要使用std::map<String, Component*>之类的东西(或为指针设计的容器boost::ptr_map<String, Component> -
@LokiAstari,我已经这样做了,尽管成功有限,因为我无法 QtMetaType 为我构造一个合适的对象。
标签: c++ serialization tree