#pragma once #include #include #include #include namespace extra2d { /** * @brief 密集存储的资源仓库 * * 使用 Dense Vec 存储,类似 ECS 的组件存储。 * 提供 O(1) 的插入、删除、访问。 * * @tparam T 资源类型 */ template class AssetStorage { public: struct Slot { Ptr asset; typename Handle::Generation generation = 0; bool active = false; }; AssetStorage() = default; ~AssetStorage() = default; AssetStorage(const AssetStorage&) = delete; AssetStorage& operator=(const AssetStorage&) = delete; /** * @brief 插入资源,返回句柄 * @param asset 资源指针 * @return 资源句柄 */ Handle insert(Ptr asset) { uint32_t index; if (!freeIndices_.empty()) { index = freeIndices_.back(); freeIndices_.pop_back(); slots_[index].asset = std::move(asset); slots_[index].active = true; } else { index = static_cast(slots_.size()); Slot slot; slot.asset = std::move(asset); slot.generation = nextGeneration_++; slot.active = true; slots_.push_back(std::move(slot)); } ++activeCount_; return Handle(index, slots_[index].generation); } /** * @brief 移除资源 * @param handle 资源句柄 */ void remove(Handle handle) { if (!isValid(handle)) return; uint32_t index = handle.index(); slots_[index].asset.reset(); slots_[index].active = false; slots_[index].generation = nextGeneration_++; freeIndices_.push_back(index); --activeCount_; } /** * @brief 获取资源(返回指针,可能为 nullptr) * @param handle 资源句柄 * @return 资源指针 */ T* get(Handle handle) const { if (!isValid(handle)) return nullptr; return slots_[handle.index()].asset.get(); } /** * @brief 获取资源(返回智能指针) * @param handle 资源句柄 * @return 资源智能指针 */ Ptr getPtr(Handle handle) const { if (!isValid(handle)) return Ptr(); return slots_[handle.index()].asset; } /** * @brief 检查句柄是否有效 * @param handle 资源句柄 * @return 是否有效 */ bool isValid(Handle handle) const { if (!handle.isValid()) return false; uint32_t index = handle.index(); if (index >= slots_.size()) return false; const Slot& slot = slots_[index]; return slot.active && slot.generation == handle.generation(); } /** * @brief 遍历所有资源 * @param func 回调函数,签名 void(Handle, T*) */ template void forEach(Func&& func) const { for (size_t i = 0; i < slots_.size(); ++i) { const Slot& slot = slots_[i]; if (slot.active && slot.asset) { func(Handle(static_cast(i), slot.generation), slot.asset.get()); } } } /** * @brief 清空所有资源 */ void clear() { slots_.clear(); freeIndices_.clear(); activeCount_ = 0; } /** * @brief 获取活跃资源数量 */ size_t count() const { return activeCount_; } /** * @brief 获取存储容量 */ size_t capacity() const { return slots_.size(); } private: std::vector slots_; std::vector freeIndices_; uint32_t nextGeneration_ = 1; size_t activeCount_ = 0; }; } // namespace extra2d