Line data Source code
1 : // Copyright 2024 OpenModelViewer Authors 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // http://www.apache.org/licenses/LICENSE-2.0 7 : // 8 : // Unless required by applicable law or agreed to in writing, software 9 : // distributed under the License is distributed on an "AS IS" BASIS, 10 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 : // See the License for the specific language governing permissions and 12 : // limitations under the License. 13 : // 14 : 15 : #include "openmodelviewer/core/resource/resource_manager.hpp" 16 : #include "openmodelviewer/core/resource/loader/text_loader.hpp" 17 : 18 : namespace openmodelviewer::core::resource 19 : { 20 50 : ResourceManager::ResourceManager(TaskScheduler& scheduler) 21 50 : : m_scheduler(scheduler) 22 : { 23 : // Import loaders 24 50 : ResourceLoaderRegistry<std::string>::loader = loader::loadTextFile; 25 50 : } 26 : 27 50 : ResourceManager::~ResourceManager() 28 : { 29 50 : this->clear(); 30 50 : } 31 : 32 16 : ResourceStatus ResourceManager::getStatus(const ResourceHandle& handle) const noexcept 33 : { 34 16 : std::lock_guard<std::mutex> lockg(m_loadMutex); 35 16 : if (m_loadTasks.contains(handle)) 36 : { 37 8 : return m_loadTasks.at(handle)->errored() ? ResourceStatus::Failed : ResourceStatus::Loading; 38 : } 39 : 40 8 : if (isCached(handle)) 41 : { 42 2 : return ResourceStatus::Ready; 43 : } 44 : 45 6 : return ResourceStatus::Invalid; 46 16 : } 47 : 48 3 : void ResourceManager::rethrowAndForget(const ResourceHandle& handle) 49 : { 50 3 : std::shared_ptr<ITaskData> tdata; 51 : 52 : { 53 3 : std::lock_guard<std::mutex> lockg(m_loadMutex); 54 3 : auto it = m_loadTasks.find(handle); 55 3 : if (it == m_loadTasks.end()) 56 : { 57 2 : throw std::logic_error("Cannot rethrow: no errored task exist for this handle."); 58 : } 59 : 60 1 : tdata = it->second; 61 : 62 1 : if (!tdata->errored()) 63 : { 64 0 : throw std::logic_error("Cannot rethrow: task did not fail."); 65 : } 66 : 67 1 : m_loadTasks.erase(it); 68 3 : } 69 : 70 2 : std::rethrow_exception(tdata->exception()); 71 3 : } 72 : 73 4 : std::exception_ptr ResourceManager::getErrorAndForget(const ResourceHandle& handle) noexcept 74 : { 75 4 : std::shared_ptr<ITaskData> tdata; 76 : 77 : { 78 4 : std::lock_guard<std::mutex> lockg(m_loadMutex); 79 4 : auto it = m_loadTasks.find(handle); 80 4 : if (it == m_loadTasks.end()) 81 : { 82 2 : return nullptr; 83 : } 84 : 85 2 : tdata = it->second; 86 : 87 2 : if (!tdata->errored()) 88 : { 89 0 : return nullptr; 90 : } 91 : 92 2 : m_loadTasks.erase(it); 93 4 : } 94 : 95 2 : return tdata->exception(); 96 4 : } 97 : 98 5 : bool ResourceManager::free(const ResourceHandle& handle) noexcept 99 : { 100 5 : std::lock_guard<std::mutex> lockg(m_loadMutex); 101 5 : if (m_loadTasks.contains(handle)) 102 : { 103 1 : if (m_loadTasks.at(handle)->errored()) 104 : { 105 0 : m_loadTasks.erase(handle); 106 0 : return true; 107 : } 108 : else 109 : { 110 1 : return false; 111 : } 112 : } 113 : 114 4 : std::unique_lock<std::shared_mutex> ulock(m_cacheMutex); 115 4 : for (auto& it : m_cache) 116 : { 117 3 : if (it.second->remove(handle)) 118 : { 119 3 : return true; 120 : } 121 : } 122 : 123 1 : return false; 124 5 : } 125 : 126 52 : void ResourceManager::clear() noexcept 127 : { 128 : { 129 52 : std::lock_guard<std::mutex> lockg(m_loadMutex); 130 52 : m_loadTasks.clear(); 131 52 : } 132 : 133 52 : std::unique_lock<std::shared_mutex> ulock(m_cacheMutex); 134 70 : for (auto& it : m_cache) 135 : { 136 18 : it.second->clear(); 137 : } 138 52 : } 139 : 140 8 : bool ResourceManager::isCached(const ResourceHandle& handle) const noexcept 141 : { 142 8 : std::unique_lock<std::shared_mutex> ulock(m_cacheMutex); 143 12 : for (auto& it : m_cache) 144 : { 145 6 : if (it.second->contains(handle)) 146 : { 147 2 : return true; 148 : } 149 : } 150 : 151 6 : return false; 152 8 : } 153 : }