我正在为游戏引擎的资源管理器工作。
它应该能够管理图像,纹理,网格,但这不是问题。加载资源时,管理器将检查该资源是否已经存在于"缓存中。 (ptr存储在典型的数据结构中)。
我想知道如果用户已经加载了哪种资源我应该发回给用户。 我在想一个const ptr
template <typename T>
const T* getResource(string resourceName)
但它避免了修改资源本身的可能性。 如果我发送一个非const ptr,用户将能够修改会引起多重影响的资源。
shared_ptr怎么样?
有任何建议吗?
答案 0 :(得分:2)
启用资源管理器用户编辑/修改数据的一个主要问题是数据可能需要放大或缩小。
为什么没有一个getResource
函数返回一个指向常量数据的指针,而不是让一个getResourse
返回一个非常量指针(不共享),然后如果用户需要修改用户必须将其复制到某个私有内存,并修改它,然后使用setResource
函数设置新的资源数据,大小正确。
答案 1 :(得分:1)
在我的ResourceManager中,我存储了一个以std::string
作为查找并存储std::unique_ptr<Resource>
的地图。
std::map map<std::string, std::unique_ptr<Resource>>;
然后我有一个看起来像这样的get函数
const Resource& get(const std::string& name)
{
//search map for name, if it exists return it, else construct then return it
auto found = map.find(name);
if(found != map.end())
{
return *found->second;
}
// otherwise construct then return from map
}
我还有一个重载函数可以使用额外的参数(例如精灵表格的纹理矩形)等,另一个函数只返回Resource&
而不是常量函数。因此可以使用const ref来防止在其他地方更改对象。
这意味着ResourceManager负责资源的所有权,如果我们确保资源管理器在游戏应用程序结束之前没有被破坏,那么资源范围将始终有效。这种处理资源的方式还可以防止在我们在应用程序的其他地方使用资源之前检查资源是否为空(假设您对资源的构造进行了一些错误检查,并且资源最初处于有效状态)
用例如下
ResourceManager<Texture> texture_manager_;
// If texture.png exists already then we just get a ref
// otherwise it gets constructed, checked for validity, stored in the map
// and then returned as a ref. That way we know the object is in a valid state
Texture tex = texture_manager.get("texture.png");
最后的好处是这个ResourceManager使用RAII,当ResourceManager超出范围时(可能在受控点,即应用程序结束时),地图中的所有内容都将被正确销毁。