WAYNETS.ORG

Game and Program

序列化与反序列化

作者:

发表于

Context Polling System Post-Processing Renderer

鉴于目前游戏引擎已经可以自由添加和移除Entity,并且可以向其中添加和移除Component,创建一个可以存储当前Scene信息的工具变得格外重要。

设计思路

由于游戏引擎中的Scene由Entity和它的Component组成,那么保存一个Scene就是保存这些信息。因此,我们可以使用序列化和反序列化工具,当需要保存时,将这些信息序列化为文本文件;当需要读取时,从文件路径中获取这个文本文件,然后执行反序列化。

YAML(Yet Another Markup Language)是一种人类可读的、层级结构清晰的序列化格式,广泛用于配置文件、资源描述、数据保存等场景。相比JSON,更简洁、支持注释和多种复杂结构。

代码实现

类SceneSerializer声明:当定义这个类的实例时,要在构造函数中要传入一个需要序列化的Scene实例,也就是告诉它需要序列化的目标。因此,在类Scene中,要定义一个友元类SceneSerializer,以便访问它的所有变量。

class SceneSerializer
{
public:
	SceneSerializer(const Ref<Scene>& scene);

	void Serialize(const std::string& filepath);
	void SerializeRuntime(const std::string& filepath);

	bool Deserialize(const std::string& filepath);
	bool DeserializeRuntime(const std::string& filepath);
private:
	Ref<Scene> m_Scene;
};

序列化函数Serializer():遍历当前Scene中的所有Entity,对其调用函数SerializeEntity(),记录所有Componnet的信息

void Serialize(const std::string& filepath)
{
	YAML::Emitter out;
	out << YAML::BeginMap;
	out << YAML::Key << "Scene" << YAML::Value << "Untitled";
	out << YAML::Key << "Entities" << YAML::Value << YAML::BeginSeq;
	m_Scene->m_Registry.each([&](auto entityID)
	{
		Entity entity = { entityID, m_Scene.get() };
		if (!entity) return;
		SerializeEntity(out, entity);
	});
	out << YAML::EndSeq;
	out << YAML::EndMap;

	std::ofstream fout(filepath);
	fout << out.c_str();
}

Leave a comment