Initial engine repository
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
#pragma once
|
||||
|
||||
#include <frostbite2D/types/type_alias.h>
|
||||
#include <frostbite2D/resource/pvf_archive.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
namespace frostbite2D {
|
||||
|
||||
/**
|
||||
* @brief 脚本指令操作码枚举
|
||||
*/
|
||||
enum class ScriptOpcode : uint8 {
|
||||
Integer = 2, ///< 整数值
|
||||
Float = 4, ///< 浮点值
|
||||
StringRef5 = 5, ///< 二进制字符串引用(类型5)
|
||||
StringRef6 = 6, ///< 二进制字符串引用(类型6)
|
||||
StringRef7 = 7, ///< 二进制字符串引用(类型7)
|
||||
StringRef8 = 8, ///< 二进制字符串引用(类型8)
|
||||
ExtendedString9 = 9, ///< 扩展字符串(带额外字节)
|
||||
ExtendedString10 = 10, ///< 扩展字符串
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 脚本值类型
|
||||
*/
|
||||
enum class ScriptValueType {
|
||||
Empty, ///< 空值
|
||||
Integer, ///< 整数值
|
||||
Float, ///< 浮点值
|
||||
String, ///< 字符串值
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 脚本解析结果值
|
||||
*/
|
||||
struct ScriptValue {
|
||||
ScriptValueType type = ScriptValueType::Empty; ///< 值类型
|
||||
int32 intValue = 0; ///< 整数值(type == Integer 时有效)
|
||||
double floatValue = 0.0; ///< 浮点值(type == Float 时有效)
|
||||
std::string stringValue; ///< 字符串值(type == String 时有效)
|
||||
|
||||
/**
|
||||
* @brief 判断是否为空值
|
||||
*/
|
||||
bool isEmpty() const { return type == ScriptValueType::Empty; }
|
||||
|
||||
/**
|
||||
* @brief 转换为字符串表示
|
||||
*/
|
||||
std::string toString() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 脚本二进制数据解析器
|
||||
*
|
||||
* 用于解析 PVF 存档中的脚本二进制数据。
|
||||
* 每条指令为 5 字节:1 字节操作码 + 4 字节数据。
|
||||
* 支持与 PvfArchive 交互获取字符串资源。
|
||||
*
|
||||
* @example
|
||||
* auto& archive = PvfArchive::get();
|
||||
* if (auto rawData = archive.getFileRawData("script/example.bin")) {
|
||||
* ScriptParser parser(*rawData, "script/example.bin");
|
||||
*
|
||||
* // 迭代解析
|
||||
* while (!parser.isEnd()) {
|
||||
* if (auto value = parser.next()) {
|
||||
* // 处理 value
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // 或者一次性解析所有
|
||||
* auto allValues = parser.parseAll();
|
||||
* }
|
||||
*/
|
||||
class ScriptParser {
|
||||
public:
|
||||
/**
|
||||
* @brief 从 RawData 构造
|
||||
* @param data 原始数据
|
||||
* @param filePath 文件路径(用于提取文件类型)
|
||||
*/
|
||||
ScriptParser(const RawData& data, const std::string& filePath);
|
||||
|
||||
/**
|
||||
* @brief 从字节数组构造
|
||||
* @param data 字节数组
|
||||
* @param filePath 文件路径(用于提取文件类型)
|
||||
*/
|
||||
ScriptParser(const std::vector<uint8>& data, const std::string& filePath);
|
||||
|
||||
/**
|
||||
* @brief 从指针和大小构造
|
||||
* @param data 数据指针
|
||||
* @param size 数据大小
|
||||
* @param filePath 文件路径(用于提取文件类型)
|
||||
*/
|
||||
ScriptParser(const char* data, size_t size, const std::string& filePath);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 迭代器风格 API
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief 获取下一个值
|
||||
* @return 解析的值,失败或结束返回 std::nullopt
|
||||
*/
|
||||
std::optional<ScriptValue> next();
|
||||
|
||||
/**
|
||||
* @brief 回退一个指令
|
||||
*/
|
||||
void back();
|
||||
|
||||
/**
|
||||
* @brief 检查是否已到达数据末尾
|
||||
* @return 到达末尾返回 true
|
||||
*/
|
||||
bool isEnd() const;
|
||||
|
||||
/**
|
||||
* @brief 重置解析位置到开头
|
||||
*/
|
||||
void reset();
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 批量解析
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief 解析所有值
|
||||
* @return 所有解析值的列表
|
||||
*/
|
||||
std::vector<ScriptValue> parseAll();
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 状态查询
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief 获取当前解析位置
|
||||
* @return 当前位置(字节偏移)
|
||||
*/
|
||||
size_t position() const;
|
||||
|
||||
/**
|
||||
* @brief 获取数据总大小
|
||||
* @return 数据大小(字节)
|
||||
*/
|
||||
size_t size() const;
|
||||
|
||||
/**
|
||||
* @brief 获取文件路径
|
||||
* @return 文件路径
|
||||
*/
|
||||
const std::string& filePath() const;
|
||||
|
||||
/**
|
||||
* @brief 获取文件类型(从路径提取)
|
||||
* @return 文件类型
|
||||
*/
|
||||
const std::string& fileType() const;
|
||||
|
||||
/**
|
||||
* @brief 检查解析器是否有效(有数据)
|
||||
* @return 有效返回 true
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief 从文件路径提取文件类型
|
||||
* @param filePath 文件路径
|
||||
* @return 文件类型
|
||||
*/
|
||||
std::string extractFileType(const std::string& filePath) const;
|
||||
|
||||
/**
|
||||
* @brief 读取 1 字节
|
||||
* @param offset 偏移位置
|
||||
* @return 字节值
|
||||
*/
|
||||
uint8 readByte(size_t offset) const;
|
||||
|
||||
/**
|
||||
* @brief 读取 4 字节整数
|
||||
* @param offset 偏移位置
|
||||
* @return 整数值
|
||||
*/
|
||||
int32 readInt32(size_t offset) const;
|
||||
|
||||
/**
|
||||
* @brief 解析单个值
|
||||
* @param offset 偏移位置
|
||||
* @return 解析的值
|
||||
*/
|
||||
std::optional<ScriptValue> parseValueAt(size_t offset) const;
|
||||
|
||||
std::vector<char> data_; ///< 数据副本
|
||||
size_t position_ = 2; ///< 当前解析位置(从第 2 字节开始)
|
||||
std::string filePath_; ///< 文件路径
|
||||
std::string fileType_; ///< 文件类型
|
||||
};
|
||||
|
||||
} // namespace frostbite2D
|
||||
Reference in New Issue
Block a user