114 lines
3.8 KiB
Markdown
114 lines
3.8 KiB
Markdown
|
|
# ResourceHandle
|
|||
|
|
|
|||
|
|
**命名空间**: `XCEngine::Resources`
|
|||
|
|
|
|||
|
|
**类型**: `class template`
|
|||
|
|
|
|||
|
|
**头文件**: `XCEngine/Core/Asset/ResourceHandle.h`
|
|||
|
|
|
|||
|
|
**模板参数**: `T` - 资源类型,必须继承自 `IResource`
|
|||
|
|
|
|||
|
|
**描述**: 资源句柄模板类,提供资源的类型安全引用和自动引用计数管理。
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
`ResourceHandle` 是一个模板智能指针类,用于安全引用 `IResource` 子类实例。它自动管理引用计数,当句柄被销毁或重置时,相应的资源引用计数会递减。这确保了资源在其被所有句柄释放前不会被卸载。
|
|||
|
|
|
|||
|
|
## 公共方法
|
|||
|
|
|
|||
|
|
### 构造与赋值
|
|||
|
|
|
|||
|
|
| 方法 | 描述 |
|
|||
|
|
|------|------|
|
|||
|
|
| `ResourceHandle()` | 默认构造,创建空句柄 |
|
|||
|
|
| `explicit ResourceHandle(T* resource)` | 从原始指针构造,增加引用计数 |
|
|||
|
|
| `ResourceHandle(const ResourceHandle& other)` | 拷贝构造,增加引用计数 |
|
|||
|
|
| `ResourceHandle(ResourceHandle&& other) noexcept` | 移动构造,不增加引用计数 |
|
|||
|
|
| `ResourceHandle& operator=(const ResourceHandle& other)` | 拷贝赋值,先释放当前引用再增加新引用 |
|
|||
|
|
| `ResourceHandle& operator=(ResourceHandle&& other) noexcept` | 移动赋值 |
|
|||
|
|
|
|||
|
|
### 资源访问
|
|||
|
|
|
|||
|
|
| 方法 | 描述 |
|
|||
|
|
|------|------|
|
|||
|
|
| `T* Get() const` | 获取原始指针 |
|
|||
|
|
| `T* operator->() const` | 通过箭头操作符访问资源方法 |
|
|||
|
|
| `T& operator*() const` | 解引用获取资源引用 |
|
|||
|
|
|
|||
|
|
### 状态查询
|
|||
|
|
|
|||
|
|
| 方法 | 描述 |
|
|||
|
|
|------|------|
|
|||
|
|
| `bool IsValid() const` | 检查句柄是否有效(非空且资源有效) |
|
|||
|
|
| `explicit operator bool() const` | 隐式转换为 bool |
|
|||
|
|
|
|||
|
|
### GUID 与类型
|
|||
|
|
|
|||
|
|
| 方法 | 描述 |
|
|||
|
|
|------|------|
|
|||
|
|
| `ResourceGUID GetGUID() const` | 获取资源的全局唯一标识符 |
|
|||
|
|
| `ResourceType GetResourceType() const` | 获取资源类型 |
|
|||
|
|
|
|||
|
|
### 句柄操作
|
|||
|
|
|
|||
|
|
| 方法 | 描述 |
|
|||
|
|
|------|------|
|
|||
|
|
| `void Reset()` | 释放当前引用,将句柄置为空 |
|
|||
|
|
| `void Swap(ResourceHandle& other)` | 交换两个句柄的引用 |
|
|||
|
|
|
|||
|
|
## 操作符重载
|
|||
|
|
|
|||
|
|
| 操作符 | 描述 |
|
|||
|
|
|------|------|
|
|||
|
|
| `template<typename T> bool operator==(const ResourceHandle<T>& lhs, const ResourceHandle<T>& rhs)` | 判断两个句柄是否引用同一资源 |
|
|||
|
|
| `template<typename T> bool operator!=(const ResourceHandle<T>& lhs, const ResourceHandle<T>& rhs)` | 判断两个句柄是否引用不同资源 |
|
|||
|
|
|
|||
|
|
## 实现说明
|
|||
|
|
|
|||
|
|
**引用计数**: 每次构造(拷贝或原始指针)或赋值操作都会调用 `ResourceManager::AddRef()` 增加引用计数。每次析构或 `Reset()` 调用都会调用 `ResourceManager::Release()` 减少引用计数。
|
|||
|
|
|
|||
|
|
**线程安全**: 引用计数操作在 `ResourceManager` 内部通过互斥锁保护。
|
|||
|
|
|
|||
|
|
**空句柄处理**: 对空句柄调用 `GetGUID()` 返回 `ResourceGUID(0)`,调用 `GetResourceType()` 返回 `ResourceType::Unknown`。
|
|||
|
|
|
|||
|
|
## 使用示例
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
#include <XCEngine/Core/Asset/ResourceHandle.h>
|
|||
|
|
#include <XCEngine/Resources/Texture.h>
|
|||
|
|
|
|||
|
|
using namespace XCEngine::Resources;
|
|||
|
|
|
|||
|
|
// 创建句柄(从加载结果)
|
|||
|
|
ResourceHandle<Texture> tex = ResourceManager::Get().Load<Texture>("textures/player.png");
|
|||
|
|
|
|||
|
|
// 检查有效性
|
|||
|
|
if (tex.IsValid()) {
|
|||
|
|
// 使用箭头操作符访问资源方法
|
|||
|
|
const Containers::String& path = tex->GetPath();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 拷贝构造(引用计数 +1)
|
|||
|
|
ResourceHandle<Texture> tex2 = tex;
|
|||
|
|
|
|||
|
|
// 移动构造(引用计数不变)
|
|||
|
|
ResourceHandle<Texture> tex3 = std::move(tex2);
|
|||
|
|
|
|||
|
|
// 句柄失效,引用计数 -1
|
|||
|
|
tex.Reset();
|
|||
|
|
|
|||
|
|
// 比较操作
|
|||
|
|
ResourceHandle<Texture> texA = ResourceManager::Get().Load<Texture>("a.png");
|
|||
|
|
ResourceHandle<Texture> texB = ResourceManager::Get().Load<Texture>("b.png");
|
|||
|
|
|
|||
|
|
if (texA == texB) {
|
|||
|
|
// 同一资源
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 相关文档
|
|||
|
|
|
|||
|
|
- [IResource](iresource/iresource.md) - 资源基类
|
|||
|
|
- [ResourceManager](resource-manager/resource-manager.md) - 资源管理器
|
|||
|
|
- [Resources 总览](resources.md) - 返回模块总览
|