#include #include #include #include #include #include #include #include namespace mbgl { struct FileSourceInfo { FileSourceInfo(FileSourceType type_, std::string id_, std::weak_ptr fileSource_) : type(type_), id(std::move(id_)), fileSource(std::move(fileSource_)) {} FileSourceType type; std::string id; std::weak_ptr fileSource; }; class FileSourceManager::Impl { public: std::list fileSources; std::map fileSourceFactories; std::recursive_mutex mutex; }; FileSourceManager::FileSourceManager() : impl(std::make_unique()) {} FileSourceManager::~FileSourceManager() = default; PassRefPtr FileSourceManager::getFileSource(FileSourceType type, const ResourceOptions& options) noexcept { std::lock_guard lock(impl->mutex); // Remove released file sources. for (auto it = impl->fileSources.begin(); it != impl->fileSources.end();) { it = it->fileSource.expired() ? impl->fileSources.erase(it) : ++it; } const auto context = reinterpret_cast(options.platformContext()); std::string id = options.baseURL() + '|' + options.accessToken() + '|' + options.cachePath() + '|' + util::toString(context); std::shared_ptr fileSource; auto fileSourceIt = std::find_if(impl->fileSources.begin(), impl->fileSources.end(), [type, &id](const auto& info) { return info.type == type && info.id == id; }); if (fileSourceIt != impl->fileSources.end()) { fileSource = fileSourceIt->fileSource.lock(); } if (!fileSource) { auto it = impl->fileSourceFactories.find(type); if (it != impl->fileSourceFactories.end()) { assert(it->second); fileSource = it->second(options); impl->fileSources.emplace_back(type, std::move(id), fileSource); } } return fileSource; } void FileSourceManager::registerFileSourceFactory(FileSourceType type, FileSourceFactory&& factory) noexcept { assert(factory); std::lock_guard lock(impl->mutex); impl->fileSourceFactories[type] = std::move(factory); } FileSourceManager::FileSourceFactory FileSourceManager::unRegisterFileSourceFactory(FileSourceType type) noexcept { std::lock_guard lock(impl->mutex); auto it = impl->fileSourceFactories.find(type); FileSourceFactory factory; if (it != impl->fileSourceFactories.end()) { factory = std::move(it->second); impl->fileSourceFactories.erase(it); } return factory; } } // namespace mbgl