# 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 bool operator==(const ResourceHandle& lhs, const ResourceHandle& rhs)` | 判断两个句柄是否引用同一资源 | | `template bool operator!=(const ResourceHandle& lhs, const ResourceHandle& rhs)` | 判断两个句柄是否引用不同资源 | ## 实现说明 **引用计数**: 每次构造(拷贝或原始指针)或赋值操作都会调用 `ResourceManager::AddRef()` 增加引用计数。每次析构或 `Reset()` 调用都会调用 `ResourceManager::Release()` 减少引用计数。 **线程安全**: 引用计数操作在 `ResourceManager` 内部通过互斥锁保护。 **空句柄处理**: 对空句柄调用 `GetGUID()` 返回 `ResourceGUID(0)`,调用 `GetResourceType()` 返回 `ResourceType::Unknown`。 ## 使用示例 ```cpp #include #include using namespace XCEngine::Resources; // 创建句柄(从加载结果) ResourceHandle tex = ResourceManager::Get().Load("textures/player.png"); // 检查有效性 if (tex.IsValid()) { // 使用箭头操作符访问资源方法 const Containers::String& path = tex->GetPath(); } // 拷贝构造(引用计数 +1) ResourceHandle tex2 = tex; // 移动构造(引用计数不变) ResourceHandle tex3 = std::move(tex2); // 句柄失效,引用计数 -1 tex.Reset(); // 比较操作 ResourceHandle texA = ResourceManager::Get().Load("a.png"); ResourceHandle texB = ResourceManager::Get().Load("b.png"); if (texA == texB) { // 同一资源 } ``` ## 相关文档 - [IResource](iresource/iresource.md) - 资源基类 - [ResourceManager](resource-manager/resource-manager.md) - 资源管理器 - [Resources 总览](resources.md) - 返回模块总览