ksys/res: Add TempResourceLoader

This commit is contained in:
Léo Lam 2020-11-12 00:28:15 +01:00
parent 2f80f2b581
commit 13d1f0d0be
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
7 changed files with 328 additions and 16 deletions

View File

@ -5049,7 +5049,7 @@
0x00000071000e6500,AI_Action_DamageTurnByWeakPoint::loadParams,156,
0x00000071000e659c,AI_Action_DamageTurnByWeakPoint::rtti1,288,
0x00000071000e66bc,AI_Action_DamageTurnByWeakPoint::rtti2,92,
0x00000071000e6718,_ZN4sead21FormatFixedSafeStringILi256EEC2EPKcz,224,
0x00000071000e6718,_ZN4sead21FormatFixedSafeStringILi256EEC2EPKcz,224,_ZN4sead21FormatFixedSafeStringILi256EEC2EPKcz
0x00000071000e67f8,j__ZdlPv_42,4,
0x00000071000e67fc,AI_Action_DefeatedHugeEnemyCount::ctor,56,
0x00000071000e6834,AI_Action_DefeatedHugeEnemyCount::dtor,20,
@ -84589,20 +84589,20 @@
0x0000007100fdf538,sub_7100FDF538,52,
0x0000007100fdf56c,sub_7100FDF56C,92,
0x0000007100fdf5c8,sub_7100FDF5C8,44,
0x0000007100fdf5f4,TempResourceLoader::ctor,148,
0x0000007100fdf688,TempResourceLoader::dtor,44,
0x0000007100fdf6b4,TempResourceLoader::unload,212,
0x0000007100fdf788,TempResourceLoader::setStruct10,16,
0x0000007100fdf798,TempResourceLoader::isStatus1,12,
0x0000007100fdf7a4,TempResourceLoader::hasResourceAndIsParseOk,24,
0x0000007100fdf7bc,TempResourceLoader::callRes2I,24,
0x0000007100fdf7d4,TempResourceLoader::submitLoadReq,412,
0x0000007100fdf970,TempResourceLoader::load,504,
0x0000007100fdfb68,TempResourceLoader::loadSync,844,
0x0000007100fdfeb4,TempResourceLoader::getResource,64,
0x0000007100fdfef4,TempResourceLoader::getResError,8,
0x0000007100fdfefc,TempResourceLoader::getFileDeviceIfHasResource,56,
0x0000007100fdff34,TempResourceLoader::getHeapSize,16,
0x0000007100fdf5f4,TempResourceLoader::ctor,148,_ZN4ksys3res18TempResourceLoaderC1Ev
0x0000007100fdf688,TempResourceLoader::dtor,44,_ZN4ksys3res18TempResourceLoaderD1Ev
0x0000007100fdf6b4,TempResourceLoader::unload,212,_ZN4ksys3res18TempResourceLoader6unloadEv
0x0000007100fdf788,TempResourceLoader::setStruct10,16,_ZN4ksys3res18TempResourceLoader4initERKNS1_7InitArgE
0x0000007100fdf798,TempResourceLoader::isStatus1,12,_ZNK4ksys3res18TempResourceLoader9isLoadingEv
0x0000007100fdf7a4,TempResourceLoader::hasResourceAndIsParseOk,24,_ZNK4ksys3res18TempResourceLoader9isSuccessEv
0x0000007100fdf7bc,TempResourceLoader::callRes2I,24,_ZNK4ksys3res18TempResourceLoader15checkLoadStatusEv
0x0000007100fdf7d4,TempResourceLoader::submitLoadReq,412,_ZN4ksys3res18TempResourceLoader11requestLoadERNS1_7LoadArgE
0x0000007100fdf970,TempResourceLoader::load,504,_ZN4ksys3res18TempResourceLoader25getResourceForLoadRequestEPNS0_7ContextE
0x0000007100fdfb68,TempResourceLoader::loadSync,844,_ZN4ksys3res18TempResourceLoader4loadERNS1_7LoadArgE
0x0000007100fdfeb4,TempResourceLoader::getResource,64,_ZNK4ksys3res18TempResourceLoader11getResourceEv
0x0000007100fdfef4,TempResourceLoader::getResError,8,_ZNK4ksys3res18TempResourceLoader15getHandleStatusEv
0x0000007100fdfefc,TempResourceLoader::getFileDeviceIfHasResource,56,_ZNK4ksys3res18TempResourceLoader19getHandleFileDeviceEv
0x0000007100fdff34,TempResourceLoader::getHeapSize,16,_ZNK4ksys3res18TempResourceLoader15getWorkHeapSizeEv
0x0000007100fdff44,Struct10::ctor,8,_ZN4ksys3res11ArchiveWorkC1Ev
0x0000007100fdff4c,sub_7100FDFF4C,88,_ZN4ksys3res11ArchiveWorkD1Ev
0x0000007100fdffa4,Struct10::initEventAndOverlayArenaS1,260,_ZN4ksys3res11ArchiveWork4initERKNS1_7InitArgE

Can't render this file because it is too large.

@ -1 +1 @@
Subproject commit 2c55e2f00fd10d58739c3a6efa57cf93c7195995
Subproject commit 29da026c05155b3432eed35f89818bf474894b2b

View File

@ -111,6 +111,8 @@ target_sources(uking PRIVATE
resResourceMgrTask.h
resSystem.cpp
resSystem.h
resTempResourceLoader.cpp
resTempResourceLoader.h
resTextureHandleList.cpp
resTextureHandleList.h
resTextureHandleMgr.cpp

View File

@ -73,6 +73,7 @@ public:
sead::SafeString makeEmptyString();
ResourceUnit* getUnit() const { return mUnit; }
void setUnit(ResourceUnit* unit) { mUnit = unit; }
bool isLinked() const { return mListNode.isLinked(); }

View File

@ -0,0 +1,220 @@
#include "KingSystem/Resource/resTempResourceLoader.h"
#include <resource/seadResource.h>
#include <thread/seadThread.h>
#include "KingSystem/Resource/resArchiveWork.h"
#include "KingSystem/Resource/resResourceMgrTask.h"
#include "KingSystem/Resource/resSystem.h"
#include "KingSystem/Resource/resUnit.h"
#include "KingSystem/Utils/Debug.h"
#include "KingSystem/Utils/Thread/TaskThread.h"
namespace ksys::res {
TempResourceLoader::TempResourceLoader() = default;
TempResourceLoader::~TempResourceLoader() {
unload();
}
void TempResourceLoader::unload() {
const auto* unit = mHandle.getUnit();
const auto& path = unit ? unit->getPath() : sead::SafeString::cEmptyString;
sead::FormatFixedSafeString<256> message("(TempResourceLoader) アンロードします。: %s\n",
path.cstr());
util::PrintDebug(message);
if (mFlags.isOn(Flag::IsRetryingLoad)) {
stubbedLogFunction();
mFlags.reset(Flag::IsRetryingLoad);
} else if (returnFalse()) {
stubbedLogFunction();
}
mFlags.reset(Flag::Loading);
mHandle.requestUnload();
if (mResource) {
ResourceMgrTask::instance()->unloadSeadResource(mResource);
mResource = nullptr;
}
if (mWork)
mWork->setEvent();
}
bool TempResourceLoader::init(const InitArg& arg) {
mWork = arg.work;
return true;
}
bool TempResourceLoader::isLoading() const {
return mFlags.isOn(Flag::Loading);
}
bool TempResourceLoader::isSuccess() const {
return !isLoading() && mHandle.isSuccess();
}
bool TempResourceLoader::checkLoadStatus() const {
return !isLoading() && mHandle.checkLoadStatus();
}
void TempResourceLoader::requestLoad(LoadArg& arg) {
if (!arg.use_handle)
return;
updateFlagsBeforeLoadingStarts();
mPath = arg.load_req.mPath;
mLoadArg = arg;
mLoadArg.load_req.mPath = mPath;
arg.load_req.mArena = mWork->getArena();
mHandle.requestLoad(arg.load_req.mPath, &arg.load_req);
if (returnFalse())
stubbedLogFunction();
}
sead::DirectResource* TempResourceLoader::getResourceForLoadRequest(Context* context) {
if (!mLoadArg.use_handle || !mHandle.isFlag2Set() || mHandle.isFlag8Set() ||
!mHandle.isReadyOrNeedsParse()) {
return nullptr;
}
mHandle.parseResource(context);
if (!mHandle.isSuccess()) {
if (mHandle.getStatus() != Handle::Status::_3) {
mFlags.reset(Flag::Loading);
sead::FormatFixedSafeString<256> message(
"(TempResourceLoader) メモリ不足以外のエラーでした。: %s(%d)\n",
mLoadArg.load_req.mPath.cstr(), s32(mHandle.getStatus()));
util::PrintDebug(message);
resetRetryFlag();
return nullptr;
}
if (!mLoadArg.retry_on_failure) {
mFlags.reset(Flag::Loading);
sead::FormatFixedSafeString<256> message(
"(TempResourceLoader) ロード失敗しました。: %s\n", mLoadArg.load_req.mPath.cstr());
util::PrintDebug(message);
resetRetryFlag();
return nullptr;
}
setRetryFlag();
mLoadArg.load_req.mArena = mWork->getArena();
mHandle.requestLoad(mLoadArg.load_req.mPath, &mLoadArg.load_req);
return nullptr;
}
mFlags.reset(Flag::Loading);
sead::FormatFixedSafeString<256> message("(TempResourceLoader) ロードに成功しました。: %s\n",
mLoadArg.load_req.mPath.cstr());
util::PrintDebug(message);
resetRetryFlag();
return mHandle.getResource();
}
sead::DirectResource* TempResourceLoader::load(TempResourceLoader::LoadArg& arg) {
updateFlagsBeforeLoadingStarts();
const auto* current_thread = sead::ThreadMgr::instance()->getCurrentThread();
bool is_on_res_thread = false;
is_on_res_thread |= current_thread == ResourceMgrTask::instance()->getResourceMemoryThread();
is_on_res_thread |= current_thread == ResourceMgrTask::instance()->getResourceLoadingThread();
if (is_on_res_thread)
arg.use_handle = false;
while (true) {
if (returnFalse())
stubbedLogFunction();
bool use_handle = arg.use_handle;
auto* arena = mWork->getArena();
if (use_handle) {
arg.load_req.mArena = arena;
mHandle.load(arg.load_req.mPath, &arg.load_req);
if (mHandle.isSuccess())
break;
if (mHandle.getStatus() != Handle::Status::_3) {
mFlags.reset(Flag::Loading);
sead::FormatFixedSafeString<256> message(
"(TempResourceLoader) メモリ不足以外のエラーでした。: %s(%d)\n",
arg.load_req.mPath.cstr(), s32(mHandle.getStatus()));
util::PrintDebug(message);
resetRetryFlag();
return nullptr;
}
} else {
ResourceMgrTask::DirectLoadArg load_arg{};
load_arg.heap = arena->getHeap();
load_arg.req._21 = false;
load_arg.req._22 = true;
load_arg.req.mPath = arg.load_req.mPath;
load_arg.req.mAocFileDevice = arg.load_req.mAocFileDevice;
load_arg.req.mLoadDataAlignment = arg.load_req.mLoadDataAlignment;
load_arg.req.mEntryFactory = arg.load_req.mEntryFactory;
load_arg.req._20 = false;
load_arg.req.mRequester = "TempResourceLoader";
if (arena->getHeap()->isLockEnabled())
arena->getHeap()->getCriticalSection().lock();
mResource = ResourceMgrTask::instance()->load(load_arg);
if (arena->getHeap()->isLockEnabled())
arena->getHeap()->getCriticalSection().unlock();
if (mResource) {
mFlags.reset(Flag::Loading);
return mResource;
}
}
if (!arg.retry_on_failure) {
mFlags.reset(Flag::Loading);
sead::FormatFixedSafeString<256> message(
"(TempResourceLoader) ロード失敗しました。: %s\n", arg.load_req.mPath.cstr());
util::PrintDebug(message);
resetRetryFlag();
return nullptr;
}
setRetryFlag();
if (!mWork->waitForEvent(arg.ms_between_attempts)) {
mFlags.reset(Flag::Loading);
return nullptr;
}
}
mFlags.reset(Flag::Loading);
sead::FormatFixedSafeString<256> message("(TempResourceLoader) ロードに成功しました。: %s\n",
arg.load_req.mPath.cstr());
util::PrintDebug(message);
resetRetryFlag();
return mHandle.getResource();
}
sead::DirectResource* TempResourceLoader::getResource() const {
if (mHandle.getResource())
return mHandle.getResource();
return mResource;
}
Handle::Status TempResourceLoader::getHandleStatus() const {
return mHandle.getStatus();
}
sead::FileDevice* TempResourceLoader::getHandleFileDevice() const {
if (mHandle.isSuccess())
return mHandle.getUnit()->getLoadArg().device;
return nullptr;
}
u32 TempResourceLoader::getWorkHeapSize() const {
return mWork ? mWork->getHeapSize() : 0;
}
} // namespace ksys::res

View File

@ -0,0 +1,87 @@
#pragma once
#include <basis/seadTypes.h>
#include <prim/seadSafeString.h>
#include <prim/seadTypedBitFlag.h>
#include "KingSystem/Resource/resHandle.h"
#include "KingSystem/Resource/resLoadRequest.h"
#include "KingSystem/Resource/resSystem.h"
#include "KingSystem/Utils/Types.h"
namespace sead {
class DirectResource;
}
namespace ksys::res {
class ArchiveWork;
class TempResourceLoader {
public:
struct InitArg {
ArchiveWork* work;
};
struct LoadArg {
bool retry_on_failure = true;
bool use_handle = true;
u32 ms_between_attempts = 0;
LoadRequest load_req;
};
TempResourceLoader();
~TempResourceLoader();
void unload();
bool init(const InitArg& arg);
bool isLoading() const;
bool isSuccess() const;
bool checkLoadStatus() const;
void requestLoad(LoadArg& arg);
sead::DirectResource* getResourceForLoadRequest(Context* context);
sead::DirectResource* load(LoadArg& arg);
sead::DirectResource* getResource() const;
Handle::Status getHandleStatus() const;
sead::FileDevice* getHandleFileDevice() const;
u32 getWorkHeapSize() const;
private:
enum class Flag : u8 {
Loading = 1,
IsRetryingLoad = 2,
};
void setRetryFlag() {
if (mFlags.isOff(Flag::IsRetryingLoad)) {
stubbedLogFunction();
mFlags.set(Flag::IsRetryingLoad);
} else if (returnFalse()) {
stubbedLogFunction();
}
}
void resetRetryFlag() {
if (mFlags.isOn(Flag::IsRetryingLoad)) {
stubbedLogFunction();
mFlags.reset(Flag::IsRetryingLoad);
} else if (returnFalse()) {
stubbedLogFunction();
}
}
void updateFlagsBeforeLoadingStarts() {
mFlags.reset(Flag::Loading);
mFlags.reset(Flag::IsRetryingLoad);
mFlags.set(Flag::Loading);
}
sead::TypedBitFlag<Flag> mFlags;
sead::DirectResource* mResource{};
ArchiveWork* mWork{};
Handle mHandle;
LoadArg mLoadArg;
sead::FixedSafeString<128> mPath;
};
KSYS_CHECK_SIZE_NX150(TempResourceLoader, 0x188);
} // namespace ksys::res

View File

@ -94,6 +94,8 @@ public:
void attachHandle(Handle* handle);
const sead::SafeString& getPath() const { return mPath; }
const sead::ResourceMgr::LoadArg& getLoadArg() const { return mLoadArg; }
s32 getRefCount() const;
Status getStatus() const;