mirror of https://github.com/AxioDL/metaforce.git
Finish CResFactory; better smart-pointer use for resources
This commit is contained in:
parent
7c3fb4174f
commit
8346f56595
|
@ -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<SObjectTag> nonMlvls;
|
||||
std::vector<SObjectTag> 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<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);
|
||||
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)
|
||||
|
|
|
@ -55,7 +55,6 @@ public:
|
|||
|
||||
void mainUpdate();
|
||||
void mainDraw();
|
||||
void asyncIdle();
|
||||
void shutdown();
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
*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<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
|
|||
std::shared_ptr<AsyncTask>
|
||||
ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag,
|
||||
const urde::CVParamTransfer& paramXfer,
|
||||
urde::IObj** objOut,
|
||||
std::unique_ptr<urde::IObj>* 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<urde::IObj>* 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()));
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
//IDvdRequest* x8_dvdReq = nullptr;
|
||||
std::unique_ptr<u8[]>* xc_targetDataPtr = nullptr;
|
||||
u8* xc_targetDataRawPtr = nullptr;
|
||||
IObj** xc_targetObjPtr = nullptr;
|
||||
std::unique_ptr<IObj>* xc_targetObjPtr = nullptr;
|
||||
std::unique_ptr<u8[]> 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<IObj>* 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<AsyncTask> BuildAsyncInternal(const urde::SObjectTag&, const urde::CVParamTransfer&, std::unique_ptr<urde::IObj>*, CObjectReference* selfRef);
|
||||
|
||||
public:
|
||||
ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {}
|
||||
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);
|
||||
std::shared_ptr<AsyncTask> BuildAsyncInternal(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);
|
||||
void CancelBuild(const urde::SObjectTag&);
|
||||
bool CanBuild(const urde::SObjectTag&);
|
||||
const urde::SObjectTag* GetResourceIdByName(const char*) const;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -70,6 +70,7 @@ private:
|
|||
void Warmup();
|
||||
public:
|
||||
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 SObjectTag* GetResIdByName(const char* name) const;
|
||||
const SResInfo* GetResInfoForLoadPreferForward(CAssetId id) const;
|
||||
|
|
|
@ -1,18 +1,109 @@
|
|||
#include "CResFactory.hpp"
|
||||
#include "IObj.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<MP1OriginalIDs> m_origIds;
|
||||
|
||||
public:
|
||||
struct SLoadingData
|
||||
{
|
||||
SObjectTag x0_tag;
|
||||
IDvdRequest* x8_dvdReq = nullptr;
|
||||
IObj** xc_targetPtr = nullptr;
|
||||
void* x10_loadBuffer = nullptr;
|
||||
std::shared_ptr<IDvdRequest> x8_dvdReq;
|
||||
std::unique_ptr<IObj>* xc_targetPtr = nullptr;
|
||||
std::unique_ptr<u8[]> 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<IObj>* 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<SObjectTag, SLoadingData> m_loadList;
|
||||
void AddToLoadList(const SLoadingData& data) {m_loadList[data.x0_tag] = data;}
|
||||
std::list<SLoadingData> m_loadList;
|
||||
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:
|
||||
CResLoader& GetLoader() {return x4_loader;}
|
||||
std::unique_ptr<IObj> Build(const SObjectTag&, const CVParamTransfer&);
|
||||
void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**);
|
||||
std::unique_ptr<IObj> Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef);
|
||||
void BuildAsync(const SObjectTag&, const CVParamTransfer&, std::unique_ptr<IObj>*, 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<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
|
||||
{
|
||||
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>> retval;
|
||||
return retval;
|
||||
return x4_loader.GetResourceIdToNameList();
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ CResLoader::CResLoader()
|
|||
|
||||
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)
|
||||
if (!CStringExtras::CompareCaseInsensitive(namePak, pak->x18_path))
|
||||
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)
|
||||
{
|
||||
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<IDvdRequest> CResLoader::LoadResourceAsync(const SObjectTag& tag
|
|||
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)
|
||||
{
|
||||
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<CPakFile>&& 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ public:
|
|||
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> 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);
|
||||
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<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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ u16 CObjectReference::RemoveReference()
|
|||
CObjectReference::CObjectReference(IObjectStore& objStore, std::unique_ptr<IObj>&& 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<IObj>&& 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<IObj>()(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<IObj>()(x10_object);
|
||||
x10_object.reset();
|
||||
else if (x3_loading)
|
||||
xC_objectStore->GetFactory().CancelBuild(x4_objTag);
|
||||
}
|
||||
|
|
|
@ -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<IObj> 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();
|
||||
|
|
|
@ -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<IObj>* objOut,
|
||||
CObjectReference* selfRef)
|
||||
{
|
||||
*objOut = Build(tag, parms, selfRef).release();
|
||||
*objOut = Build(tag, parms, selfRef);
|
||||
}
|
||||
|
||||
void CCharacterFactoryBuilder::CDummyFactory::CancelBuild(const SObjectTag&)
|
||||
|
|
|
@ -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<IObj>*, CObjectReference* selfRef);
|
||||
void CancelBuild(const SObjectTag&);
|
||||
bool CanBuild(const SObjectTag&);
|
||||
const SObjectTag* GetResourceIdByName(const char*) const;
|
||||
|
|
|
@ -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<IObj>* objOut,
|
||||
CObjectReference* selfRef)
|
||||
{
|
||||
*objOut = Build(tag, parms, selfRef).release();
|
||||
*objOut = Build(tag, parms, selfRef);
|
||||
}
|
||||
|
||||
void CCharacterFactory::CDummyFactory::CancelBuild(const SObjectTag&)
|
||||
|
|
|
@ -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<IObj>*, CObjectReference* selfRef);
|
||||
void CancelBuild(const SObjectTag&);
|
||||
bool CanBuild(const SObjectTag&);
|
||||
const SObjectTag* GetResourceIdByName(const char*) const;
|
||||
|
|
|
@ -12,6 +12,7 @@ class IObj;
|
|||
class CObjectReference;
|
||||
class CResLoader;
|
||||
class CFactoryMgr;
|
||||
class CSimplePool;
|
||||
|
||||
using CFactoryFnReturn = std::unique_ptr<IObj>;
|
||||
using FFactoryFunc = std::function<CFactoryFnReturn(const urde::SObjectTag& tag,
|
||||
|
@ -28,7 +29,7 @@ class IFactory
|
|||
public:
|
||||
virtual ~IFactory() = default;
|
||||
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 bool CanBuild(const SObjectTag&)=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 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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -52,8 +52,10 @@ class CGameGlobalObjects
|
|||
friend class CMain;
|
||||
|
||||
std::unique_ptr<CMemoryCardSys> x0_memoryCardSys;
|
||||
IFactory& x4_resFactory;
|
||||
CSimplePool& xcc_simplePool;
|
||||
std::unique_ptr<CResFactory> x4_gameResFactory;
|
||||
IFactory* x4_resFactory;
|
||||
std::unique_ptr<CSimplePool> x4_gameSimplePool;
|
||||
CSimplePool* xcc_simplePool;
|
||||
CCharacterFactoryBuilder xec_charFactoryBuilder;
|
||||
CAiFuncMap x110_aiFuncMap;
|
||||
std::unique_ptr<CGameState> 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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue