Initial engine repository

This commit is contained in:
2026-06-08 19:58:35 +08:00
commit 7a925c3736
137 changed files with 162421 additions and 0 deletions
@@ -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