11 KiB
11 KiB
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. 初始化资源服务
#include <extra2d/extra2d.h>
using namespace extra2d;
// 创建资源服务
AssetService service;
service.init();
service.setRoot("assets");
// 注册加载器
service.registerLoader<TextureAsset>(AssetLoaderFactory::createTextureLoader());
service.registerLoader<FontAsset>(AssetLoaderFactory::createFontLoader());
service.registerLoader<ShaderAsset>(AssetLoaderFactory::createShaderLoader());
2. 同步加载资源
// 加载纹理
AssetHandle<TextureAsset> texture = service.load<TextureAsset>("sprites/player.png");
if (texture.valid()) {
int width = texture->width();
int height = texture->height();
const u8* data = texture->data();
}
3. 异步加载资源
// 异步加载
service.loadAsync<TextureAsset>("sprites/background.png",
[](AssetHandle<TextureAsset> handle) {
if (handle.valid()) {
// 资源加载完成,在主线程处理
}
});
// 在主线程处理回调
service.process();
4. 使用资源包
// 挂载资源包
service.mount("data.pak");
// 从资源包加载
auto texture = service.load<TextureAsset>("textures/hero.png");
// 卸载资源包
service.unmount("data.pak");
5. 缓存管理
// 设置缓存上限 (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
资源标识符,使用哈希值进行快速比较。
struct AssetID {
u64 hash; // 哈希值
std::string path; // 原始路径
explicit AssetID(const std::string& path);
bool valid() const;
bool operator==(const AssetID& other) const;
};
AssetHandle
类型安全的资源句柄,使用弱引用避免阻止资源回收。
template<typename T>
class AssetHandle {
public:
bool valid() const; // 检查是否有效
Ref<T> get() const; // 获取强引用
T* operator->() const; // 解引用
bool loaded() const; // 检查是否已加载
AssetState state() const; // 获取状态
};
AssetCache
LRU 缓存管理器。
class AssetCache {
public:
explicit AssetCache(size_t limit = 0);
template<typename T>
AssetHandle<T> add(Ref<T> asset);
template<typename T>
AssetHandle<T> 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
资源服务接口。
class IAssetService : public IService {
public:
// 同步加载
template<typename T>
AssetHandle<T> load(const std::string& path);
// 异步加载
template<typename T>
void loadAsync(const std::string& path, AssetLoadCallback<T> callback);
// 获取已缓存资源
template<typename T>
AssetHandle<T> get(const std::string& path);
// 预加载
template<typename T>
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<typename T>
void registerLoader(Unique<AssetLoader<T>> 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
数据处理管道,支持链式调用。
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<DataProcessor> processor);
std::vector<u8> process(const std::vector<u8>& input);
void clear();
bool empty() const;
size_t size() const;
};
AssetPackBuilder
资源包构建器。
class AssetPackBuilder {
public:
explicit AssetPackBuilder(Compression compression = Compression::None, int level = 3);
void add(const std::string& path, const std::vector<u8>& data);
void add(const std::string& path, std::vector<u8>&& 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 加载。
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 字体。
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
着色器资源。
class ShaderAsset : public Asset {
public:
AssetType type() const override { return AssetType::Shader; }
const std::string& vertexSource() const;
const std::string& fragmentSource() const;
};
AudioAsset
音频资源。
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
通用二进制数据。
class DataAsset : public Asset {
public:
AssetType type() const override { return AssetType::Data; }
const u8* data() const;
size_t size() const;
};
资源打包工具
安装
xmake build asset_packer
用法
Extra2D 资源打包工具 v1.0.0
用法:
asset_packer create <output.pack> [options] <inputs...>
asset_packer list <pack file>
asset_packer extract <pack file> <output dir>
命令:
create 创建资源包
list 列出资源包内容
extract 提取资源包内容
选项:
-c, --compression <algo> 压缩算法 (none, zstd, lz4, zlib),默认 zstd
-l, --level <level> 压缩级别 (1-22),默认 3
-e, --encrypt <key> 加密密钥
-t, --encrypt-type <type> 加密类型 (xor, aes),默认 xor
-v, --verbose 详细输出
-h, --help 显示帮助
示例
# 创建资源包(使用 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)
不同资源类型使用不同的加载策略。
class AssetLoader<T> {
public:
virtual Ref<T> load(const std::string& path) = 0;
virtual Ref<T> 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<std::string> extensions() const = 0;
};
享元模式 (AssetCache)
共享资源实例,减少内存占用。
装饰器模式 (DataProcessor)
链式处理数据流。
DataPipe pipe;
pipe.encrypt("key")
.compress(Compression::Zstd);
服务定位器模式
全局访问资源服务。
auto* service = ServiceLocator::get<IAssetService>();
线程安全
AssetCache使用读写锁 (std::shared_mutex)AssetService使用读写锁保护资源映射- 异步加载使用独立的工作线程
- 回调在主线程执行(需要调用
process())
最佳实践
1. 资源路径约定
assets/
├── textures/
│ ├── sprites/
│ └── backgrounds/
├── fonts/
├── shaders/
└── audio/
2. 预加载关键资源
// 游戏启动时预加载
service.preload<TextureAsset>("textures/loading.png");
service.preload<FontAsset>("fonts/main.ttf");
3. 合理设置缓存上限
// 根据目标平台设置
#ifdef MOBILE
service.setLimit(50 * 1024 * 1024); // 50MB
#else
service.setLimit(200 * 1024 * 1024); // 200MB
#endif
4. 定期清理缓存
// 场景切换时清理
void onSceneChange() {
service.purge();
}
5. 使用资源包减少文件数量
// 将小文件打包成资源包
// 减少文件 I/O 操作,提高加载速度
service.mount("textures.pak");
service.mount("audio.pak");
错误处理
auto handle = service.load<TextureAsset>("missing.png");
if (!handle.valid()) {
// 资源加载失败
std::cerr << "Failed to load texture\n";
}
// 检查加载状态
if (handle.state() == AssetState::Failed) {
// 处理失败情况
}
版本历史
- v1.0.0 - 初始版本
- 资源加载和缓存
- 资源打包和加密
- 异步加载支持
- 多种压缩算法