# Extra2D 资源服务系统 ## 概述 Extra2D 资源服务系统提供了一套完整的资源管理解决方案,包括资源加载、缓存、打包和加密压缩功能。 ### 主要特性 - **类型安全**:使用模板和强类型 ID 避免类型错误 - **自动缓存**:LRU 缓存策略,自动管理内存 - **异步加载**:后台线程加载,不阻塞主线程 - **资源打包**:支持压缩和加密的资源包格式 - **多格式支持**:纹理、字体、着色器、音频等 ## 模块结构 ``` extra2d/asset/ ├── asset_types.h # 资源类型定义 ├── asset.h # 资源基类 ├── asset_handle.h # 资源句柄 ├── asset_cache.h # 资源缓存 ├── asset_loader.h # 资源加载器 ├── asset_pack.h # 资源包 ├── data_processor.h # 数据处理器 └── asset_service.h # 资源服务 ``` ## 快速开始 ### 1. 初始化资源服务 ```cpp #include using namespace extra2d; // 创建资源服务 AssetService service; service.init(); service.setRoot("assets"); // 注册加载器 service.registerLoader(AssetLoaderFactory::createTextureLoader()); service.registerLoader(AssetLoaderFactory::createFontLoader()); service.registerLoader(AssetLoaderFactory::createShaderLoader()); ``` ### 2. 同步加载资源 ```cpp // 加载纹理 AssetHandle texture = service.load("sprites/player.png"); if (texture.valid()) { int width = texture->width(); int height = texture->height(); const u8* data = texture->data(); } ``` ### 3. 异步加载资源 ```cpp // 异步加载 service.loadAsync("sprites/background.png", [](AssetHandle handle) { if (handle.valid()) { // 资源加载完成,在主线程处理 } }); // 在主线程处理回调 service.process(); ``` ### 4. 使用资源包 ```cpp // 挂载资源包 service.mount("data.pak"); // 从资源包加载 auto texture = service.load("textures/hero.png"); // 卸载资源包 service.unmount("data.pak"); ``` ### 5. 缓存管理 ```cpp // 设置缓存上限 (100MB) service.setLimit(100 * 1024 * 1024); // 获取缓存统计 CacheStats stats = service.stats(); std::cout << "缓存使用: " << stats.bytes << " 字节\n"; std::cout << "命中率: " << (stats.hitRate() * 100) << "%\n"; // 清理无引用资源 service.purge(); // 清空缓存 service.clear(); ``` ## API 参考 ### AssetID 资源标识符,使用哈希值进行快速比较。 ```cpp struct AssetID { u64 hash; // 哈希值 std::string path; // 原始路径 explicit AssetID(const std::string& path); bool valid() const; bool operator==(const AssetID& other) const; }; ``` ### AssetHandle 类型安全的资源句柄,使用弱引用避免阻止资源回收。 ```cpp template class AssetHandle { public: bool valid() const; // 检查是否有效 Ref get() const; // 获取强引用 T* operator->() const; // 解引用 bool loaded() const; // 检查是否已加载 AssetState state() const; // 获取状态 }; ``` ### AssetCache LRU 缓存管理器。 ```cpp class AssetCache { public: explicit AssetCache(size_t limit = 0); template AssetHandle add(Ref asset); template AssetHandle get(const AssetID& id); bool has(const AssetID& id) const; bool remove(const AssetID& id); void setLimit(size_t limit); size_t bytes() const; size_t count() const; size_t purge(); // 清理无引用资源 void clear(); // 清空缓存 CacheStats stats() const; }; ``` ### IAssetService 资源服务接口。 ```cpp class IAssetService : public IService { public: // 同步加载 template AssetHandle load(const std::string& path); // 异步加载 template void loadAsync(const std::string& path, AssetLoadCallback callback); // 获取已缓存资源 template AssetHandle get(const std::string& path); // 预加载 template void preload(const std::string& path); // 状态查询 bool isLoaded(const std::string& path) const; bool isLoading(const std::string& path) const; // 资源管理 void unload(const std::string& path); void setLimit(size_t maxBytes); size_t size() const; void purge(); void clear(); CacheStats stats() const; // 加载器注册 template void registerLoader(Unique> loader); // 资源包管理 bool mount(const std::string& path); void unmount(const std::string& path); // 数据处理管道 void setPipe(DataPipe pipe); // 根目录 void setRoot(const std::string& path); std::string root() const; // 处理异步回调 void process(); }; ``` ### DataPipe 数据处理管道,支持链式调用。 ```cpp class DataPipe { public: DataPipe& decrypt(const std::string& key, Decryptor::Type type = Decryptor::Type::XOR); DataPipe& decompress(Compression algo); DataPipe& encrypt(const std::string& key, Decryptor::Type type = Decryptor::Type::XOR); DataPipe& compress(Compression algo, int level = 3); DataPipe& add(Unique processor); std::vector process(const std::vector& input); void clear(); bool empty() const; size_t size() const; }; ``` ### AssetPackBuilder 资源包构建器。 ```cpp class AssetPackBuilder { public: explicit AssetPackBuilder(Compression compression = Compression::None, int level = 3); void add(const std::string& path, const std::vector& data); void add(const std::string& path, std::vector&& data); bool addFile(const std::string& filePath, const std::string& packPath = ""); size_t addDirectory(const std::string& dirPath, const std::string& prefix = ""); void setEncryption(const std::string& key, Decryptor::Type type = Decryptor::Type::XOR); bool build(const std::string& outputPath); void clear(); size_t count() const; size_t totalOriginalSize() const; size_t totalCompressedSize() const; }; ``` ## 资源类型 ### TextureAsset 纹理资源,使用 stb_image 加载。 ```cpp class TextureAsset : public Asset { public: AssetType type() const override { return AssetType::Texture; } int width() const; int height() const; int channels() const; const u8* data() const; size_t dataSize() const; }; ``` ### FontAsset 字体资源,支持 TrueType 字体。 ```cpp class FontAsset : public Asset { public: AssetType type() const override { return AssetType::Font; } float scaleForPixelHeight(float pixels) const; const u8* data() const; size_t dataSize() const; }; ``` ### ShaderAsset 着色器资源。 ```cpp class ShaderAsset : public Asset { public: AssetType type() const override { return AssetType::Shader; } const std::string& vertexSource() const; const std::string& fragmentSource() const; }; ``` ### AudioAsset 音频资源。 ```cpp class AudioAsset : public Asset { public: AssetType type() const override { return AssetType::Audio; } AudioFormat format() const; int channels() const; int sampleRate() const; int bitsPerSample() const; float duration() const; const u8* data() const; size_t dataSize() const; bool streaming() const; }; ``` ### DataAsset 通用二进制数据。 ```cpp class DataAsset : public Asset { public: AssetType type() const override { return AssetType::Data; } const u8* data() const; size_t size() const; }; ``` ## 资源打包工具 ### 安装 ```bash xmake build asset_packer ``` ### 用法 ``` Extra2D 资源打包工具 v1.0.0 用法: asset_packer create [options] asset_packer list asset_packer extract 命令: create 创建资源包 list 列出资源包内容 extract 提取资源包内容 选项: -c, --compression 压缩算法 (none, zstd, lz4, zlib),默认 zstd -l, --level 压缩级别 (1-22),默认 3 -e, --encrypt 加密密钥 -t, --encrypt-type 加密类型 (xor, aes),默认 xor -v, --verbose 详细输出 -h, --help 显示帮助 ``` ### 示例 ```bash # 创建资源包(使用 Zstd 压缩) asset_packer create game.pak -c zstd -v assets/ # 创建加密资源包 asset_packer create game.pak -c zstd -e "secret_key" -t xor -v assets/ # 列出资源包内容 asset_packer list game.pak # 提取资源包 asset_packer extract game.pak extracted/ # 使用不同压缩算法 asset_packer create game.pak -c lz4 -v assets/ asset_packer create game.pak -c zlib -l 9 -v assets/ ``` ## 压缩算法对比 | 算法 | 压缩率 | 压缩速度 | 解压速度 | 适用场景 | |------|--------|----------|----------|----------| | Zstd | 高 | 快 | 很快 | 通用推荐 | | LZ4 | 中 | 很快 | 很快 | 实时解压 | | Zlib | 高 | 中 | 中 | 兼容性好 | | None | - | - | - | 已压缩资源 | ## 设计模式 ### 策略模式 (AssetLoader) 不同资源类型使用不同的加载策略。 ```cpp class AssetLoader { public: virtual Ref load(const std::string& path) = 0; virtual Ref loadFromMemory(const u8* data, size_t size) = 0; virtual bool canLoad(const std::string& path) const = 0; virtual AssetType type() const = 0; virtual std::vector extensions() const = 0; }; ``` ### 享元模式 (AssetCache) 共享资源实例,减少内存占用。 ### 装饰器模式 (DataProcessor) 链式处理数据流。 ```cpp DataPipe pipe; pipe.encrypt("key") .compress(Compression::Zstd); ``` ### 服务定位器模式 全局访问资源服务。 ```cpp auto* service = ServiceLocator::get(); ``` ## 线程安全 - `AssetCache` 使用读写锁 (`std::shared_mutex`) - `AssetService` 使用读写锁保护资源映射 - 异步加载使用独立的工作线程 - 回调在主线程执行(需要调用 `process()`) ## 最佳实践 ### 1. 资源路径约定 ``` assets/ ├── textures/ │ ├── sprites/ │ └── backgrounds/ ├── fonts/ ├── shaders/ └── audio/ ``` ### 2. 预加载关键资源 ```cpp // 游戏启动时预加载 service.preload("textures/loading.png"); service.preload("fonts/main.ttf"); ``` ### 3. 合理设置缓存上限 ```cpp // 根据目标平台设置 #ifdef MOBILE service.setLimit(50 * 1024 * 1024); // 50MB #else service.setLimit(200 * 1024 * 1024); // 200MB #endif ``` ### 4. 定期清理缓存 ```cpp // 场景切换时清理 void onSceneChange() { service.purge(); } ``` ### 5. 使用资源包减少文件数量 ```cpp // 将小文件打包成资源包 // 减少文件 I/O 操作,提高加载速度 service.mount("textures.pak"); service.mount("audio.pak"); ``` ## 错误处理 ```cpp auto handle = service.load("missing.png"); if (!handle.valid()) { // 资源加载失败 std::cerr << "Failed to load texture\n"; } // 检查加载状态 if (handle.state() == AssetState::Failed) { // 处理失败情况 } ``` ## 版本历史 - **v1.0.0** - 初始版本 - 资源加载和缓存 - 资源打包和加密 - 异步加载支持 - 多种压缩算法