2021SC@SDUSC
开源游戏引擎 Overload 代码模块分析 之 OvTools(二)—— Filesystem
前言
本文是该系列的第二部分,笔者将解析 Overload 中 OvTools 的 Filesystem 文件系统模块。
若想先大致了解该引擎各个大模块,可前往笔者这篇相关文章查看。
若想了解第一部分(Eventing 模块),可前往笔者上篇文章。
分析
1、Filesystem 模块概述
该模块负责创建文件 .ini 对一系列属性或值资源文件的读写处理,包含了下列文件:
从命名上显而易见,包括了 IniFile 和 tinyxml2 两部分。其中,tinyxml2 是简单高效的开源 C++ XML 文件解析库,可以进行存储简单数据、配置文件、对象序列化等不是很大的数据量操作,所以想了解更多信息请前往官网,在此不多探讨。因此,我们将主要探究 IniFile 实现的功能与方法。
2、IniFile
2.1 IniFile.h
2.1.1 头文件
该文件包含了两个头文件:
#include <string>
#include <unordered_map>
string 头文件不用赘述;对于 unordered_map ,它还有个好兄弟头文件 map,两者都是包含了某种数据结构容器。
其中,map 包含的是有序容器,底层是红黑树,使用空间大;unordered_map 包含的是无序容器,底层是哈希表,虽然建立耗时,但占存小、读取快。
从作者对两者的选择中可以看出,在开发游戏中必然有大量数据交流,而我们需要追求的性能应该是底存储、快读取。
2.1.2 IniFile 类
代码包含了各种函数的声明定义与注释解释,不多赘述。
值得一提的是,代码相较上篇文章探究的 Event 类加了一个关键词 final ,该词是 C++ 11 关键词,意义是锁定该类,不可继承;此外,代码重新命名了 pair(一种配对操作,能将两个值合并为一个值单元操作,常用于配合 map 系列容器)与 unordered_map(上文已提及)。
全部代码如下:
class IniFile final
{
public:
using AttributePair = std::pair<std::string, std::string>;
using AttributeMap = std::unordered_map<std::string, std::string>;
/**
* Create an IniFile by parsing the given file path and extracting key/values pairs for future usage
* @param p_filePath
*/
IniFile(const std::string& p_filePath);
/**
* Overwrite the content of the current data by reloading the file
*/
void Reload();
/**
* Rewrite the entiere .ini file with the current values. This operation is destructive and can't be undone.
* Any comment or line break in your .ini file will get destroyed
*/
void Rewrite() const;
/**
* Return the value attached to the given key
* If the key doesn't exist, a default value is returned (0, false, "NULL")
* @param p_key
*/
template<typename T>
T Get(const std::string& p_key);
/**
* Return the value attached to the given key
* If the key doesn't exist, the specified value is returned
* @param p_key
* @param p_default
*/
template<typename T>
T GetOrDefault(const std::string& p_key, T p_default);
/**
* Set a new value to the given key (Not applied to the real file untill Rewrite() or Save() is called)
* @param p_key
* @param p_value
*/
template<typename T>
bool Set(const std::string& p_key, const T& p_value);
/**
* Add a new key/value to the IniFile object (Not applied to the real file untill Rewrite() or Save() is called)
* @param p_key
* @param p_value
*/
template<typename T>
bool Add(const std::string& p_key, const T& p_value);
/**
* Remove an key/value pair identified by the given key (Not applied to the real file untill Rewrite() or Save() is called)
* @param p_key
*/
bool Remove(const std::string& p_key);
/**
* Remove all key/value pairs (Not applied to the real file untill Rewrite() or Save() is called)
*/
void RemoveAll();
/**
* Verify if the given key exists
* @param p_key
*/
bool IsKeyExisting(const std::string& p_key) const;
/**
* Get the content stored in the ini file as a vector of strings (Each string correspond to an attribute pair : Attribute=Value
*/
std::vector<std::string> GetFormattedContent() const;
private:
void RegisterPair(const std::string& p_key, const std::string& p_value);
void RegisterPair(const AttributePair& p_pair);
void Load();
AttributePair ExtractKeyAndValue(const std::string& p_attributeLine) const;
bool IsValidLine(const std::string& p_attributeLine) const;
bool StringToBoolean(