feat(平台): 添加Switch平台支持并实现资源管理器

- 新增Switch平台初始化与清理功能
- 实现Asset资源管理器类,提供文件读写、路径处理等功能
- 完善Window类的销毁逻辑,释放SDL资源
- 更新Switch平台编译配置,移除冗余标志
- 在主程序中集成资源管理器功能
This commit is contained in:
2026-02-21 03:34:48 +08:00
parent ce2cc4d210
commit 9f29192ae8
9 changed files with 905 additions and 8 deletions

View File

@@ -0,0 +1,397 @@
#pragma once
#include <filesystem>
#include <fostbite2D/types/type_alias.h>
#include <optional>
#include <string>
#include <vector>
namespace frostbite2D {
namespace fs = std::filesystem;
/**
* @brief 文件信息结构体
*/
struct FileInfo {
std::string name; ///< 文件名(包含扩展名)
std::string extension; ///< 文件扩展名(包含点,如 ".txt"
std::string fullPath; ///< 完整路径
uint64 size = 0; ///< 文件大小(字节)
bool isDirectory = false; ///< 是否为目录
bool isRegularFile = false; ///< 是否为普通文件
bool exists = false; ///< 是否存在
};
/**
* @brief 资源管理类(单例)
*
* 提供文件读写、目录操作、路径处理等功能。
* 支持设置工作目录,所有相对路径将基于工作目录解析。
* 支持 UTF-8 编码的中文路径。
*
* @example
* auto& asset = Asset::get();
* asset.setWorkingDirectory("D:/游戏/资源");
* std::string content;
* asset.readTextFile("配置/设置.json", content);
*/
class Asset {
public:
/**
* @brief 获取单例实例
* @return 资源管理器实例引用
*/
static Asset &get();
Asset(const Asset &) = delete;
Asset &operator=(const Asset &) = delete;
// ---------------------------------------------------------------------------
// 文件读写
// ---------------------------------------------------------------------------
/**
* @brief 读取文本文件
* @param path 文件路径(相对或绝对路径)
* @param outContent 输出文件内容
* @return 读取成功返回 true
*/
bool readTextFile(const std::string &path, std::string &outContent);
/**
* @brief 写入文本文件
* @param path 文件路径
* @param content 要写入的内容
* @param append 是否追加模式,默认覆盖
* @return 写入成功返回 true
*/
bool writeTextFile(const std::string &path, const std::string &content,
bool append = false);
/**
* @brief 读取二进制文件
* @param path 文件路径
* @param outData 输出字节数组
* @return 读取成功返回 true
*/
bool readBinaryFile(const std::string &path, std::vector<uint8> &outData);
/**
* @brief 写入二进制文件
* @param path 文件路径
* @param data 要写入的字节数组
* @param append 是否追加模式,默认覆盖
* @return 写入成功返回 true
*/
bool writeBinaryFile(const std::string &path, const std::vector<uint8> &data,
bool append = false);
/**
* @brief 读取文本文件到字符串(便捷方法)
* @param path 文件路径
* @return 文件内容,失败返回 std::nullopt
*/
std::optional<std::string> readFileToString(const std::string &path);
/**
* @brief 读取二进制文件到字节数组(便捷方法)
* @param path 文件路径
* @return 字节数组,失败返回 std::nullopt
*/
std::optional<std::vector<uint8>> readFileToBytes(const std::string &path);
// ---------------------------------------------------------------------------
// 文件/目录检查
// ---------------------------------------------------------------------------
/**
* @brief 检查路径是否存在
* @param path 路径
* @return 存在返回 true
*/
bool exists(const std::string &path) const;
/**
* @brief 检查路径是否为目录
* @param path 路径
* @return 是目录返回 true
*/
bool isDirectory(const std::string &path) const;
/**
* @brief 检查路径是否为普通文件
* @param path 路径
* @return 是普通文件返回 true
*/
bool isRegularFile(const std::string &path) const;
/**
* @brief 检查文件或目录是否为空
* @param path 路径
* @return 为空返回 true
*/
bool isEmpty(const std::string &path) const;
// ---------------------------------------------------------------------------
// 目录操作
// ---------------------------------------------------------------------------
/**
* @brief 创建单层目录
* @param path 目录路径
* @return 创建成功返回 true
*/
bool createDirectory(const std::string &path);
/**
* @brief 递归创建多层目录
* @param path 目录路径
* @return 创建成功返回 true
*/
bool createDirectories(const std::string &path);
/**
* @brief 删除文件
* @param path 文件路径
* @return 删除成功返回 true
*/
bool removeFile(const std::string &path);
/**
* @brief 删除目录及其所有内容
* @param path 目录路径
* @return 删除成功返回 true
*/
bool removeDirectory(const std::string &path);
// ---------------------------------------------------------------------------
// 文件操作
// ---------------------------------------------------------------------------
/**
* @brief 复制文件
* @param from 源文件路径
* @param to 目标文件路径
* @param overwrite 是否覆盖已存在的文件
* @return 复制成功返回 true
*/
bool copyFile(const std::string &from, const std::string &to,
bool overwrite = false);
/**
* @brief 移动文件
* @param from 源文件路径
* @param to 目标文件路径
* @return 移动成功返回 true
*/
bool moveFile(const std::string &from, const std::string &to);
/**
* @brief 重命名文件或目录
* @param oldPath 原路径
* @param newPath 新路径
* @return 重命名成功返回 true
*/
bool rename(const std::string &oldPath, const std::string &newPath);
// ---------------------------------------------------------------------------
// 目录遍历
// ---------------------------------------------------------------------------
/**
* @brief 列出目录中的所有文件
* @param directoryPath 目录路径
* @param recursive 是否递归遍历子目录
* @return 文件路径列表
*/
std::vector<std::string> listFiles(const std::string &directoryPath,
bool recursive = false);
/**
* @brief 列出目录中的所有子目录
* @param directoryPath 目录路径
* @param recursive 是否递归遍历子目录
* @return 子目录路径列表
*/
std::vector<std::string> listDirectories(const std::string &directoryPath,
bool recursive = false);
/**
* @brief 列出目录中的所有文件和子目录
* @param directoryPath 目录路径
* @param recursive 是否递归遍历子目录
* @return 所有项目路径列表
*/
std::vector<std::string> listAll(const std::string &directoryPath,
bool recursive = false);
/**
* @brief 按扩展名列出文件
* @param directoryPath 目录路径
* @param extension 文件扩展名(如 ".png"
* @param recursive 是否递归遍历子目录
* @return 匹配的文件路径列表
*/
std::vector<std::string>
listFilesWithExtension(const std::string &directoryPath,
const std::string &extension, bool recursive = false);
// ---------------------------------------------------------------------------
// 文件信息
// ---------------------------------------------------------------------------
/**
* @brief 获取文件详细信息
* @param path 文件路径
* @return 文件信息结构体
*/
FileInfo getFileInfo(const std::string &path);
/**
* @brief 获取文件大小
* @param path 文件路径
* @return 文件大小(字节)
*/
uint64 getFileSize(const std::string &path) const;
// ---------------------------------------------------------------------------
// 路径处理
// ---------------------------------------------------------------------------
/**
* @brief 获取文件名(包含扩展名)
* @param path 文件路径
* @return 文件名
*/
std::string getFileName(const std::string &path) const;
/**
* @brief 获取文件名(不含扩展名)
* @param path 文件路径
* @return 文件名
*/
std::string getFileNameWithoutExtension(const std::string &path) const;
/**
* @brief 获取文件扩展名
* @param path 文件路径
* @return 扩展名(包含点,如 ".txt"
*/
std::string getExtension(const std::string &path) const;
/**
* @brief 获取父目录路径
* @param path 文件路径
* @return 父目录路径
*/
std::string getParentPath(const std::string &path) const;
/**
* @brief 获取绝对路径
* @param path 相对或绝对路径
* @return 绝对路径
*/
std::string getAbsolutePath(const std::string &path) const;
/**
* @brief 获取规范路径(解析符号链接和相对路径)
* @param path 路径
* @return 规范化路径
*/
std::string getCanonicalPath(const std::string &path) const;
/**
* @brief 合并两个路径
* @param left 左侧路径
* @param right 右侧路径
* @return 合并后的路径
*/
std::string combinePath(const std::string &left,
const std::string &right) const;
/**
* @brief 规范化路径(转换为系统首选格式)
* @param path 路径
* @return 规范化路径
*/
std::string normalizePath(const std::string &path) const;
// ---------------------------------------------------------------------------
// 工作目录
// ---------------------------------------------------------------------------
/**
* @brief 获取当前工作目录
* @return 当前工作目录路径
*/
std::string getCurrentPath() const;
/**
* @brief 设置当前工作目录
* @param path 目录路径
* @return 设置成功返回 true
*/
bool setCurrentPath(const std::string &path);
/**
* @brief 设置资源工作目录
*
* 设置后,所有相对路径操作都将基于此目录。
*
* @param path 工作目录路径
*/
void setWorkingDirectory(const std::string &path);
/**
* @brief 获取资源工作目录
* @return 工作目录路径
*/
const std::string &getWorkingDirectory() const;
/**
* @brief 解析相对路径为完整路径
* @param relativePath 相对路径
* @return 完整路径
*/
std::string resolvePath(const std::string &relativePath) const;
// ---------------------------------------------------------------------------
// 资源根目录
// ---------------------------------------------------------------------------
/**
* @brief 设置资源根目录
* @param root 资源根目录路径
*/
void setAssetRoot(const std::string &root);
/**
* @brief 获取资源根目录
* @return 资源根目录路径
*/
const std::string &getAssetRoot() const;
/**
* @brief 解析资源相对路径
*
* 将相对路径解析为:工作目录/资源根目录/相对路径
*
* @param relativePath 相对路径
* @return 完整路径
*/
std::string resolveAssetPath(const std::string &relativePath) const;
private:
Asset() = default;
~Asset() = default;
fs::path toPath(const std::string &path) const;
std::string fromPath(const fs::path &path) const;
std::string resolveFullPath(const std::string &path) const;
std::string workingDirectory_;
std::string assetRoot_;
};
} // namespace frostbite2D