#include #include #include #include #include #include namespace mbgl { class FileSourceManager::Impl { public: using Key = std::tuple; std::map> fileSources; std::map fileSourceFactories; std::recursive_mutex mutex; }; FileSourceManager::FileSourceManager() : impl(std::make_unique()) {} FileSourceManager::~FileSourceManager() = default; std::shared_ptr 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->second.expired() ? impl->fileSources.erase(it) : ++it; } const auto context = reinterpret_cast(options.platformContext()); const std::string optionsKey = options.baseURL() + '|' + options.accessToken() + '|' + options.cachePath() + '|' + util::toString(context); const auto key = std::tie(type, optionsKey); std::shared_ptr fileSource; auto tuple = impl->fileSources.find(key); if (tuple != impl->fileSources.end()) { fileSource = tuple->second.lock(); } if (!fileSource) { auto it = impl->fileSourceFactories.find(type); if (it != impl->fileSourceFactories.end()) { assert(it->second); impl->fileSources[key] = fileSource = it->second(options); } } 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