136 lines
3.1 KiB
C++
136 lines
3.1 KiB
C++
#pragma once
|
|
|
|
#include <resource/resource.h>
|
|
#include <types/ptr/intrusive_ptr.h>
|
|
#include <unordered_map>
|
|
#include <string>
|
|
#include <mutex>
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
namespace extra2d {
|
|
|
|
/**
|
|
* @brief 资源缓存模板类
|
|
*
|
|
* 管理资源的加载和缓存,支持线程安全
|
|
* T 必须是 Resource 的子类
|
|
*/
|
|
template<typename T, typename... LoadArgs>
|
|
class ResourceCache {
|
|
public:
|
|
using Loader = std::function<Ptr<T>(const std::string&, LoadArgs...)>;
|
|
|
|
ResourceCache() = default;
|
|
~ResourceCache() = default;
|
|
|
|
// 禁止拷贝
|
|
ResourceCache(const ResourceCache&) = delete;
|
|
ResourceCache& operator=(const ResourceCache&) = delete;
|
|
|
|
// 允许移动
|
|
ResourceCache(ResourceCache&&) = default;
|
|
ResourceCache& operator=(ResourceCache&&) = default;
|
|
|
|
/**
|
|
* @brief 获取资源(如果不存在则加载)
|
|
* @param path 资源路径
|
|
* @param args 加载参数
|
|
* @return 资源指针
|
|
*/
|
|
Ptr<T> get(const std::string& path, LoadArgs... args) {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
auto it = cache_.find(path);
|
|
if (it != cache_.end()) {
|
|
return it->second;
|
|
}
|
|
|
|
Ptr<T> resource;
|
|
if (customLoader_) {
|
|
resource = customLoader_(path, args...);
|
|
} else {
|
|
resource = defaultLoad(path, args...);
|
|
}
|
|
|
|
if (resource && resource->isLoaded()) {
|
|
cache_[path] = resource;
|
|
}
|
|
|
|
return resource;
|
|
}
|
|
|
|
/**
|
|
* @brief 预加载资源
|
|
* @param path 资源路径
|
|
* @param args 加载参数
|
|
* @return 资源指针
|
|
*/
|
|
Ptr<T> preload(const std::string& path, LoadArgs... args) {
|
|
return get(path, args...);
|
|
}
|
|
|
|
/**
|
|
* @brief 检查资源是否已缓存
|
|
* @param path 资源路径
|
|
* @return 是否已缓存
|
|
*/
|
|
bool has(const std::string& path) const {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
return cache_.find(path) != cache_.end();
|
|
}
|
|
|
|
/**
|
|
* @brief 移除资源
|
|
* @param path 资源路径
|
|
*/
|
|
void remove(const std::string& path) {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
cache_.erase(path);
|
|
}
|
|
|
|
/**
|
|
* @brief 清空缓存
|
|
*/
|
|
void clear() {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
cache_.clear();
|
|
}
|
|
|
|
/**
|
|
* @brief 设置自定义加载器
|
|
* @param loader 自定义加载函数
|
|
*/
|
|
void setLoader(Loader loader) {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
customLoader_ = loader;
|
|
}
|
|
|
|
/**
|
|
* @brief 获取缓存大小
|
|
* @return 缓存中的资源数量
|
|
*/
|
|
size_t size() const {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
return cache_.size();
|
|
}
|
|
|
|
private:
|
|
mutable std::mutex mutex_;
|
|
std::unordered_map<std::string, Ptr<T>> cache_;
|
|
Loader customLoader_;
|
|
|
|
/**
|
|
* @brief 默认加载函数
|
|
*/
|
|
Ptr<T> defaultLoad(const std::string& path, LoadArgs... args) {
|
|
Ptr<T> resource = makePtr<T>();
|
|
if (resource->loadFromFile(path, args...)) {
|
|
return resource;
|
|
}
|
|
return nullptr;
|
|
}
|
|
};
|
|
|
|
} // namespace extra2d
|