ksys/res: Implement more ResourceUnit functions

This commit is contained in:
Léo Lam 2020-10-10 16:37:41 +02:00
parent 689221f4a2
commit fc0d0ddaf7
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
11 changed files with 266 additions and 47 deletions

View File

@ -48284,11 +48284,11 @@
0x00000071007cb614,GameSceneTaskMgr::init,324,
0x00000071007cb758,GameSceneTaskMgr::invokeInvoker,40,
0x00000071007cb780,GameSceneTaskMgr::submitRequest,172,
0x00000071007cb82c,BaseProcEvent::Request::dtor,4,
0x00000071007cb82c,BaseProcEvent::Request::dtor,4,_ZN4ksys4util11TaskRequestD2Ev
0x00000071007cb830,j__ZdlPv_350,4,
0x00000071007cb834,sub_71007CB834,112,
0x00000071007cb8a4,sub_71007CB8A4,92,
0x00000071007cb900,j__ZdlPv_351,4,
0x00000071007cb834,sub_71007CB834,112,_ZNK4ksys4util11TaskRequest27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x00000071007cb8a4,sub_71007CB8A4,92,_ZNK4ksys4util11TaskRequest18getRuntimeTypeInfoEv
0x00000071007cb900,j__ZdlPv_351,4,_ZN4ksys4util11TaskRequestD0Ev
0x00000071007cb904,sub_71007CB904,52,
0x00000071007cb938,sub_71007CB938,92,
0x00000071007cb994,sub_71007CB994,56,
@ -82718,7 +82718,7 @@
0x0000007100fe6438,sub_7100FE6438,204,
0x0000007100fe6504,sub_7100FE6504,92,
0x0000007100fe6560,j__ZdlPv_1024,4,
0x0000007100fe6564,sub_7100FE6564,140,
0x0000007100fe6564,sub_7100FE6564,140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4util11TaskRequestEE9isDerivedEPKNS0_9InterfaceE
0x0000007100fe65f0,sub_7100FE65F0,52,
0x0000007100fe6624,sub_7100FE6624,92,
0x0000007100fe6680,sub_7100FE6680,48,
@ -90521,7 +90521,7 @@
0x00000071011f7a80,SetMainInvokerClass::ctor,20,_ZN4ksys4util18TaskDelegateSetterC1Ev
0x00000071011f7a94,SetMainInvokerClass::dtor,4,_ZN4ksys4util18TaskDelegateSetterD1Ev
0x00000071011f7a98,j__ZdlPv_1227,4,_ZN4ksys4util18TaskDelegateSetterD0Ev
0x00000071011f7a9c,sub_71011F7A9C,8,_ZN4ksys4util18TaskDelegateSetter11setDelegateEPN4sead13AnyDelegate1RIPvbEE
0x00000071011f7a9c,sub_71011F7A9C,8,_ZN4ksys4util18TaskDelegateSetter11setDelegateEPN4sead11IDelegate1RIPvbEE
0x00000071011f7aa4,EventPlusString::ctor,120,_ZN4ksys4util4TaskC1EPN4sead4HeapE
0x00000071011f7b1c,EventPlusString::ctor2,120,_ZN4ksys4util4TaskC1EPN4sead4HeapENS2_9IDisposer14HeapNullOptionE
0x00000071011f7b94,EventPlusString::dtor,132,_ZN4ksys4util4TaskD1Ev?
@ -90531,7 +90531,7 @@
0x00000071011f7d38,EventPlusString::submitRequest,544,_ZN4ksys4util4Task13submitRequestERNS0_11TaskRequestE?
0x00000071011f7f58,EventPlusString::u,124,_ZNK4ksys4util4Task16canSubmitRequestEv
0x00000071011f7fd4,_ZN4ksys4util4Task11setUserDataEPv,8,_ZN4ksys4util4Task11setUserDataEPv
0x00000071011f7fdc,_ZN4ksys4util4Task20setDelegateInternal_EPN4sead13AnyDelegate1RIPvbEE,0x58,_ZN4ksys4util4Task20setDelegateInternal_EPN4sead13AnyDelegate1RIPvbEE
0x00000071011f7fdc,_ZN4ksys4util4Task20setDelegateInternal_EPN4sead11IDelegate1RIPvbEE,0x58,_ZN4ksys4util4Task20setDelegateInternal_EPN4sead11IDelegate1RIPvbEE
0x00000071011f8034,EventPlusString::v,360,_ZN4ksys4util4Task30processOnCurrentThreadDirectlyEPNS0_10TaskThreadE
0x00000071011f819c,EventPlusString::p,28,_ZN4ksys4util4Task15removeFromQueueEv
0x00000071011f81b8,sub_71011F81B8,28,_ZN4ksys4util4Task16removeFromQueue2Ev
@ -90902,7 +90902,7 @@
0x0000007101207110,res::ResourceMgrTask::postCalc,20,
0x0000007101207124,res::ResourceMgrTask::clearAllCaches,288,
0x0000007101207244,res::ResourceMgrTask::BinderArray::getTexHandleMgrArena,32,
0x0000007101207264,EventPlusString::RequestEx::dtor,24,
0x0000007101207264,EventPlusString::RequestEx::dtor,24,_ZN4ksys3res18ControlTaskRequestD2Ev
0x000000710120727c,res::ResourceMgrTask::defragAllMemoryMgr,800,
0x000000710120759c,res::ResourceMgrTask::__auto7,20,
0x00000071012075b0,res::ResourceMgrTask::getDefragProgress,104,
@ -90965,9 +90965,9 @@
0x000000710120c530,res::ResourceMgrTask::removeOverlayArena,152,
0x000000710120c6dc,res::ResourceMgrTask::checkDerivedRuntimeTypeInfo,288,
0x000000710120c7fc,res::ResourceMgrTask::getRuntimeTypeInfo,92,
0x000000710120c858,EventPlusString::RequestEx::rtti1,204,
0x000000710120c924,EventPlusString::RequestEx::rtti2,92,
0x000000710120c980,EventPlusString::RequestEx::dtorDelete,56,
0x000000710120c858,EventPlusString::RequestEx::rtti1,204,_ZNK4ksys3res18ControlTaskRequest27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x000000710120c924,EventPlusString::RequestEx::rtti2,92,_ZNK4ksys3res18ControlTaskRequest18getRuntimeTypeInfoEv
0x000000710120c980,EventPlusString::RequestEx::dtorDelete,56,_ZN4ksys3res18ControlTaskRequestD0Ev
0x000000710120c9b8,sub_710120C9B8,204,_ZNK4ksys3res17MemoryTaskRequest27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x000000710120ca84,sub_710120CA84,92,_ZNK4ksys3res17MemoryTaskRequest18getRuntimeTypeInfoEv
0x000000710120cae0,j__ZdlPv_1239,4,_ZN4ksys3res17MemoryTaskRequestD0Ev
@ -91021,14 +91021,14 @@
0x000000710120df44,ResourceBinder::field8Stuff,56,_ZN4ksys3res12ResourceUnit18setIsLinkedToCacheEb
0x000000710120df7c,ResourceBinder::c,24,_ZN4ksys3res12ResourceUnit15removeFromCacheEv
0x000000710120df94,ResourceBinder::eps3CallP,28,_ZN4ksys3res12ResourceUnit20removeTask3FromQueueEv
0x000000710120dfb0,ResourceBinder::requestReadFilePathAndPrepareLoadOnResMemThread,204,
0x000000710120e07c,ResourceBinder::waitForResourceAndParse,792,
0x000000710120e394,ResourceBinder::waitForEvent1,28,
0x000000710120e3b0,ResourceBinder::adjustHeapStuff,552,
0x000000710120e5d8,ResourceBinder::eps1WaitTimed,8,
0x000000710120e5e0,Res::clearBinderPtr,8,
0x000000710120e5e8,ResourceBinder::setStatus10000,16,
0x000000710120e5f8,ResourceBinder::checkStatusByte2,12,
0x000000710120dfb0,ResourceBinder::requestReadFilePathAndPrepareLoadOnResMemThread,204,_ZN4ksys3res12ResourceUnit15requestInitLoadERKNS1_18RequestInitLoadArgE
0x000000710120e07c,ResourceBinder::waitForResourceAndParse,792,_ZN4ksys3res12ResourceUnit23waitForResourceAndParseEPNS0_7ContextE
0x000000710120e394,ResourceBinder::waitForEvent1,28,_ZN4ksys3res12ResourceUnit12waitForTask1Ev
0x000000710120e3b0,ResourceBinder::adjustHeapStuff,552,_ZN4ksys3res12ResourceUnit18adjustHeapAndArenaEv
0x000000710120e5d8,ResourceBinder::eps1WaitTimed,8,_ZN4ksys3res12ResourceUnit12waitForTask1ERKN4sead8TickSpanE
0x000000710120e5e0,Res::clearBinderPtr,8,_ZN4ksys3res12ResourceUnit17detachFromHandle_EPNS0_6HandleE
0x000000710120e5e8,ResourceBinder::setStatus10000,16,_ZN4ksys3res12ResourceUnit18setStatusFlag10000Ev
0x000000710120e5f8,ResourceBinder::checkStatusByte2,12,_ZNK4ksys3res12ResourceUnit20isStatusFlag10000SetEv
0x000000710120e604,ResourceBinder::defrag_createNewResAndCopyData,2272,
0x000000710120eee4,ResourceBinder::readFilePathAndGetBufSize,4612,
0x00000071012100e8,ResourceBinder::readFilePathInternalAndGetBufSize,348,

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

View File

@ -43,7 +43,7 @@ Handle::Status Cache::loadResource(const ControlTaskData& data) {
return false;
}
if (unit->isStatusFlag1000Set()) {
if (unit->isStatusFlag10000Set()) {
unit->removeFromCache();
return false;
}
@ -130,10 +130,10 @@ Handle::Status Cache::loadResource(const ControlTaskData& data) {
lane_id = 2 * data.mResLoadReq._c + (x ? 1 : 2);
}
ResourceUnit::RequestLoadArg load_arg;
ResourceUnit::RequestInitLoadArg load_arg;
load_arg.lane_id = lane_id;
load_arg.has_handle = data.mResLoadReq._8;
result->requestLoad(load_arg);
result->requestInitLoad(load_arg);
return Handle::Status::_7;
}

View File

@ -43,6 +43,7 @@ class ControlTaskRequest : public util::TaskRequest {
SEAD_RTTI_OVERRIDE(ControlTaskRequest, util::TaskRequest)
public:
ControlTaskRequest() = default;
ControlTaskRequest(bool has_handle) : TaskRequest(has_handle) {}
bool mHasResLoadReq = false;
ResourceUnit* mPackResUnit = nullptr;

View File

@ -16,8 +16,8 @@ void Resource::onDestroy() {
onDestroy_();
}
void Resource::parse(Context*, sead::Heap* heap) {
parse_(mRawData, mRawSize, heap);
bool Resource::parse(Context*, sead::Heap* heap) {
return parse_(mRawData, mRawSize, heap);
}
bool Resource::finalize() {
@ -25,7 +25,7 @@ bool Resource::finalize() {
return true;
}
bool Resource::finishParsing() {
bool Resource::finishParsing(Context*) {
const bool ret = finishParsing_();
mContext = nullptr;
return ret;

View File

@ -29,9 +29,9 @@ public:
void setContext(Context* context);
void onDestroy();
void parse(Context*, sead::Heap* heap);
bool parse(Context*, sead::Heap* heap);
bool finalize();
bool finishParsing();
bool finishParsing(Context* context);
bool m7();
static constexpr size_t cLoadDataAlignment = 4;

View File

@ -71,6 +71,21 @@ KSYS_CHECK_SIZE_NX150(FileDevicePrefix, 0x28);
class ResourceMgrTask : public sead::CalculateTask, public sead::hostio::Node {
SEAD_RTTI_OVERRIDE(ResourceMgrTask, sead::CalculateTask)
public:
enum class LaneId {
_9 = 9,
_10 = 10,
};
using ResourceUnitDelegate = sead::Delegate1RFunc<void*, bool>;
using TaskCallback =
sead::Delegate2Func<util::TaskPostRunResult*, const util::TaskPostRunContext&>;
using MemoryTaskDelegate = sead::Delegate1R<ResourceMgrTask, void*, bool>;
struct ResourceUnitDelegatePair {
ResourceUnitDelegate fn;
TaskCallback cb;
};
static ResourceMgrTask* instance() { return sInstance; }
void prepare() override;
@ -97,6 +112,14 @@ public:
sead::BufferedSafeString& new_path, s32 dot_idx,
const sead::SafeString& extension);
util::TaskThread* getResourceLoadingThread() const { return mResourceLoadingThread; }
util::TaskThread* getResourceControlThread() const { return mResourceControlThread; }
util::TaskThread* getResourceMemoryThread() const { return mResourceMemoryThread; }
util::TaskThread* getMovableMemoryThread() const { return mMovableMemoryThread; }
ResourceUnitDelegatePair& getUnitInitLoadFn() { return mUnitInitLoadFn; }
auto& getUnitAdjustHeapFn() { return mUnitAdjustHeapFn; }
private:
enum class Flag {
@ -106,20 +129,6 @@ private:
ClearAllCachesRequested = 1,
};
enum class LaneId {
_9 = 9,
};
using ResourceUnitDelegate = sead::Delegate1RFunc<void*, bool>;
using TaskCallback =
sead::Delegate2Func<util::TaskPostRunResult*, const util::TaskPostRunContext&>;
using MemoryTaskDelegate = sead::Delegate1R<ResourceMgrTask, void*, bool>;
struct ResourceUnitDelegatePair {
ResourceUnitDelegate fn;
TaskCallback cb;
};
explicit ResourceMgrTask(const sead::TaskConstructArg& arg);
~ResourceMgrTask();
@ -168,7 +177,7 @@ private:
ResourceUnitDelegatePair mUnitInitLoadFn;
ResourceUnitDelegate mUnitPrepareLoadFn;
ResourceUnitDelegate mUnitAdjustHeapFn;
ResourceUnitDelegatePair mDelegate2; // TODO: rename
ResourceUnitDelegatePair mUnitUnloadForSyncFn;
ResourceUnitDelegatePair mUnitUnloadFn;
ResourceUnitDelegatePair mUnitClearCacheForSyncFn;
ResourceUnitDelegatePair mUnitClearCacheFn;

View File

@ -1,5 +1,7 @@
#pragma once
#include <prim/seadSafeString.h>
namespace ksys::res {
// In release builds, the only thing this function does is return 1.
@ -12,6 +14,6 @@ bool returnFalse();
// In release builds, the only thing this function does is return 0.
// TODO: figure out what this is used for. Stubbed log function?
bool returnFalse2();
bool returnFalse2(const sead::SafeString&);
} // namespace ksys::res

View File

@ -2,8 +2,10 @@
#include <filedevice/seadArchiveFileDevice.h>
#include <resource/seadArchiveRes.h>
#include "KingSystem/Resource/resCache.h"
#include "KingSystem/Resource/resControlTask.h"
#include "KingSystem/Resource/resEntryFactory.h"
#include "KingSystem/Resource/resLoadRequest.h"
#include "KingSystem/Resource/resResourceMgrTask.h"
#include "KingSystem/Resource/resSystem.h"
namespace ksys::res {
@ -224,4 +226,169 @@ bool ResourceUnit::removeTask3FromQueue() {
return true;
}
void ResourceUnit::requestInitLoad(const RequestInitLoadArg& arg) {
mStatus = Status::_7;
util::TaskRequest req;
req.mHasHandle = arg.has_handle;
req.mSynchronous = false;
req.mLaneId = arg.lane_id;
req.mThread = ResourceMgrTask::instance()->getResourceMemoryThread();
req.mDelegate = &ResourceMgrTask::instance()->getUnitInitLoadFn().fn;
req.mUserData = this;
req.mPostRunCallback = &ResourceMgrTask::instance()->getUnitInitLoadFn().cb;
req.mName = mPath;
mTask1.submitRequest(req);
if (returnFalse2(sead::SafeString(mPath)))
stubbedLogFunction();
}
bool ResourceUnit::waitForResourceAndParse(Context* context) {
const auto adjust_heap_and_dec_ref = [&] {
adjustHeapAndArena();
if (mStatusFlags.isOn(StatusFlag::_80000)) {
mRefCount.decrement();
mStatusFlags.reset(StatusFlag::_80000);
ksys::res::stubbedLogFunction();
}
};
if (isParseOk())
return true;
if (mCounter.increment() >= 1) {
mEvent.wait();
if (mStatus != Status::_15 && mStatus != Status::_12)
return true;
ksys::res::stubbedLogFunction();
return false;
}
mTask1.wait();
bool set_status_12 = true;
if (mResource) {
auto* res = sead::DynamicCast<ksys::res::Resource>(mResource);
if (!res || !res->needsParse()) {
mEvent.setSignal();
return true;
}
bool finish_parsing = mStatus != Status::_8;
if (!finish_parsing) {
auto* heap = mHeap;
mStatus = Status::_10;
if (context)
res->setContext(context);
if (res->parse(context, heap)) {
mStatus = Status::_11;
finish_parsing = true;
} else {
adjust_heap_and_dec_ref();
}
}
if (finish_parsing) {
mStatus = Status::_13;
if (mResource) {
bool ok = true;
if (auto* ksys_res = sead::DynamicCast<ksys::res::Resource>(mResource)) {
if (context)
ksys_res->setContext(context);
ok = ksys_res->finishParsing(context);
}
mStatus = ok ? Status::_14 : Status::_15;
if (ok) {
adjustHeapAndArena();
mEvent.setSignal();
return true;
}
}
adjust_heap_and_dec_ref();
set_status_12 = false;
}
}
if (set_status_12)
mStatus = Status::_12;
mEvent.setSignal();
ksys::res::stubbedLogFunction();
return false;
}
bool ResourceUnit::waitForTask1() {
mTask1.wait();
return true;
}
void ResourceUnit::adjustHeapAndArena() {
if (mStatusFlags.isOn(StatusFlag::HasHeap)) {
mStatusFlags.set(StatusFlag::_8);
return;
}
if (mStatusFlags.isOn(StatusFlag::_8)) {
auto* arena = mArena1;
if (mStatusFlags.isOff(StatusFlag::_2)) {
arena->addSize(mHeap ? mHeap->getSize() : 0);
mStatusFlags.set(StatusFlag::_2);
}
if (mStatusFlags.isOff(StatusFlag::_4) &&
mStatusFlags.isOff(StatusFlag::NeedToIncrementRefCount)) {
arena->addSize2(mHeap ? mHeap->getSize() : 0);
mStatusFlags.set(StatusFlag::_4);
return;
}
} else {
if (mStatusFlags.isOn(StatusFlag::_40000)) {
ControlTaskRequest req{false};
req.mHasHandle = false;
req.mSynchronous = false;
req.mLaneId = u8(res::ResourceMgrTask::LaneId::_10);
req.mThread = res::ResourceMgrTask::instance()->getResourceMemoryThread();
req.mDelegate = &res::ResourceMgrTask::instance()->getUnitAdjustHeapFn();
req.mUserData = this;
req.mName = "HeapAdjust";
mTask2.submitRequest(req);
return;
}
auto* arena = mArena1;
if (mStatusFlags.isOff(StatusFlag::_2)) {
arena->addSize(mHeap ? mHeap->getSize() : 0);
mStatusFlags.set(StatusFlag::_2);
}
if (mStatusFlags.isOff(StatusFlag::_4) &&
mStatusFlags.isOff(StatusFlag::NeedToIncrementRefCount)) {
arena->addSize2(mHeap ? mHeap->getSize() : 0);
mStatusFlags.set(StatusFlag::_4);
return;
}
}
}
bool ResourceUnit::waitForTask1(const sead::TickSpan& span) {
return mTask1.wait(span);
}
void ResourceUnit::detachFromHandle_(Handle* handle) {
handle->setUnit(nullptr);
}
void ResourceUnit::setStatusFlag10000() {
mStatusFlags.set(StatusFlag::_10000);
}
bool ResourceUnit::isStatusFlag10000Set() const {
return mStatusFlags.isOn(StatusFlag::_10000);
}
} // namespace ksys::res

View File

@ -25,6 +25,7 @@ class OverlayArena;
namespace ksys::res {
class Cache;
class Context;
class Handle;
class LoadRequest;
class ResourceUnit;
@ -93,11 +94,11 @@ public:
};
KSYS_CHECK_SIZE_NX150(InitArg, 0x50);
struct RequestLoadArg {
struct RequestInitLoadArg {
u8 lane_id;
bool has_handle;
};
KSYS_CHECK_SIZE_NX150(RequestLoadArg, 0x2);
KSYS_CHECK_SIZE_NX150(RequestInitLoadArg, 0x2);
explicit ResourceUnit(const InitArg& arg);
ResourceUnit();
@ -133,9 +134,21 @@ public:
bool removeTask3FromQueue();
void requestLoad(const RequestLoadArg& arg);
void requestInitLoad(const RequestInitLoadArg& arg);
bool waitForResourceAndParse(Context* context);
bool waitForTask1();
bool waitForTask1(const sead::TickSpan& span);
bool isStatusFlag1000Set() const;
void setStatusFlag10000();
bool isStatusFlag10000Set() const;
/// Destroys the underlying resource and reallocates it for defragmentation purposes.
void reallocate();
u32 determineFileBufferSize();
u32 determineFileBufferSize(const sead::SafeString& path, bool flag4, bool flag1, bool flag2);
void detachFromHandle_(Handle* handle);
static size_t getArenaUnitListNodeOffset() {
return offsetof(ResourceUnit, mArenaUnitListNode);
@ -165,22 +178,45 @@ private:
enum class StatusFlag {
HasHeap = 0x1,
_2 = 0x2,
_4 = 0x4,
_8 = 0x8,
BufferSizeIsNonZero = 0x10,
LoadFromArchive = 0x20,
LoadReqField24IsTrue = 0x40,
_80 = 0x80,
FailedMaybe = 0x100,
FileSizeIsZero = 0x200,
_400 = 0x400,
FileSizeExceedsAllocSize = 0x800,
_1000 = 0x1000,
FileOrResInstanceTooLargeForHeap = 0x2000,
LoadFailed = 0x4000,
NeedToIncrementRefCount = 0x8000,
_10000 = 0x10000,
_20000 = 0x20000,
_40000 = 0x40000,
_80000 = 0x80000,
};
void adjustHeapAndArena();
void doLoad();
void doRetryLoad();
void prepareUnload();
void initLoad(void* x = nullptr);
void prepareLoad();
void requestPrepareLoad(util::TaskPostRunResult* result, const util::TaskPostRunContext& ctx);
void unloadForSync();
void clearCacheForSync();
void unload();
void clearCache();
void requestClearCache(util::TaskPostRunResult* result, const util::TaskPostRunContext& ctx);
sead::TypedBitFlag<CacheFlag> mCacheFlags;
sead::TypedBitFlag<Flag> mFlags;
sead::TypedBitFlag<StatusFlag> mStatusFlags;

View File

@ -45,6 +45,9 @@ public:
bool init(const InitArg& arg);
void destroy();
void addSize(s32 size);
void addSize2(s32 size);
static constexpr size_t getListNodeOffset() { return offsetof(OverlayArena, mListNode); }
private:

View File

@ -74,6 +74,7 @@ class TaskRequest {
SEAD_RTTI_BASE(TaskRequest)
public:
TaskRequest() = default;
explicit TaskRequest(bool has_handle) : mHasHandle(has_handle) {}
virtual ~TaskRequest() = default;
bool mHasHandle = true;