| #include "CResourcesManager.h"
|
| #include "CEngine.h"
|
| #include "CLogger.h"
|
| #include "CGenericResource.h"
|
| #include "U_ScriptClasses.h"
|
|
|
| #include <algorithm>
|
| #include <stdexcept>
|
| #include <filesystem>
|
|
|
| #include "U_Log.h"
|
|
|
| CResourcesManager::CResourcesManager()
|
| {
|
| AsyncLoadingPool.SetThreadsAmount(4); //TODO not hardcoded
|
| }
|
|
|
| void CResourcesManager::RegisterResource(const std::shared_ptr<CResource>& res)
|
| {
|
| if(!res || res->Name.empty()) { COMPONENT_CALL(CLogger, Err(L"Tried to register invalid resource (null/empty name)\n")); return; }
|
| if(std::find_if(Resources.begin(), Resources.end(), [&res](auto& kv) -> bool
|
| {
|
| return kv.second.lock() == res;
|
| }) != Resources.end()) { throw std::runtime_error("Tried to register resource that is already registered\n"); }
|
|
|
| if(Resources.find({ res->GetType(), res->Name }) != Resources.end()) { COMPONENT_CALL(CLogger, Err(L"Tried to register resource with occupied name\n")); return; }
|
|
|
| Resources.emplace(std::make_pair(res->GetType(), res->Name), res);
|
| //Log::Instance() << "Registered resource " << res->Name << " type " << res->GetType() << "\n"; LOGLOG
|
| }
|
|
|
| void CResourcesManager::V_DeInit()
|
| {
|
| AsyncLoadingPool.Stop();
|
|
|
| Cache.Clear();
|
| Resources.clear();
|
| }
|
|
|
| void CResourcesManager::StopResource(CResource* res)
|
| {
|
| if(!res || res->Name.empty()) { COMPONENT_CALL(CLogger, Err(L"Tried to stop invalid resource (null/empty name)\n")); return; }
|
| auto it = std::find_if(Resources.begin(), Resources.end(), [&res](auto& kv) -> bool
|
| {
|
| return kv.second.lock().get() == res && kv.first.second == res->Name && kv.first.first == res->GetType();
|
| });
|
|
|
| if(it != Resources.end())
|
| {
|
| auto ptr = it->second.lock();
|
| if(ptr)
|
| {
|
| Log::Instance() << "Stopped resource " << ptr->Name << "\n";
|
| }
|
|
|
| Resources.erase(it);
|
| }
|
| }
|
|
|
| void CResourcesManager::V_Update()
|
| {
|
| Cache.RemoveExpired();
|
| for(auto& _res : Resources)
|
| {
|
| if(_res.second.expired()) { continue; }
|
|
|
| auto res = _res.second.lock();
|
| if(res->LoadingStatus != CResource::CLoadingStatus::None && res->LoadingStatus != CResource::CLoadingStatus::Done)
|
| {
|
| res->ProcessPipeline();
|
| }
|
| }
|
| }
|
|
|
| std::shared_ptr<CResource> CResourcesManager::GetOrCreate(const std::string& type, const std::string& path, bool startPipeline)
|
| {
|
| std::lock_guard _lock(RetrieveMutex);
|
|
|
| std::shared_ptr<CResource> res;
|
| bool okget = false;
|
|
|
| std::filesystem::path pp(path);
|
| try
|
| {
|
| res = GetResource(type, pp.stem().string());
|
|
|
| if(res && res->GetType() == type)
|
| {
|
| okget = true;
|
| }
|
| }
|
| catch(...) {}
|
|
|
| if(okget)
|
| {
|
| return res;
|
| }
|
|
|
| res = CEngine::GetInstance()->ResourcesFactory.create(type);
|
| if(!res) { return nullptr; }
|
|
|
| res->Name = pp.stem().string();
|
| RegisterResource(res);
|
|
|
| if(startPipeline)
|
| {
|
| res->StartPipeline(pp);
|
| }
|
| return res;
|
| }
|
|
|
| std::shared_ptr<CResource> CResourcesManager::LoadResource(const std::string& type, const std::string& path)
|
| {
|
| std::lock_guard _lock(RetrieveMutex);
|
|
|
| std::shared_ptr<CResource> res;
|
| bool okget = false;
|
|
|
| std::filesystem::path pp(path);
|
| try
|
| {
|
| res = GetResource(type, pp.stem().string());
|
|
|
| if(res && res->GetType() == type)
|
| {
|
| okget = true;
|
| }
|
| }
|
| catch(...) {}
|
|
|
| if(okget)
|
| {
|
| return res;
|
| }
|
| res = CEngine::GetInstance()->ResourcesFactory.create(type);
|
| //if(!res) { throw std::runtime_error("No resources with such type: " + type); }
|
| if(!res) { return nullptr; }
|
|
|
| bool ok = res->Load(path);
|
|
|
| //if(!ok) { throw std::runtime_error("Can't load resource at \"" + path + "\" with type " + type); }
|
| if(!ok)
|
| {
|
| StopResource(res.get());
|
| return nullptr;
|
| }
|
| return res;
|
| }
|
|
|
| bool CResourcesManager::IsResourceExist(const std::string& type, const std::string& name)
|
| {
|
| return std::find_if(Resources.begin(), Resources.end(), [&type, &name](auto& kv) -> bool
|
| {
|
| return kv.first.second == name && kv.first.first == type;
|
| }) != Resources.end();
|
| }
|
|
|
| std::shared_ptr<CResource> CResourcesManager::GetResource(const std::string& type, const std::string& name)
|
| {
|
| //Log::Instance() << "Trying to GetResource \"" << name << "\"\n"; LOGLOG
|
| auto it = std::find_if(Resources.begin(), Resources.end(), [&type, &name](auto& kv) -> bool
|
| {
|
| return kv.first.second == name && kv.first.first == type;
|
| });
|
|
|
| //if(it == Resources.end()) { throw std::runtime_error("No such named resource"); }
|
| if(it == Resources.end()) { return nullptr; }
|
|
|
| auto shared = it->second.lock();
|
| if (!shared)
|
| {
|
| //Log::Instance() << "Resource " << name << " expired, removing from manager\n"; LOGLOG
|
| Resources.erase(it);
|
| return nullptr;
|
| }
|
| //Log::Instance() << "Returned existing\n"; LOGLOG
|
| return shared;
|
| }
|
|
|
| bool CResourcesManager::V_ScriptInit(std::shared_ptr<sol::state> state, sol::table table)
|
| {
|
| table.set_function("registerNew", InvokeRegisterFunction<CResource, "resource">); //generic or resource
|
| return true;
|
| }
|
|
|
| LINK_SOL_USERTYPE(CResourcesManager);
|
| LINK_COMPONENT_TO_CLASS(CResourcesManager, resourcesmanager); |