mirror of https://github.com/zeldaret/botw.git
ksys/res: Add TempResourceLoader
This commit is contained in:
parent
2f80f2b581
commit
13d1f0d0be
|
|
@ -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.
|
2
lib/sead
2
lib/sead
|
|
@ -1 +1 @@
|
|||
Subproject commit 2c55e2f00fd10d58739c3a6efa57cf93c7195995
|
||||
Subproject commit 29da026c05155b3432eed35f89818bf474894b2b
|
||||
|
|
@ -111,6 +111,8 @@ target_sources(uking PRIVATE
|
|||
resResourceMgrTask.h
|
||||
resSystem.cpp
|
||||
resSystem.h
|
||||
resTempResourceLoader.cpp
|
||||
resTempResourceLoader.h
|
||||
resTextureHandleList.cpp
|
||||
resTextureHandleList.h
|
||||
resTextureHandleMgr.cpp
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue