metaforce/Runtime/CResFactory.cpp

148 lines
4.5 KiB
C++
Raw Normal View History

#include "CResFactory.hpp"
#include "CSimplePool.hpp"
2017-11-18 23:10:54 -08:00
#include "CStopwatch.hpp"
2016-03-04 15:04:53 -08:00
namespace urde
{
2017-10-27 03:10:32 -07:00
static logvisor::Module Log("CResFactory");
void CResFactory::AddToLoadList(SLoadingData&& data)
2015-08-21 18:58:41 -07:00
{
m_loadMap[data.x0_tag] = m_loadList.insert(m_loadList.end(), std::move(data));
2015-08-21 18:58:41 -07:00
}
CFactoryFnReturn CResFactory::BuildSync(const SObjectTag& tag, const CVParamTransfer& xfer, CObjectReference* selfRef)
{
2017-10-27 03:10:32 -07:00
CFactoryFnReturn ret;
if (x5c_factoryMgr.CanMakeMemory(tag))
{
std::unique_ptr<uint8_t[]> data;
2017-10-28 00:08:48 -07:00
int size = 0;
x4_loader.LoadMemResourceSync(tag, data, &size);
2017-10-28 00:08:48 -07:00
if (size)
ret = x5c_factoryMgr.MakeObjectFromMemory(tag, std::move(data), size,
x4_loader.GetResourceCompression(tag), xfer, selfRef);
2018-01-13 22:44:22 -08:00
else
ret = std::make_unique<TObjOwnerDerivedFromIObjUntyped>(nullptr);
}
else
{
2017-10-28 00:08:48 -07:00
if (auto rp = x4_loader.LoadNewResourceSync(tag, nullptr))
ret = x5c_factoryMgr.MakeObject(tag, *rp, xfer, selfRef);
2018-01-13 22:44:22 -08:00
else
ret = std::make_unique<TObjOwnerDerivedFromIObjUntyped>(nullptr);
}
2017-10-27 03:10:32 -07:00
Log.report(logvisor::Warning, "sync-built %.4s %08X", tag.type.getChars(), tag.id.Value());
return ret;
}
bool CResFactory::PumpResource(SLoadingData& data)
{
2018-05-07 22:10:24 -07:00
if (data.x8_dvdReq && data.x8_dvdReq->IsComplete())
{
2018-05-07 22:10:24 -07:00
data.x8_dvdReq.reset();
*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);
2017-10-27 03:10:32 -07:00
Log.report(logvisor::Info, "async-built %.4s %08X", data.x0_tag.type.getChars(), data.x0_tag.id.Value());
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) {}
2017-10-28 00:08:48 -07:00
std::unique_ptr<IObj> ret = std::move(*search->second->xc_targetPtr);
m_loadList.erase(search->second);
m_loadMap.erase(search);
2017-10-28 00:08:48 -07:00
return ret;
}
return BuildSync(tag, xfer, selfRef);
}
void CResFactory::BuildAsync(const SObjectTag& tag, const CVParamTransfer& xfer, std::unique_ptr<IObj>* target,
CObjectReference* selfRef)
2015-08-21 18:58:41 -07:00
{
auto search = m_loadMap.find(tag);
2017-10-28 00:08:48 -07:00
if (search == m_loadMap.end())
{
SLoadingData data(tag, target, xfer, x4_loader.GetResourceCompression(tag), selfRef);
2017-10-28 00:08:48 -07:00
data.x14_resSize = x4_loader.ResourceSize(tag);
if (data.x14_resSize)
{
data.x10_loadBuffer = std::unique_ptr<u8[]>(new u8[data.x14_resSize]);
data.x8_dvdReq = x4_loader.LoadResourceAsync(tag, data.x10_loadBuffer.get());
AddToLoadList(std::move(data));
}
2018-01-13 22:44:22 -08:00
else
{
*target = std::make_unique<TObjOwnerDerivedFromIObjUntyped>(nullptr);
}
}
2015-08-21 18:58:41 -07:00
}
void CResFactory::AsyncIdle()
{
2017-10-27 03:10:32 -07:00
if (m_loadList.empty())
return;
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();
2017-10-28 00:08:48 -07:00
if (m_loadList.empty())
return;
}
}
}
void CResFactory::CancelBuild(const SObjectTag& tag)
{
auto search = m_loadMap.find(tag);
if (search != m_loadMap.end())
{
2018-05-07 22:10:24 -07:00
if (search->second->x8_dvdReq)
search->second->x8_dvdReq->PostCancelRequest();
m_loadList.erase(search->second);
m_loadMap.erase(search);
}
}
void CResFactory::LoadOriginalIDs(CSimplePool& sp)
{
2018-04-07 13:55:57 -07:00
#if RUNTIME_ORIGINAL_IDS
m_origIds = sp.GetObj("MP1OriginalIDs");
#endif
}
CAssetId CResFactory::TranslateOriginalToNew(CAssetId id) const
{
2018-04-07 13:55:57 -07:00
#if RUNTIME_ORIGINAL_IDS
return m_origIds->TranslateOriginalToNew(id);
#else
/* The packager will have restored these ahead of time */
return id;
2018-04-07 13:55:57 -07:00
#endif
}
CAssetId CResFactory::TranslateNewToOriginal(CAssetId id) const
2015-08-21 18:58:41 -07:00
{
2018-04-07 13:55:57 -07:00
#if RUNTIME_ORIGINAL_IDS
return m_origIds->TranslateNewToOriginal(id);
#else
/* The packager will have restored these ahead of time */
return id;
2018-04-07 13:55:57 -07:00
#endif
2015-08-21 18:58:41 -07:00
}
}