From 8346f565955544ffd0dc7a2d92514bd9b6b21592 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Thu, 26 Oct 2017 00:09:51 -1000 Subject: [PATCH] Finish CResFactory; better smart-pointer use for resources --- Editor/ProjectManager.cpp | 59 ++++++++------ Editor/ProjectManager.hpp | 1 - Editor/ProjectResourceFactoryBase.cpp | 8 +- Editor/ProjectResourceFactoryBase.hpp | 8 +- Editor/ViewManager.cpp | 3 +- Runtime/CPakFile.hpp | 1 + Runtime/CResFactory.cpp | 101 ++++++++++++++++++++++-- Runtime/CResFactory.hpp | 59 +++++++++++--- Runtime/CResLoader.cpp | 57 ++++++++++++- Runtime/CResLoader.hpp | 5 ++ Runtime/CToken.cpp | 13 ++- Runtime/CToken.hpp | 4 +- Runtime/Character/CAssetFactory.cpp | 4 +- Runtime/Character/CAssetFactory.hpp | 2 +- Runtime/Character/CCharacterFactory.cpp | 4 +- Runtime/Character/CCharacterFactory.hpp | 2 +- Runtime/IFactory.hpp | 5 +- Runtime/MP1/MP1.cpp | 3 +- Runtime/MP1/MP1.hpp | 29 +++++-- Runtime/MP1/MP1OriginalIDs.cpp | 4 +- 20 files changed, 288 insertions(+), 84 deletions(-) diff --git a/Editor/ProjectManager.cpp b/Editor/ProjectManager.cpp index 74a9ead6f..8517e30d0 100644 --- a/Editor/ProjectManager.cpp +++ b/Editor/ProjectManager.cpp @@ -81,7 +81,8 @@ bool ProjectManager::newProject(const hecl::SystemString& path) bool ProjectManager::openProject(const hecl::SystemString& path) { - hecl::ProjectRootPath projPath = hecl::SearchForProject(path); + hecl::SystemString subPath; + hecl::ProjectRootPath projPath = hecl::SearchForProject(path, subPath); if (!projPath) { Log.report(logvisor::Warning, _S("project doesn't exist at '%s'"), path.c_str()); @@ -129,30 +130,43 @@ makeProj: else m_vm.SetupEditorView(); - m_factoryMP1.IndexMP1Resources(*m_proj, m_objStore); - m_mainMP1.emplace(m_factoryMP1, m_objStore, m_vm.m_mainBooFactory, - m_vm.m_mainCommandQueue, m_vm.m_renderTex); + bool runFromPaks = hecl::StringUtils::BeginsWith(subPath, _S("out")); + if (runFromPaks) + { + m_mainMP1.emplace(nullptr, nullptr, m_vm.m_mainBooFactory, + m_vm.m_mainCommandQueue, m_vm.m_renderTex); + } + else + { + m_factoryMP1.IndexMP1Resources(*m_proj, m_objStore); + m_mainMP1.emplace(&m_factoryMP1, &m_objStore, m_vm.m_mainBooFactory, + m_vm.m_mainCommandQueue, m_vm.m_renderTex); + } + m_vm.InitMP1(*m_mainMP1); // precook - m_precooking = true; - std::vector nonMlvls; - std::vector mlvls; - mlvls.reserve(8); - m_factoryMP1.EnumerateResources([this, &nonMlvls, &mlvls](const SObjectTag& tag) + if (!runFromPaks) { - if (tag.type == FOURCC('CMDL') || tag.type == FOURCC('MREA')) + m_precooking = true; + std::vector nonMlvls; + std::vector mlvls; + mlvls.reserve(8); + m_factoryMP1.EnumerateResources([this, &nonMlvls, &mlvls](const SObjectTag& tag) + { + if (tag.type == FOURCC('CMDL') || tag.type == FOURCC('MREA')) + m_factoryMP1.CookResourceAsync(tag); + else if (tag.type != FOURCC('MLVL')) + nonMlvls.push_back(tag); + else // (tag.type == FOURCC('MLVL')) + mlvls.push_back(tag); + return true; + }); + for (const SObjectTag& tag : nonMlvls) m_factoryMP1.CookResourceAsync(tag); - else if (tag.type != FOURCC('MLVL')) - nonMlvls.push_back(tag); - else // (tag.type == FOURCC('MLVL')) - mlvls.push_back(tag); - return true; - }); - for (const SObjectTag& tag : nonMlvls) - m_factoryMP1.CookResourceAsync(tag); - for (const SObjectTag& tag : mlvls) - m_factoryMP1.CookResourceAsync(tag); + for (const SObjectTag& tag : mlvls) + m_factoryMP1.CookResourceAsync(tag); + } if (needsSave) saveProject(); @@ -228,11 +242,6 @@ void ProjectManager::mainDraw() m_mainMP1->Draw(); } -void ProjectManager::asyncIdle() -{ - m_factoryMP1.AsyncIdle(); -} - void ProjectManager::shutdown() { if (m_mainMP1) diff --git a/Editor/ProjectManager.hpp b/Editor/ProjectManager.hpp index 37ffed62f..1e3c28488 100644 --- a/Editor/ProjectManager.hpp +++ b/Editor/ProjectManager.hpp @@ -55,7 +55,6 @@ public: void mainUpdate(); void mainDraw(); - void asyncIdle(); void shutdown(); }; diff --git a/Editor/ProjectResourceFactoryBase.cpp b/Editor/ProjectResourceFactoryBase.cpp index 211136dbb..d5c7b6a9b 100644 --- a/Editor/ProjectResourceFactoryBase.cpp +++ b/Editor/ProjectResourceFactoryBase.cpp @@ -299,7 +299,7 @@ std::unique_ptr ProjectResourceFactoryBase::Build(const urde::SObjec newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, selfRef); } - *task.xc_targetObjPtr = newObj.get(); + //*task.xc_targetObjPtr = newObj.get(); Log.report(logvisor::Warning, "spin-built %.4s %08X", task.x0_tag.type.toString().c_str(), u32(task.x0_tag.id.Value())); @@ -328,7 +328,7 @@ std::unique_ptr ProjectResourceFactoryBase::Build(const urde::SObjec std::shared_ptr ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag, const urde::CVParamTransfer& paramXfer, - urde::IObj** objOut, + std::unique_ptr* objOut, CObjectReference* selfRef) { if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end()) @@ -338,7 +338,7 @@ ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag, void ProjectResourceFactoryBase::BuildAsync(const urde::SObjectTag& tag, const urde::CVParamTransfer& paramXfer, - urde::IObj** objOut, + std::unique_ptr* objOut, CObjectReference* selfRef) { if (!tag.id.IsValid()) @@ -528,7 +528,7 @@ bool ProjectResourceFactoryBase::AsyncPumpTask(ItType& it) newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, task.m_selfRef); } - *task.xc_targetObjPtr = newObj.release(); + *task.xc_targetObjPtr = std::move(newObj); Log.report(logvisor::Info, "async-built %.4s %08X", task.x0_tag.type.toString().c_str(), u32(task.x0_tag.id.Value())); diff --git a/Editor/ProjectResourceFactoryBase.hpp b/Editor/ProjectResourceFactoryBase.hpp index 4ee75ab56..320043dd6 100644 --- a/Editor/ProjectResourceFactoryBase.hpp +++ b/Editor/ProjectResourceFactoryBase.hpp @@ -29,7 +29,7 @@ public: //IDvdRequest* x8_dvdReq = nullptr; std::unique_ptr* xc_targetDataPtr = nullptr; u8* xc_targetDataRawPtr = nullptr; - IObj** xc_targetObjPtr = nullptr; + std::unique_ptr* xc_targetObjPtr = nullptr; std::unique_ptr x10_loadBuffer; u32 x14_resSize = UINT32_MAX; u32 x14_resOffset = 0; @@ -58,7 +58,7 @@ public: x14_resOffset(off) {} AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag, - IObj** ptr, const CVParamTransfer& xfer, CObjectReference* selfRef) + std::unique_ptr* ptr, const CVParamTransfer& xfer, CObjectReference* selfRef) : m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer), m_selfRef(selfRef) {} /* Cook only */ @@ -135,12 +135,12 @@ protected: bool SyncCook(const hecl::ProjectPath& working); CFactoryFnReturn BuildSync(const SObjectTag& tag, const hecl::ProjectPath& path, const CVParamTransfer& paramXfer, CObjectReference* selfRef); + std::shared_ptr BuildAsyncInternal(const urde::SObjectTag&, const urde::CVParamTransfer&, std::unique_ptr*, CObjectReference* selfRef); public: ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {} std::unique_ptr Build(const urde::SObjectTag&, const urde::CVParamTransfer&, CObjectReference* selfRef); - void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**, CObjectReference* selfRef); - std::shared_ptr BuildAsyncInternal(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**, CObjectReference* selfRef); + void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, std::unique_ptr*, CObjectReference* selfRef); void CancelBuild(const urde::SObjectTag&); bool CanBuild(const urde::SObjectTag&); const urde::SObjectTag* GetResourceIdByName(const char*) const; diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index fa93ceba9..fb327bb5c 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -279,7 +279,8 @@ bool ViewManager::proc() if (g_Renderer) g_Renderer->EndScene(); gfxQ->execute(); - m_projManager.asyncIdle(); + if (g_ResFactory) + g_ResFactory->AsyncIdle(); m_mainWindow->waitForRetrace(m_voiceEngine.get()); CBooModel::ClearModelUniformCounters(); CGraphics::TickRenderTimings(); diff --git a/Runtime/CPakFile.hpp b/Runtime/CPakFile.hpp index 6657aaf37..9715226de 100644 --- a/Runtime/CPakFile.hpp +++ b/Runtime/CPakFile.hpp @@ -70,6 +70,7 @@ private: void Warmup(); public: CPakFile(const std::string& filename, bool buildDepList, bool worldPak); + const std::vector>& GetNameList() const { return x54_nameList; } const std::vector& GetDepList() const { return x64_depList; } const SObjectTag* GetResIdByName(const char* name) const; const SResInfo* GetResInfoForLoadPreferForward(CAssetId id) const; diff --git a/Runtime/CResFactory.cpp b/Runtime/CResFactory.cpp index 54f4e6995..2d0c62c89 100644 --- a/Runtime/CResFactory.cpp +++ b/Runtime/CResFactory.cpp @@ -1,18 +1,109 @@ #include "CResFactory.hpp" -#include "IObj.hpp" +#include "CSimplePool.hpp" namespace urde { -std::unique_ptr CResFactory::Build(const SObjectTag&, const CVParamTransfer&) +void CResFactory::AddToLoadList(SLoadingData&& data) { - return std::unique_ptr(); + m_loadMap[data.x0_tag] = m_loadList.insert(m_loadList.end(), std::move(data)); } -void CResFactory::BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**) + +CFactoryFnReturn CResFactory::BuildSync(const SObjectTag& tag, const CVParamTransfer& xfer, CObjectReference* selfRef) { + if (x5c_factoryMgr.CanMakeMemory(tag)) + { + std::unique_ptr data; + int size; + x4_loader.LoadMemResourceSync(tag, data, &size); + return x5c_factoryMgr.MakeObjectFromMemory(tag, std::move(data), size, + x4_loader.GetResourceCompression(tag), xfer, selfRef); + } + else + { + auto rp = x4_loader.LoadNewResourceSync(tag, nullptr); + return x5c_factoryMgr.MakeObject(tag, *rp, xfer, selfRef); + } } -void CResFactory::CancelBuild(const SObjectTag&) + +bool CResFactory::PumpResource(SLoadingData& data) { + if (data.x8_dvdReq->IsComplete()) + { + *data.xc_targetPtr = + x5c_factoryMgr.MakeObjectFromMemory(data.x0_tag, std::move(data.x10_loadBuffer), + data.x14_resSize, data.m_compressed, data.x18_cvXfer, + data.m_selfRef); + return true; + } + return false; +} + +std::unique_ptr CResFactory::Build(const SObjectTag& tag, const CVParamTransfer& xfer, CObjectReference* selfRef) +{ + auto search = m_loadMap.find(tag); + if (search != m_loadMap.end()) + { + while (!PumpResource(*search->second) || !search->second->xc_targetPtr) {} + m_loadList.erase(search->second); + m_loadMap.erase(search); + return std::move(*search->second->xc_targetPtr); + } + return BuildSync(tag, xfer, selfRef); +} + +void CResFactory::BuildAsync(const SObjectTag& tag, const CVParamTransfer& xfer, std::unique_ptr* target, + CObjectReference* selfRef) +{ + auto search = m_loadMap.find(tag); + if (search != m_loadMap.end()) + { + SLoadingData data(tag, target, xfer, x4_loader.GetResourceCompression(tag), selfRef); + data.x10_loadBuffer = std::unique_ptr(new u8[x4_loader.ResourceSize(tag)]); + x4_loader.LoadResourceAsync(tag, data.x10_loadBuffer.get()); + AddToLoadList(std::move(data)); + } +} + +void CResFactory::AsyncIdle() +{ + auto startTime = std::chrono::steady_clock::now(); + while (std::chrono::duration_cast( + std::chrono::steady_clock::now() - startTime).count() < 2) + { + auto& task = m_loadList.front(); + if (PumpResource(task)) + { + m_loadMap.erase(task.x0_tag); + m_loadList.pop_front(); + } + } +} + +void CResFactory::CancelBuild(const SObjectTag& tag) +{ + auto search = m_loadMap.find(tag); + if (search != m_loadMap.end()) + { + search->second->x8_dvdReq->PostCancelRequest(); + m_loadList.erase(search->second); + m_loadMap.erase(search); + } +} + +void CResFactory::LoadOriginalIDs(CSimplePool& sp) +{ + m_origIds = sp.GetObj("MP1OriginalIDs"); +} + +CAssetId CResFactory::TranslateOriginalToNew(CAssetId id) const +{ + return m_origIds->TranslateOriginalToNew(id); +} + +CAssetId CResFactory::TranslateNewToOriginal(CAssetId id) const +{ + return m_origIds->TranslateNewToOriginal(id); } } diff --git a/Runtime/CResFactory.hpp b/Runtime/CResFactory.hpp index ba1913930..165a07d65 100644 --- a/Runtime/CResFactory.hpp +++ b/Runtime/CResFactory.hpp @@ -5,35 +5,48 @@ #include "IFactory.hpp" #include "CResLoader.hpp" #include "IVParamObj.hpp" +#include "MP1/MP1OriginalIDs.hpp" +#include "CToken.hpp" namespace urde { class IDvdRequest; +class CSimplePool; class CResFactory : public IFactory { CResLoader x4_loader; + CFactoryMgr x5c_factoryMgr; + TLockedToken m_origIds; + public: struct SLoadingData { SObjectTag x0_tag; - IDvdRequest* x8_dvdReq = nullptr; - IObj** xc_targetPtr = nullptr; - void* x10_loadBuffer = nullptr; + std::shared_ptr x8_dvdReq; + std::unique_ptr* xc_targetPtr = nullptr; + std::unique_ptr x10_loadBuffer; u32 x14_resSize = 0; CVParamTransfer x18_cvXfer; + bool m_compressed = false; + CObjectReference* m_selfRef = nullptr; SLoadingData() = default; - SLoadingData(const SObjectTag& tag, IObj** ptr, const CVParamTransfer& xfer) - : x0_tag(tag), xc_targetPtr(ptr), x18_cvXfer(xfer) {} + SLoadingData(const SObjectTag& tag, std::unique_ptr* ptr, const CVParamTransfer& xfer, + bool compressed, CObjectReference* selfRef) + : x0_tag(tag), xc_targetPtr(ptr), x18_cvXfer(xfer), m_compressed(compressed), m_selfRef(selfRef) {} }; private: - std::unordered_map m_loadList; - void AddToLoadList(const SLoadingData& data) {m_loadList[data.x0_tag] = data;} + std::list m_loadList; + std::unordered_map::iterator> m_loadMap; + void AddToLoadList(SLoadingData&& data); + CFactoryFnReturn BuildSync(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef); + bool PumpResource(SLoadingData& data); public: CResLoader& GetLoader() {return x4_loader;} - std::unique_ptr Build(const SObjectTag&, const CVParamTransfer&); - void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**); + std::unique_ptr Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef); + void BuildAsync(const SObjectTag&, const CVParamTransfer&, std::unique_ptr*, CObjectReference* selfRef); + void AsyncIdle(); void CancelBuild(const SObjectTag&); bool CanBuild(const SObjectTag& tag) @@ -41,6 +54,21 @@ public: return x4_loader.ResourceExists(tag); } + u32 ResourceSize(const urde::SObjectTag& tag) + { + return x4_loader.ResourceSize(tag); + } + + std::unique_ptr LoadResourceSync(const urde::SObjectTag& tag) + { + return x4_loader.LoadResourceSync(tag); + } + + std::unique_ptr LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off) + { + return x4_loader.LoadResourcePartSync(tag, size, off); + } + const SObjectTag* GetResourceIdByName(const char* name) const { return x4_loader.GetResourceIdByName(name); @@ -53,17 +81,22 @@ public: std::vector> GetResourceIdToNameList() const { - std::vector> retval; - return retval; + return x4_loader.GetResourceIdToNameList(); } - void EnumerateResources(std::function lambda) const + void EnumerateResources(const std::function& lambda) const { + return x4_loader.EnumerateResources(lambda); } - void EnumerateNamedResources(std::function lambda) const + void EnumerateNamedResources(const std::function& lambda) const { + return x4_loader.EnumerateNamedResources(lambda); } + + void LoadOriginalIDs(CSimplePool& sp); + CAssetId TranslateOriginalToNew(CAssetId id) const; + CAssetId TranslateNewToOriginal(CAssetId id) const; }; } diff --git a/Runtime/CResLoader.cpp b/Runtime/CResLoader.cpp index 2c2505b3e..b3b5240bb 100644 --- a/Runtime/CResLoader.cpp +++ b/Runtime/CResLoader.cpp @@ -11,7 +11,7 @@ CResLoader::CResLoader() const std::vector* CResLoader::GetTagListForFile(const std::string& name) const { - std::string namePak = name + ".pak"; + std::string namePak = name + ".upak"; for (const std::unique_ptr& pak : x18_pakLoadedList) if (!CStringExtras::CompareCaseInsensitive(namePak, pak->x18_path)) return &pak->GetDepList(); @@ -20,7 +20,7 @@ const std::vector* CResLoader::GetTagListForFile(const std::string& na void CResLoader::AddPakFileAsync(const std::string& name, bool samusPak, bool worldPak) { - std::string namePak = name + ".pak"; + std::string namePak = name + ".upak"; if (CDvdFile::FileExists(namePak.c_str())) { x30_pakLoadingList.emplace_back(new CPakFile(namePak, samusPak, worldPak)); @@ -95,6 +95,23 @@ std::shared_ptr CResLoader::LoadResourceAsync(const SObjectTag& tag ESeekOrigin::Begin, x50_cachedResInfo->GetOffset()); } +std::unique_ptr CResLoader::LoadResourceSync(const urde::SObjectTag& tag) +{ + CPakFile* file = FindResourceForLoad(tag.id); + u32 size = ROUND_UP_32(x50_cachedResInfo->GetSize()); + std::unique_ptr ret(new u8[size]); + file->SyncSeekRead(ret.get(), size, ESeekOrigin::Begin, x50_cachedResInfo->GetOffset()); + return ret; +} + +std::unique_ptr CResLoader::LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off) +{ + CPakFile* file = FindResourceForLoad(tag.id); + std::unique_ptr ret(new u8[size]); + file->SyncSeekRead(ret.get(), size, ESeekOrigin::Begin, x50_cachedResInfo->GetOffset() + off); + return ret; +} + bool CResLoader::GetResourceCompression(const SObjectTag& tag) { if (FindResource(tag.id)) @@ -118,7 +135,7 @@ FourCC CResLoader::GetResourceTypeById(CAssetId id) const { if (FindResource(id)) return x50_cachedResInfo->GetType(); - return FourCC(); + return {}; } const SObjectTag* CResLoader::GetResourceIdByName(const char* name) const @@ -236,4 +253,38 @@ void CResLoader::MoveToCorrectLoadedList(std::unique_ptr&& file) x18_pakLoadedList.push_back(std::move(file)); } +std::vector> CResLoader::GetResourceIdToNameList() const +{ + std::vector> ret; + for (auto it = x18_pakLoadedList.begin() ; it != x18_pakLoadedList.end() ; ++it) + for (const auto& name : (*it)->GetNameList()) + ret.push_back(name); + return ret; +} + +void CResLoader::EnumerateResources(const std::function& lambda) const +{ + for (auto it = x18_pakLoadedList.begin() ; it != x18_pakLoadedList.end() ; ++it) + { + for (const CAssetId& id : (*it)->GetDepList()) + { + SObjectTag fcc(GetResourceTypeById(id), id); + if (!lambda(fcc)) + return; + } + } +} + +void CResLoader::EnumerateNamedResources(const std::function& lambda) const +{ + for (auto it = x18_pakLoadedList.begin() ; it != x18_pakLoadedList.end() ; ++it) + { + for (const auto& name : (*it)->GetNameList()) + { + if (!lambda(name.first, name.second)) + return; + } + } +} + } diff --git a/Runtime/CResLoader.hpp b/Runtime/CResLoader.hpp index a05057bb1..087f4b663 100644 --- a/Runtime/CResLoader.hpp +++ b/Runtime/CResLoader.hpp @@ -34,6 +34,8 @@ public: std::unique_ptr LoadNewResourceSync(const SObjectTag& tag, void* extBuf=nullptr); std::shared_ptr LoadResourcePartAsync(const SObjectTag& tag, int offset, int length, void* buf); std::shared_ptr LoadResourceAsync(const SObjectTag& tag, void* buf); + std::unique_ptr LoadResourceSync(const urde::SObjectTag& tag); + std::unique_ptr LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off); bool GetResourceCompression(const SObjectTag& tag); u32 ResourceSize(const SObjectTag& tag); bool ResourceExists(const SObjectTag& tag); @@ -47,6 +49,9 @@ public: bool CacheFromPakForLoad(CPakFile& file, CAssetId id); bool CacheFromPak(const CPakFile& file, CAssetId id) const; void MoveToCorrectLoadedList(std::unique_ptr&& file); + std::vector> GetResourceIdToNameList() const; + void EnumerateResources(const std::function& lambda) const; + void EnumerateNamedResources(const std::function& lambda) const; }; } diff --git a/Runtime/CToken.cpp b/Runtime/CToken.cpp index f32696fbf..fa4e8c65b 100644 --- a/Runtime/CToken.cpp +++ b/Runtime/CToken.cpp @@ -20,9 +20,9 @@ u16 CObjectReference::RemoveReference() CObjectReference::CObjectReference(IObjectStore& objStore, std::unique_ptr&& obj, const SObjectTag& objTag, CVParamTransfer buildParams) : x4_objTag(objTag), xC_objectStore(&objStore), - x10_object(obj.release()), x14_params(buildParams) {} + x10_object(std::move(obj)), x14_params(buildParams) {} CObjectReference::CObjectReference(std::unique_ptr&& obj) -: x10_object(obj.release()) {} +: x10_object(std::move(obj)) {} void CObjectReference::Unlock() { @@ -57,8 +57,7 @@ void CObjectReference::CancelLoad() void CObjectReference::Unload() { - std::default_delete()(x10_object); - x10_object = nullptr; + x10_object.reset(); x3_loading = false; } @@ -67,16 +66,16 @@ IObj* CObjectReference::GetObject() if (!x10_object) { IFactory& factory = xC_objectStore->GetFactory(); - x10_object = factory.Build(x4_objTag, x14_params, this).release(); + x10_object = factory.Build(x4_objTag, x14_params, this); } x3_loading = false; - return x10_object; + return x10_object.get(); } CObjectReference::~CObjectReference() { if (x10_object) - std::default_delete()(x10_object); + x10_object.reset(); else if (x3_loading) xC_objectStore->GetFactory().CancelBuild(x4_objTag); } diff --git a/Runtime/CToken.hpp b/Runtime/CToken.hpp index 5a52d37bf..9f7020544 100644 --- a/Runtime/CToken.hpp +++ b/Runtime/CToken.hpp @@ -22,7 +22,7 @@ class CObjectReference bool x3_loading = false; /* Rightmost bit of lockCount */ SObjectTag x4_objTag; IObjectStore* xC_objectStore = nullptr; - IObj* x10_object = nullptr; + std::unique_ptr x10_object; CVParamTransfer x14_params; /** Mechanism by which CToken decrements 1st ref-count, indicating CToken invalidation or reset. @@ -37,7 +37,7 @@ class CObjectReference bool IsLoading() const {return x3_loading;} /** Indicates an asynchronous load transaction has finished and object is completely loaded */ - bool IsLoaded() const {return x10_object != nullptr;} + bool IsLoaded() const {return x10_object.operator bool();} /** Decrements 2nd ref-count, performing unload or async-load-cancel if 0 reached */ void Unlock(); diff --git a/Runtime/Character/CAssetFactory.cpp b/Runtime/Character/CAssetFactory.cpp index 8f1d61dc4..f26f18e02 100644 --- a/Runtime/Character/CAssetFactory.cpp +++ b/Runtime/Character/CAssetFactory.cpp @@ -20,10 +20,10 @@ CFactoryFnReturn CCharacterFactoryBuilder::CDummyFactory::Build(const SObjectTag void CCharacterFactoryBuilder::CDummyFactory::BuildAsync(const SObjectTag& tag, const CVParamTransfer& parms, - IObj** objOut, + std::unique_ptr* objOut, CObjectReference* selfRef) { - *objOut = Build(tag, parms, selfRef).release(); + *objOut = Build(tag, parms, selfRef); } void CCharacterFactoryBuilder::CDummyFactory::CancelBuild(const SObjectTag&) diff --git a/Runtime/Character/CAssetFactory.hpp b/Runtime/Character/CAssetFactory.hpp index 33de79ad2..6d4c9952d 100644 --- a/Runtime/Character/CAssetFactory.hpp +++ b/Runtime/Character/CAssetFactory.hpp @@ -18,7 +18,7 @@ public: { public: CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef); - void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**, CObjectReference* selfRef); + void BuildAsync(const SObjectTag&, const CVParamTransfer&, std::unique_ptr*, CObjectReference* selfRef); void CancelBuild(const SObjectTag&); bool CanBuild(const SObjectTag&); const SObjectTag* GetResourceIdByName(const char*) const; diff --git a/Runtime/Character/CCharacterFactory.cpp b/Runtime/Character/CCharacterFactory.cpp index dbee90731..3a3c3bf17 100644 --- a/Runtime/Character/CCharacterFactory.cpp +++ b/Runtime/Character/CCharacterFactory.cpp @@ -49,10 +49,10 @@ CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag, void CCharacterFactory::CDummyFactory::BuildAsync(const SObjectTag& tag, const CVParamTransfer& parms, - IObj** objOut, + std::unique_ptr* objOut, CObjectReference* selfRef) { - *objOut = Build(tag, parms, selfRef).release(); + *objOut = Build(tag, parms, selfRef); } void CCharacterFactory::CDummyFactory::CancelBuild(const SObjectTag&) diff --git a/Runtime/Character/CCharacterFactory.hpp b/Runtime/Character/CCharacterFactory.hpp index aa2e912a0..4387c81a5 100644 --- a/Runtime/Character/CCharacterFactory.hpp +++ b/Runtime/Character/CCharacterFactory.hpp @@ -27,7 +27,7 @@ public: { public: CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef); - void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**, CObjectReference* selfRef); + void BuildAsync(const SObjectTag&, const CVParamTransfer&, std::unique_ptr*, CObjectReference* selfRef); void CancelBuild(const SObjectTag&); bool CanBuild(const SObjectTag&); const SObjectTag* GetResourceIdByName(const char*) const; diff --git a/Runtime/IFactory.hpp b/Runtime/IFactory.hpp index a5722637c..10ffcab48 100644 --- a/Runtime/IFactory.hpp +++ b/Runtime/IFactory.hpp @@ -12,6 +12,7 @@ class IObj; class CObjectReference; class CResLoader; class CFactoryMgr; +class CSimplePool; using CFactoryFnReturn = std::unique_ptr; using FFactoryFunc = std::function*, CObjectReference*)=0; virtual void CancelBuild(const SObjectTag&)=0; virtual bool CanBuild(const SObjectTag&)=0; virtual const SObjectTag* GetResourceIdByName(const char*) const=0; @@ -37,6 +38,8 @@ public: virtual void EnumerateNamedResources(const std::function& lambda) const=0; virtual CResLoader* GetResLoader() const { return nullptr; } virtual CFactoryMgr* GetFactoryMgr() const { return nullptr; } + virtual void LoadOriginalIDs(CSimplePool& sp) {} + virtual void AsyncIdle() {} /* Non-factory versions, replaces CResLoader */ virtual u32 ResourceSize(const urde::SObjectTag& tag)=0; diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index aa3ff4535..b07f17036 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -239,7 +239,7 @@ CGameArchitectureSupport::~CGameArchitectureSupport() CStreamAudioManager::Shutdown(); } -CMain::CMain(IFactory& resFactory, CSimplePool& resStore, +CMain::CMain(IFactory* resFactory, CSimplePool* resStore, boo::IGraphicsDataFactory* gfxFactory, boo::IGraphicsCommandQueue* cmdQ, boo::ITextureR* spareTex) @@ -339,7 +339,6 @@ void CMain::AddWorldPaks() std::string path = pakPrefix; if (i != 0) path += '0' + i; - path += ".upak"; if (CDvdFile::FileExists(path.c_str())) if (CResLoader* loader = g_ResFactory->GetResLoader()) loader->AddPakFileAsync(path, false, true); diff --git a/Runtime/MP1/MP1.hpp b/Runtime/MP1/MP1.hpp index 0bd9be496..8e82737c0 100644 --- a/Runtime/MP1/MP1.hpp +++ b/Runtime/MP1/MP1.hpp @@ -52,8 +52,10 @@ class CGameGlobalObjects friend class CMain; std::unique_ptr x0_memoryCardSys; - IFactory& x4_resFactory; - CSimplePool& xcc_simplePool; + std::unique_ptr x4_gameResFactory; + IFactory* x4_resFactory; + std::unique_ptr x4_gameSimplePool; + CSimplePool* xcc_simplePool; CCharacterFactoryBuilder xec_charFactoryBuilder; CAiFuncMap x110_aiFuncMap; std::unique_ptr x134_gameState; @@ -75,12 +77,22 @@ class CGameGlobalObjects } public: - CGameGlobalObjects(IFactory& resFactory, - CSimplePool& objStore) + CGameGlobalObjects(IFactory* resFactory, + CSimplePool* objStore) : x4_resFactory(resFactory), xcc_simplePool(objStore) { - g_ResFactory = &x4_resFactory; - g_SimplePool = &xcc_simplePool; + if (!x4_resFactory) + { + x4_gameResFactory.reset(new CResFactory()); + x4_resFactory = x4_gameResFactory.get(); + } + if (!xcc_simplePool) + { + x4_gameSimplePool.reset(new CSimplePool(*x4_resFactory)); + xcc_simplePool = x4_gameSimplePool.get(); + } + g_ResFactory = x4_resFactory; + g_SimplePool = xcc_simplePool; g_CharFactoryBuilder = &xec_charFactoryBuilder; g_AiFuncMap = &x110_aiFuncMap; x134_gameState.reset(new CGameState()); @@ -91,8 +103,9 @@ public: void PostInitialize() { AddPaksAndFactories(); + x4_resFactory->LoadOriginalIDs(*xcc_simplePool); LoadStringTable(); - m_renderer.reset(AllocateRenderer(xcc_simplePool, x4_resFactory)); + m_renderer.reset(AllocateRenderer(*xcc_simplePool, *x4_resFactory)); CScriptMazeNode::LoadMazeSeeds(); } @@ -250,7 +263,7 @@ private: void InitializeSubsystems(const hecl::Runtime::FileStoreManager& storeMgr); public: - CMain(IFactory& resFactory, CSimplePool& resStore, + CMain(IFactory* resFactory, CSimplePool* resStore, boo::IGraphicsDataFactory* gfxFactory, boo::IGraphicsCommandQueue* cmdQ, boo::ITextureR* spareTex); diff --git a/Runtime/MP1/MP1OriginalIDs.cpp b/Runtime/MP1/MP1OriginalIDs.cpp index 8300af688..0ef1dfdc8 100644 --- a/Runtime/MP1/MP1OriginalIDs.cpp +++ b/Runtime/MP1/MP1OriginalIDs.cpp @@ -28,7 +28,7 @@ CAssetId MP1OriginalIDs::TranslateOriginalToNew(CAssetId id) const auto search = rstl::binary_find(m_origToNew.cbegin(), m_origToNew.cend(), id, [](const auto& id) { return id.first; }); if (search == m_origToNew.cend()) - return -1; + return {}; return search->second; } @@ -37,7 +37,7 @@ CAssetId MP1OriginalIDs::TranslateNewToOriginal(CAssetId id) const auto search = rstl::binary_find(m_newToOrig.cbegin(), m_newToOrig.cend(), id, [](const auto& id) { return id.first; }); if (search == m_newToOrig.cend()) - return -1; + return {}; return search->second; }