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)
{
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)

View File

@ -55,7 +55,6 @@ public:
void mainUpdate();
void mainDraw();
void asyncIdle();
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);
}
*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()));

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;
};
}

View File

@ -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;
}
}
}
}

View File

@ -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;
};
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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&)

View File

@ -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;

View File

@ -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&)

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
}