2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-08-09 12:59:06 +00:00

Finish CResFactory; better smart-pointer use for resources

This commit is contained in:
Jack Andersen 2017-10-26 00:09:51 -10:00
parent 7c3fb4174f
commit 8346f56595
20 changed files with 288 additions and 84 deletions

View File

@ -81,7 +81,8 @@ bool ProjectManager::newProject(const hecl::SystemString& path)
bool ProjectManager::openProject(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) if (!projPath)
{ {
Log.report(logvisor::Warning, _S("project doesn't exist at '%s'"), path.c_str()); Log.report(logvisor::Warning, _S("project doesn't exist at '%s'"), path.c_str());
@ -129,30 +130,43 @@ makeProj:
else else
m_vm.SetupEditorView(); m_vm.SetupEditorView();
m_factoryMP1.IndexMP1Resources(*m_proj, m_objStore); bool runFromPaks = hecl::StringUtils::BeginsWith(subPath, _S("out"));
m_mainMP1.emplace(m_factoryMP1, m_objStore, m_vm.m_mainBooFactory, if (runFromPaks)
m_vm.m_mainCommandQueue, m_vm.m_renderTex); {
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); m_vm.InitMP1(*m_mainMP1);
// precook // precook
m_precooking = true; if (!runFromPaks)
std::vector<SObjectTag> nonMlvls;
std::vector<SObjectTag> mlvls;
mlvls.reserve(8);
m_factoryMP1.EnumerateResources([this, &nonMlvls, &mlvls](const SObjectTag& tag)
{ {
if (tag.type == FOURCC('CMDL') || tag.type == FOURCC('MREA')) m_precooking = true;
std::vector<SObjectTag> nonMlvls;
std::vector<SObjectTag> 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); m_factoryMP1.CookResourceAsync(tag);
else if (tag.type != FOURCC('MLVL')) for (const SObjectTag& tag : mlvls)
nonMlvls.push_back(tag); m_factoryMP1.CookResourceAsync(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);
if (needsSave) if (needsSave)
saveProject(); saveProject();
@ -228,11 +242,6 @@ void ProjectManager::mainDraw()
m_mainMP1->Draw(); m_mainMP1->Draw();
} }
void ProjectManager::asyncIdle()
{
m_factoryMP1.AsyncIdle();
}
void ProjectManager::shutdown() void ProjectManager::shutdown()
{ {
if (m_mainMP1) if (m_mainMP1)

View File

@ -55,7 +55,6 @@ public:
void mainUpdate(); void mainUpdate();
void mainDraw(); void mainDraw();
void asyncIdle();
void shutdown(); void shutdown();
}; };

View File

@ -299,7 +299,7 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, selfRef); 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", Log.report(logvisor::Warning, "spin-built %.4s %08X",
task.x0_tag.type.toString().c_str(), u32(task.x0_tag.id.Value())); task.x0_tag.type.toString().c_str(), u32(task.x0_tag.id.Value()));
@ -328,7 +328,7 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
std::shared_ptr<AsyncTask> std::shared_ptr<AsyncTask>
ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag, ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag,
const urde::CVParamTransfer& paramXfer, const urde::CVParamTransfer& paramXfer,
urde::IObj** objOut, std::unique_ptr<urde::IObj>* objOut,
CObjectReference* selfRef) CObjectReference* selfRef)
{ {
if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end()) 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, void ProjectResourceFactoryBase::BuildAsync(const urde::SObjectTag& tag,
const urde::CVParamTransfer& paramXfer, const urde::CVParamTransfer& paramXfer,
urde::IObj** objOut, std::unique_ptr<urde::IObj>* objOut,
CObjectReference* selfRef) CObjectReference* selfRef)
{ {
if (!tag.id.IsValid()) 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); 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", Log.report(logvisor::Info, "async-built %.4s %08X",
task.x0_tag.type.toString().c_str(), task.x0_tag.type.toString().c_str(),
u32(task.x0_tag.id.Value())); u32(task.x0_tag.id.Value()));

View File

@ -29,7 +29,7 @@ public:
//IDvdRequest* x8_dvdReq = nullptr; //IDvdRequest* x8_dvdReq = nullptr;
std::unique_ptr<u8[]>* xc_targetDataPtr = nullptr; std::unique_ptr<u8[]>* xc_targetDataPtr = nullptr;
u8* xc_targetDataRawPtr = nullptr; u8* xc_targetDataRawPtr = nullptr;
IObj** xc_targetObjPtr = nullptr; std::unique_ptr<IObj>* xc_targetObjPtr = nullptr;
std::unique_ptr<u8[]> x10_loadBuffer; std::unique_ptr<u8[]> x10_loadBuffer;
u32 x14_resSize = UINT32_MAX; u32 x14_resSize = UINT32_MAX;
u32 x14_resOffset = 0; u32 x14_resOffset = 0;
@ -58,7 +58,7 @@ public:
x14_resOffset(off) {} x14_resOffset(off) {}
AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag, AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag,
IObj** ptr, const CVParamTransfer& xfer, CObjectReference* selfRef) std::unique_ptr<IObj>* ptr, const CVParamTransfer& xfer, CObjectReference* selfRef)
: m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer), m_selfRef(selfRef) {} : m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer), m_selfRef(selfRef) {}
/* Cook only */ /* Cook only */
@ -135,12 +135,12 @@ protected:
bool SyncCook(const hecl::ProjectPath& working); bool SyncCook(const hecl::ProjectPath& working);
CFactoryFnReturn BuildSync(const SObjectTag& tag, const hecl::ProjectPath& path, CFactoryFnReturn BuildSync(const SObjectTag& tag, const hecl::ProjectPath& path,
const CVParamTransfer& paramXfer, CObjectReference* selfRef); const CVParamTransfer& paramXfer, CObjectReference* selfRef);
std::shared_ptr<AsyncTask> BuildAsyncInternal(const urde::SObjectTag&, const urde::CVParamTransfer&, std::unique_ptr<urde::IObj>*, CObjectReference* selfRef);
public: public:
ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {} ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {}
std::unique_ptr<urde::IObj> Build(const urde::SObjectTag&, const urde::CVParamTransfer&, CObjectReference* selfRef); std::unique_ptr<urde::IObj> Build(const urde::SObjectTag&, const urde::CVParamTransfer&, CObjectReference* selfRef);
void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**, CObjectReference* selfRef); void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, std::unique_ptr<urde::IObj>*, CObjectReference* selfRef);
std::shared_ptr<AsyncTask> BuildAsyncInternal(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**, CObjectReference* selfRef);
void CancelBuild(const urde::SObjectTag&); void CancelBuild(const urde::SObjectTag&);
bool CanBuild(const urde::SObjectTag&); bool CanBuild(const urde::SObjectTag&);
const urde::SObjectTag* GetResourceIdByName(const char*) const; const urde::SObjectTag* GetResourceIdByName(const char*) const;

View File

@ -279,7 +279,8 @@ bool ViewManager::proc()
if (g_Renderer) if (g_Renderer)
g_Renderer->EndScene(); g_Renderer->EndScene();
gfxQ->execute(); gfxQ->execute();
m_projManager.asyncIdle(); if (g_ResFactory)
g_ResFactory->AsyncIdle();
m_mainWindow->waitForRetrace(m_voiceEngine.get()); m_mainWindow->waitForRetrace(m_voiceEngine.get());
CBooModel::ClearModelUniformCounters(); CBooModel::ClearModelUniformCounters();
CGraphics::TickRenderTimings(); CGraphics::TickRenderTimings();

View File

@ -70,6 +70,7 @@ private:
void Warmup(); void Warmup();
public: public:
CPakFile(const std::string& filename, bool buildDepList, bool worldPak); CPakFile(const std::string& filename, bool buildDepList, bool worldPak);
const std::vector<std::pair<std::string, SObjectTag>>& GetNameList() const { return x54_nameList; }
const std::vector<CAssetId>& GetDepList() const { return x64_depList; } const std::vector<CAssetId>& GetDepList() const { return x64_depList; }
const SObjectTag* GetResIdByName(const char* name) const; const SObjectTag* GetResIdByName(const char* name) const;
const SResInfo* GetResInfoForLoadPreferForward(CAssetId id) const; const SResInfo* GetResInfoForLoadPreferForward(CAssetId id) const;

View File

@ -1,18 +1,109 @@
#include "CResFactory.hpp" #include "CResFactory.hpp"
#include "IObj.hpp" #include "CSimplePool.hpp"
namespace urde namespace urde
{ {
std::unique_ptr<IObj> CResFactory::Build(const SObjectTag&, const CVParamTransfer&) void CResFactory::AddToLoadList(SLoadingData&& data)
{ {
return std::unique_ptr<IObj>(); 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<uint8_t[]> 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<IObj> 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<IObj>* 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<u8[]>(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::milliseconds>(
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);
} }
} }

View File

@ -5,35 +5,48 @@
#include "IFactory.hpp" #include "IFactory.hpp"
#include "CResLoader.hpp" #include "CResLoader.hpp"
#include "IVParamObj.hpp" #include "IVParamObj.hpp"
#include "MP1/MP1OriginalIDs.hpp"
#include "CToken.hpp"
namespace urde namespace urde
{ {
class IDvdRequest; class IDvdRequest;
class CSimplePool;
class CResFactory : public IFactory class CResFactory : public IFactory
{ {
CResLoader x4_loader; CResLoader x4_loader;
CFactoryMgr x5c_factoryMgr;
TLockedToken<MP1OriginalIDs> m_origIds;
public: public:
struct SLoadingData struct SLoadingData
{ {
SObjectTag x0_tag; SObjectTag x0_tag;
IDvdRequest* x8_dvdReq = nullptr; std::shared_ptr<IDvdRequest> x8_dvdReq;
IObj** xc_targetPtr = nullptr; std::unique_ptr<IObj>* xc_targetPtr = nullptr;
void* x10_loadBuffer = nullptr; std::unique_ptr<u8[]> x10_loadBuffer;
u32 x14_resSize = 0; u32 x14_resSize = 0;
CVParamTransfer x18_cvXfer; CVParamTransfer x18_cvXfer;
bool m_compressed = false;
CObjectReference* m_selfRef = nullptr;
SLoadingData() = default; SLoadingData() = default;
SLoadingData(const SObjectTag& tag, IObj** ptr, const CVParamTransfer& xfer) SLoadingData(const SObjectTag& tag, std::unique_ptr<IObj>* ptr, const CVParamTransfer& xfer,
: x0_tag(tag), xc_targetPtr(ptr), x18_cvXfer(xfer) {} bool compressed, CObjectReference* selfRef)
: x0_tag(tag), xc_targetPtr(ptr), x18_cvXfer(xfer), m_compressed(compressed), m_selfRef(selfRef) {}
}; };
private: private:
std::unordered_map<SObjectTag, SLoadingData> m_loadList; std::list<SLoadingData> m_loadList;
void AddToLoadList(const SLoadingData& data) {m_loadList[data.x0_tag] = data;} std::unordered_map<SObjectTag, std::list<SLoadingData>::iterator> m_loadMap;
void AddToLoadList(SLoadingData&& data);
CFactoryFnReturn BuildSync(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef);
bool PumpResource(SLoadingData& data);
public: public:
CResLoader& GetLoader() {return x4_loader;} CResLoader& GetLoader() {return x4_loader;}
std::unique_ptr<IObj> Build(const SObjectTag&, const CVParamTransfer&); std::unique_ptr<IObj> Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef);
void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**); void BuildAsync(const SObjectTag&, const CVParamTransfer&, std::unique_ptr<IObj>*, CObjectReference* selfRef);
void AsyncIdle();
void CancelBuild(const SObjectTag&); void CancelBuild(const SObjectTag&);
bool CanBuild(const SObjectTag& tag) bool CanBuild(const SObjectTag& tag)
@ -41,6 +54,21 @@ public:
return x4_loader.ResourceExists(tag); return x4_loader.ResourceExists(tag);
} }
u32 ResourceSize(const urde::SObjectTag& tag)
{
return x4_loader.ResourceSize(tag);
}
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag)
{
return x4_loader.LoadResourceSync(tag);
}
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off)
{
return x4_loader.LoadResourcePartSync(tag, size, off);
}
const SObjectTag* GetResourceIdByName(const char* name) const const SObjectTag* GetResourceIdByName(const char* name) const
{ {
return x4_loader.GetResourceIdByName(name); return x4_loader.GetResourceIdByName(name);
@ -53,17 +81,22 @@ public:
std::vector<std::pair<std::string, SObjectTag>> GetResourceIdToNameList() const std::vector<std::pair<std::string, SObjectTag>> GetResourceIdToNameList() const
{ {
std::vector<std::pair<std::string, SObjectTag>> retval; return x4_loader.GetResourceIdToNameList();
return retval;
} }
void EnumerateResources(std::function<bool(const SObjectTag&)> lambda) const void EnumerateResources(const std::function<bool(const SObjectTag&)>& lambda) const
{ {
return x4_loader.EnumerateResources(lambda);
} }
void EnumerateNamedResources(std::function<bool(const std::string&, const SObjectTag&)> lambda) const void EnumerateNamedResources(const std::function<bool(const std::string&, const SObjectTag&)>& lambda) const
{ {
return x4_loader.EnumerateNamedResources(lambda);
} }
void LoadOriginalIDs(CSimplePool& sp);
CAssetId TranslateOriginalToNew(CAssetId id) const;
CAssetId TranslateNewToOriginal(CAssetId id) const;
}; };
} }

View File

@ -11,7 +11,7 @@ CResLoader::CResLoader()
const std::vector<CAssetId>* CResLoader::GetTagListForFile(const std::string& name) const const std::vector<CAssetId>* CResLoader::GetTagListForFile(const std::string& name) const
{ {
std::string namePak = name + ".pak"; std::string namePak = name + ".upak";
for (const std::unique_ptr<CPakFile>& pak : x18_pakLoadedList) for (const std::unique_ptr<CPakFile>& pak : x18_pakLoadedList)
if (!CStringExtras::CompareCaseInsensitive(namePak, pak->x18_path)) if (!CStringExtras::CompareCaseInsensitive(namePak, pak->x18_path))
return &pak->GetDepList(); return &pak->GetDepList();
@ -20,7 +20,7 @@ const std::vector<CAssetId>* CResLoader::GetTagListForFile(const std::string& na
void CResLoader::AddPakFileAsync(const std::string& name, bool samusPak, bool worldPak) 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())) if (CDvdFile::FileExists(namePak.c_str()))
{ {
x30_pakLoadingList.emplace_back(new CPakFile(namePak, samusPak, worldPak)); x30_pakLoadingList.emplace_back(new CPakFile(namePak, samusPak, worldPak));
@ -95,6 +95,23 @@ std::shared_ptr<IDvdRequest> CResLoader::LoadResourceAsync(const SObjectTag& tag
ESeekOrigin::Begin, x50_cachedResInfo->GetOffset()); ESeekOrigin::Begin, x50_cachedResInfo->GetOffset());
} }
std::unique_ptr<u8[]> CResLoader::LoadResourceSync(const urde::SObjectTag& tag)
{
CPakFile* file = FindResourceForLoad(tag.id);
u32 size = ROUND_UP_32(x50_cachedResInfo->GetSize());
std::unique_ptr<u8[]> ret(new u8[size]);
file->SyncSeekRead(ret.get(), size, ESeekOrigin::Begin, x50_cachedResInfo->GetOffset());
return ret;
}
std::unique_ptr<u8[]> CResLoader::LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off)
{
CPakFile* file = FindResourceForLoad(tag.id);
std::unique_ptr<u8[]> ret(new u8[size]);
file->SyncSeekRead(ret.get(), size, ESeekOrigin::Begin, x50_cachedResInfo->GetOffset() + off);
return ret;
}
bool CResLoader::GetResourceCompression(const SObjectTag& tag) bool CResLoader::GetResourceCompression(const SObjectTag& tag)
{ {
if (FindResource(tag.id)) if (FindResource(tag.id))
@ -118,7 +135,7 @@ FourCC CResLoader::GetResourceTypeById(CAssetId id) const
{ {
if (FindResource(id)) if (FindResource(id))
return x50_cachedResInfo->GetType(); return x50_cachedResInfo->GetType();
return FourCC(); return {};
} }
const SObjectTag* CResLoader::GetResourceIdByName(const char* name) const const SObjectTag* CResLoader::GetResourceIdByName(const char* name) const
@ -236,4 +253,38 @@ void CResLoader::MoveToCorrectLoadedList(std::unique_ptr<CPakFile>&& file)
x18_pakLoadedList.push_back(std::move(file)); x18_pakLoadedList.push_back(std::move(file));
} }
std::vector<std::pair<std::string, SObjectTag>> CResLoader::GetResourceIdToNameList() const
{
std::vector<std::pair<std::string, SObjectTag>> 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<bool(const SObjectTag&)>& 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<bool(const std::string&, const SObjectTag&)>& 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;
}
}
}
} }

View File

@ -34,6 +34,8 @@ public:
std::unique_ptr<CInputStream> LoadNewResourceSync(const SObjectTag& tag, void* extBuf=nullptr); std::unique_ptr<CInputStream> LoadNewResourceSync(const SObjectTag& tag, void* extBuf=nullptr);
std::shared_ptr<IDvdRequest> LoadResourcePartAsync(const SObjectTag& tag, int offset, int length, void* buf); std::shared_ptr<IDvdRequest> LoadResourcePartAsync(const SObjectTag& tag, int offset, int length, void* buf);
std::shared_ptr<IDvdRequest> LoadResourceAsync(const SObjectTag& tag, void* buf); std::shared_ptr<IDvdRequest> LoadResourceAsync(const SObjectTag& tag, void* buf);
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);
bool GetResourceCompression(const SObjectTag& tag); bool GetResourceCompression(const SObjectTag& tag);
u32 ResourceSize(const SObjectTag& tag); u32 ResourceSize(const SObjectTag& tag);
bool ResourceExists(const SObjectTag& tag); bool ResourceExists(const SObjectTag& tag);
@ -47,6 +49,9 @@ public:
bool CacheFromPakForLoad(CPakFile& file, CAssetId id); bool CacheFromPakForLoad(CPakFile& file, CAssetId id);
bool CacheFromPak(const CPakFile& file, CAssetId id) const; bool CacheFromPak(const CPakFile& file, CAssetId id) const;
void MoveToCorrectLoadedList(std::unique_ptr<CPakFile>&& file); void MoveToCorrectLoadedList(std::unique_ptr<CPakFile>&& file);
std::vector<std::pair<std::string, SObjectTag>> GetResourceIdToNameList() const;
void EnumerateResources(const std::function<bool(const SObjectTag&)>& lambda) const;
void EnumerateNamedResources(const std::function<bool(const std::string&, const SObjectTag&)>& lambda) const;
}; };
} }

View File

@ -20,9 +20,9 @@ u16 CObjectReference::RemoveReference()
CObjectReference::CObjectReference(IObjectStore& objStore, std::unique_ptr<IObj>&& obj, CObjectReference::CObjectReference(IObjectStore& objStore, std::unique_ptr<IObj>&& obj,
const SObjectTag& objTag, CVParamTransfer buildParams) const SObjectTag& objTag, CVParamTransfer buildParams)
: x4_objTag(objTag), xC_objectStore(&objStore), : 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<IObj>&& obj) CObjectReference::CObjectReference(std::unique_ptr<IObj>&& obj)
: x10_object(obj.release()) {} : x10_object(std::move(obj)) {}
void CObjectReference::Unlock() void CObjectReference::Unlock()
{ {
@ -57,8 +57,7 @@ void CObjectReference::CancelLoad()
void CObjectReference::Unload() void CObjectReference::Unload()
{ {
std::default_delete<IObj>()(x10_object); x10_object.reset();
x10_object = nullptr;
x3_loading = false; x3_loading = false;
} }
@ -67,16 +66,16 @@ IObj* CObjectReference::GetObject()
if (!x10_object) if (!x10_object)
{ {
IFactory& factory = xC_objectStore->GetFactory(); 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; x3_loading = false;
return x10_object; return x10_object.get();
} }
CObjectReference::~CObjectReference() CObjectReference::~CObjectReference()
{ {
if (x10_object) if (x10_object)
std::default_delete<IObj>()(x10_object); x10_object.reset();
else if (x3_loading) else if (x3_loading)
xC_objectStore->GetFactory().CancelBuild(x4_objTag); xC_objectStore->GetFactory().CancelBuild(x4_objTag);
} }

View File

@ -22,7 +22,7 @@ class CObjectReference
bool x3_loading = false; /* Rightmost bit of lockCount */ bool x3_loading = false; /* Rightmost bit of lockCount */
SObjectTag x4_objTag; SObjectTag x4_objTag;
IObjectStore* xC_objectStore = nullptr; IObjectStore* xC_objectStore = nullptr;
IObj* x10_object = nullptr; std::unique_ptr<IObj> x10_object;
CVParamTransfer x14_params; CVParamTransfer x14_params;
/** Mechanism by which CToken decrements 1st ref-count, indicating CToken invalidation or reset. /** 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;} bool IsLoading() const {return x3_loading;}
/** Indicates an asynchronous load transaction has finished and object is completely loaded */ /** 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 */ /** Decrements 2nd ref-count, performing unload or async-load-cancel if 0 reached */
void Unlock(); void Unlock();

View File

@ -20,10 +20,10 @@ CFactoryFnReturn CCharacterFactoryBuilder::CDummyFactory::Build(const SObjectTag
void CCharacterFactoryBuilder::CDummyFactory::BuildAsync(const SObjectTag& tag, void CCharacterFactoryBuilder::CDummyFactory::BuildAsync(const SObjectTag& tag,
const CVParamTransfer& parms, const CVParamTransfer& parms,
IObj** objOut, std::unique_ptr<IObj>* objOut,
CObjectReference* selfRef) CObjectReference* selfRef)
{ {
*objOut = Build(tag, parms, selfRef).release(); *objOut = Build(tag, parms, selfRef);
} }
void CCharacterFactoryBuilder::CDummyFactory::CancelBuild(const SObjectTag&) void CCharacterFactoryBuilder::CDummyFactory::CancelBuild(const SObjectTag&)

View File

@ -18,7 +18,7 @@ public:
{ {
public: public:
CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef); 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<IObj>*, CObjectReference* selfRef);
void CancelBuild(const SObjectTag&); void CancelBuild(const SObjectTag&);
bool CanBuild(const SObjectTag&); bool CanBuild(const SObjectTag&);
const SObjectTag* GetResourceIdByName(const char*) const; const SObjectTag* GetResourceIdByName(const char*) const;

View File

@ -49,10 +49,10 @@ CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag,
void CCharacterFactory::CDummyFactory::BuildAsync(const SObjectTag& tag, void CCharacterFactory::CDummyFactory::BuildAsync(const SObjectTag& tag,
const CVParamTransfer& parms, const CVParamTransfer& parms,
IObj** objOut, std::unique_ptr<IObj>* objOut,
CObjectReference* selfRef) CObjectReference* selfRef)
{ {
*objOut = Build(tag, parms, selfRef).release(); *objOut = Build(tag, parms, selfRef);
} }
void CCharacterFactory::CDummyFactory::CancelBuild(const SObjectTag&) void CCharacterFactory::CDummyFactory::CancelBuild(const SObjectTag&)

View File

@ -27,7 +27,7 @@ public:
{ {
public: public:
CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef); 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<IObj>*, CObjectReference* selfRef);
void CancelBuild(const SObjectTag&); void CancelBuild(const SObjectTag&);
bool CanBuild(const SObjectTag&); bool CanBuild(const SObjectTag&);
const SObjectTag* GetResourceIdByName(const char*) const; const SObjectTag* GetResourceIdByName(const char*) const;

View File

@ -12,6 +12,7 @@ class IObj;
class CObjectReference; class CObjectReference;
class CResLoader; class CResLoader;
class CFactoryMgr; class CFactoryMgr;
class CSimplePool;
using CFactoryFnReturn = std::unique_ptr<IObj>; using CFactoryFnReturn = std::unique_ptr<IObj>;
using FFactoryFunc = std::function<CFactoryFnReturn(const urde::SObjectTag& tag, using FFactoryFunc = std::function<CFactoryFnReturn(const urde::SObjectTag& tag,
@ -28,7 +29,7 @@ class IFactory
public: public:
virtual ~IFactory() = default; virtual ~IFactory() = default;
virtual CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference*)=0; virtual CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference*)=0;
virtual void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**, CObjectReference*)=0; virtual void BuildAsync(const SObjectTag&, const CVParamTransfer&, std::unique_ptr<IObj>*, CObjectReference*)=0;
virtual void CancelBuild(const SObjectTag&)=0; virtual void CancelBuild(const SObjectTag&)=0;
virtual bool CanBuild(const SObjectTag&)=0; virtual bool CanBuild(const SObjectTag&)=0;
virtual const SObjectTag* GetResourceIdByName(const char*) const=0; virtual const SObjectTag* GetResourceIdByName(const char*) const=0;
@ -37,6 +38,8 @@ public:
virtual void EnumerateNamedResources(const std::function<bool(const std::string&, const SObjectTag&)>& lambda) const=0; virtual void EnumerateNamedResources(const std::function<bool(const std::string&, const SObjectTag&)>& lambda) const=0;
virtual CResLoader* GetResLoader() const { return nullptr; } virtual CResLoader* GetResLoader() const { return nullptr; }
virtual CFactoryMgr* GetFactoryMgr() const { return nullptr; } virtual CFactoryMgr* GetFactoryMgr() const { return nullptr; }
virtual void LoadOriginalIDs(CSimplePool& sp) {}
virtual void AsyncIdle() {}
/* Non-factory versions, replaces CResLoader */ /* Non-factory versions, replaces CResLoader */
virtual u32 ResourceSize(const urde::SObjectTag& tag)=0; virtual u32 ResourceSize(const urde::SObjectTag& tag)=0;

View File

@ -239,7 +239,7 @@ CGameArchitectureSupport::~CGameArchitectureSupport()
CStreamAudioManager::Shutdown(); CStreamAudioManager::Shutdown();
} }
CMain::CMain(IFactory& resFactory, CSimplePool& resStore, CMain::CMain(IFactory* resFactory, CSimplePool* resStore,
boo::IGraphicsDataFactory* gfxFactory, boo::IGraphicsDataFactory* gfxFactory,
boo::IGraphicsCommandQueue* cmdQ, boo::IGraphicsCommandQueue* cmdQ,
boo::ITextureR* spareTex) boo::ITextureR* spareTex)
@ -339,7 +339,6 @@ void CMain::AddWorldPaks()
std::string path = pakPrefix; std::string path = pakPrefix;
if (i != 0) if (i != 0)
path += '0' + i; path += '0' + i;
path += ".upak";
if (CDvdFile::FileExists(path.c_str())) if (CDvdFile::FileExists(path.c_str()))
if (CResLoader* loader = g_ResFactory->GetResLoader()) if (CResLoader* loader = g_ResFactory->GetResLoader())
loader->AddPakFileAsync(path, false, true); loader->AddPakFileAsync(path, false, true);

View File

@ -52,8 +52,10 @@ class CGameGlobalObjects
friend class CMain; friend class CMain;
std::unique_ptr<CMemoryCardSys> x0_memoryCardSys; std::unique_ptr<CMemoryCardSys> x0_memoryCardSys;
IFactory& x4_resFactory; std::unique_ptr<CResFactory> x4_gameResFactory;
CSimplePool& xcc_simplePool; IFactory* x4_resFactory;
std::unique_ptr<CSimplePool> x4_gameSimplePool;
CSimplePool* xcc_simplePool;
CCharacterFactoryBuilder xec_charFactoryBuilder; CCharacterFactoryBuilder xec_charFactoryBuilder;
CAiFuncMap x110_aiFuncMap; CAiFuncMap x110_aiFuncMap;
std::unique_ptr<CGameState> x134_gameState; std::unique_ptr<CGameState> x134_gameState;
@ -75,12 +77,22 @@ class CGameGlobalObjects
} }
public: public:
CGameGlobalObjects(IFactory& resFactory, CGameGlobalObjects(IFactory* resFactory,
CSimplePool& objStore) CSimplePool* objStore)
: x4_resFactory(resFactory), xcc_simplePool(objStore) : x4_resFactory(resFactory), xcc_simplePool(objStore)
{ {
g_ResFactory = &x4_resFactory; if (!x4_resFactory)
g_SimplePool = &xcc_simplePool; {
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_CharFactoryBuilder = &xec_charFactoryBuilder;
g_AiFuncMap = &x110_aiFuncMap; g_AiFuncMap = &x110_aiFuncMap;
x134_gameState.reset(new CGameState()); x134_gameState.reset(new CGameState());
@ -91,8 +103,9 @@ public:
void PostInitialize() void PostInitialize()
{ {
AddPaksAndFactories(); AddPaksAndFactories();
x4_resFactory->LoadOriginalIDs(*xcc_simplePool);
LoadStringTable(); LoadStringTable();
m_renderer.reset(AllocateRenderer(xcc_simplePool, x4_resFactory)); m_renderer.reset(AllocateRenderer(*xcc_simplePool, *x4_resFactory));
CScriptMazeNode::LoadMazeSeeds(); CScriptMazeNode::LoadMazeSeeds();
} }
@ -250,7 +263,7 @@ private:
void InitializeSubsystems(const hecl::Runtime::FileStoreManager& storeMgr); void InitializeSubsystems(const hecl::Runtime::FileStoreManager& storeMgr);
public: public:
CMain(IFactory& resFactory, CSimplePool& resStore, CMain(IFactory* resFactory, CSimplePool* resStore,
boo::IGraphicsDataFactory* gfxFactory, boo::IGraphicsDataFactory* gfxFactory,
boo::IGraphicsCommandQueue* cmdQ, boo::IGraphicsCommandQueue* cmdQ,
boo::ITextureR* spareTex); boo::ITextureR* spareTex);

View File

@ -28,7 +28,7 @@ CAssetId MP1OriginalIDs::TranslateOriginalToNew(CAssetId id) const
auto search = rstl::binary_find(m_origToNew.cbegin(), m_origToNew.cend(), id, auto search = rstl::binary_find(m_origToNew.cbegin(), m_origToNew.cend(), id,
[](const auto& id) { return id.first; }); [](const auto& id) { return id.first; });
if (search == m_origToNew.cend()) if (search == m_origToNew.cend())
return -1; return {};
return search->second; 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, auto search = rstl::binary_find(m_newToOrig.cbegin(), m_newToOrig.cend(), id,
[](const auto& id) { return id.first; }); [](const auto& id) { return id.first; });
if (search == m_newToOrig.cend()) if (search == m_newToOrig.cend())
return -1; return {};
return search->second; return search->second;
} }