| 69 | } |
| 70 | |
| 71 | std::shared_ptr<IResource> ResourceManager::LoadResourceProcess(const std::string& filePath, bool loadExact) { |
| 72 | // Check for and remove the OTR signature |
| 73 | if (OtrSignatureCheck(filePath.c_str())) { |
| 74 | const auto newFilePath = filePath.substr(7); |
| 75 | return LoadResourceProcess(newFilePath); |
| 76 | } |
| 77 | |
| 78 | // Attempt to load the alternate version of the asset, if we fail then we continue trying to load the standard |
| 79 | // asset. |
| 80 | if (!loadExact && mAltAssetsEnabled && !filePath.starts_with(IResource::gAltAssetPrefix)) { |
| 81 | const auto altPath = IResource::gAltAssetPrefix + filePath; |
| 82 | auto altResource = LoadResourceProcess(altPath, loadExact); |
| 83 | |
| 84 | if (altResource != nullptr) { |
| 85 | return altResource; |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | // While waiting in the queue, another thread could have loaded the resource. |
| 90 | // In a last attempt to avoid doing work that will be discarded, let's check if the cached version exists. |
| 91 | auto cacheLine = CheckCache(filePath, loadExact); |
| 92 | auto cachedResource = GetCachedResource(cacheLine); |
| 93 | if (cachedResource != nullptr) { |
| 94 | return cachedResource; |
| 95 | } |
| 96 | |
| 97 | // Check for resource load errors which can indicate an alternate asset. |
| 98 | // If we are attempting to load an alternate asset, we can return null |
| 99 | if (!loadExact && mAltAssetsEnabled && filePath.starts_with(IResource::gAltAssetPrefix)) { |
| 100 | if (std::holds_alternative<ResourceLoadError>(cacheLine)) { |
| 101 | try { |
| 102 | // If we have attempted to cache an alternate asset, but failed, we return nullptr and rely on the |
| 103 | // calling function to return a regular asset. If we have NOT attempted load already, attempt the load. |
| 104 | auto loadError = std::get<ResourceLoadError>(cacheLine); |
| 105 | if (loadError != ResourceLoadError::NotCached) { |
| 106 | return nullptr; |
| 107 | } |
| 108 | } catch (std::bad_variant_access const& e) { |
| 109 | // Ignore the exception. This should never happen. The last check should've returned the resource. |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | // Get the file from the OTR |
| 115 | auto file = LoadFileProcess(filePath); |
| 116 | if (file == nullptr) { |
| 117 | SPDLOG_TRACE("Failed to load resource file at path {}", filePath); |
| 118 | } |
| 119 | |
| 120 | // Transform the raw data into a resource |
| 121 | auto resource = GetResourceLoader()->LoadResource(file); |
| 122 | |
| 123 | // Another thread could have loaded the resource while we were processing, so we want to check before setting to |
| 124 | // the cache. |
| 125 | cachedResource = GetCachedResource(filePath, true); |
| 126 | { |
| 127 | const std::lock_guard<std::mutex> lock(mMutex); |
| 128 |
no test coverage detected