summaryrefslogtreecommitdiff
path: root/src/KingSystem/Resource
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2020-10-13 02:11:12 +0200
committerLéo Lam <leo@leolam.fr>2020-10-15 17:09:26 +0200
commitb16ba552db85d87409a610ab39fbde6670f73bde (patch)
treedb89213555787f250df86b730c6c34c11b04bbff /src/KingSystem/Resource
parent436085f61dc25a387b2c0eae0380eaf1e1aa6e12 (diff)
ksys/res: Implement all of Handle
Diffstat (limited to 'src/KingSystem/Resource')
-rw-r--r--src/KingSystem/Resource/CMakeLists.txt1
-rw-r--r--src/KingSystem/Resource/resHandle.cpp416
-rw-r--r--src/KingSystem/Resource/resHandle.h37
-rw-r--r--src/KingSystem/Resource/resInfoContainer.cpp2
-rw-r--r--src/KingSystem/Resource/resLoadRequest.cpp20
-rw-r--r--src/KingSystem/Resource/resResourceMgrTask.h10
-rw-r--r--src/KingSystem/Resource/resUnit.cpp30
-rw-r--r--src/KingSystem/Resource/resUnit.h21
8 files changed, 482 insertions, 55 deletions
diff --git a/src/KingSystem/Resource/CMakeLists.txt b/src/KingSystem/Resource/CMakeLists.txt
index 068e3f13..abf6860e 100644
--- a/src/KingSystem/Resource/CMakeLists.txt
+++ b/src/KingSystem/Resource/CMakeLists.txt
@@ -100,7 +100,6 @@ target_sources(uking PRIVATE
resHandle.h
resInfoContainer.cpp
resInfoContainer.h
- resLoadRequest.cpp
resLoadRequest.h
resMemoryTask.cpp
resMemoryTask.h
diff --git a/src/KingSystem/Resource/resHandle.cpp b/src/KingSystem/Resource/resHandle.cpp
index 1655a485..81e43aa2 100644
--- a/src/KingSystem/Resource/resHandle.cpp
+++ b/src/KingSystem/Resource/resHandle.cpp
@@ -2,8 +2,11 @@
#include <container/seadBuffer.h>
#include <prim/seadSafeString.h>
#include <time/seadTickTime.h>
+#include "KingSystem/Resource/resLoadRequest.h"
+#include "KingSystem/Resource/resResource.h"
#include "KingSystem/Resource/resResourceMgrTask.h"
#include "KingSystem/Resource/resSystem.h"
+#include "KingSystem/Utils/Debug.h"
namespace ksys::res {
@@ -40,13 +43,28 @@ const sead::SafeString sStatusStrings_[0x11] = {
};
const sead::Buffer<const sead::SafeString> sStatusStrings{0x11, sStatusStrings_};
+ILoadRequest::~ILoadRequest() {
+ ;
+}
+
+LoadRequest::LoadRequest() = default;
+
+LoadRequest::LoadRequest(s32 load_data_alignment, u32 arg_c, bool arg_20)
+ : _20(arg_20), mLoadDataAlignment(load_data_alignment) {
+ _c = arg_c;
+}
+
+SimpleLoadRequest::SimpleLoadRequest() = default;
+
+SimplePackedLoadRequest::SimplePackedLoadRequest() = default;
+
Handle::Handle() = default;
Handle::~Handle() {
- unload();
+ requestUnload();
}
-void Handle::unload() {
+void Handle::requestUnload() {
if (!mFlags.isOn(Flag::_2))
return;
@@ -69,4 +87,398 @@ void Handle::unload() {
ResourceMgrTask::instance()->requestUnload(this);
}
+sead::DirectResource* Handle::getResource() const {
+ if (!isSuccess())
+ return nullptr;
+ return mUnit->mResource;
+}
+
+bool Handle::isSuccess() const {
+ if (mFlags.isOff(Flag::_2))
+ return false;
+
+ if (isBusy())
+ return false;
+
+ if (!mUnit || !mUnit->isParseOk())
+ return false;
+
+ return true;
+}
+
+sead::DirectResource* Handle::getResourceUnchecked() const {
+ return mUnit->mResource;
+}
+
+Handle::Status Handle::getStatus() const {
+ return mStatus;
+}
+
+void Handle::setStatusForResourceMgr_(const Status& status) {
+ mStatus = status;
+}
+
+inline bool Handle::checkPathChange_(const sead::SafeString& path) {
+ if (!mFlags.isOn(Flag::_2))
+ return true;
+
+ stubbedLogFunction();
+ sead::FormatFixedSafeString<512> message("↓↓↓\n前回ファイル:%s\n今回ファイル:%s\n↑↑↑\n",
+ mUnit ? mUnit->mPath.cstr() : "***", path.cstr());
+ util::PrintDebug(message);
+ return false;
+}
+
+sead::DirectResource* Handle::load(const sead::SafeString& path, const ILoadRequest* request,
+ Handle::Status* out_status) {
+ if (checkPathChange_(path)) {
+ mFlags.reset(Flag::_F);
+ mFlags.set(Flag::_2);
+ mStatus = Status::_0;
+ if (request) {
+ ResourceMgrTask::instance()->requestLoadForSync(this, path, *request);
+ } else {
+ LoadRequest temp_request;
+ ResourceMgrTask::instance()->requestLoadForSync(this, path, temp_request);
+ }
+ if (out_status)
+ *out_status = mStatus;
+ } else {
+ if (out_status)
+ *out_status = Status::_8;
+ }
+
+ return getResource();
+}
+
+bool Handle::isFlag2Set() const {
+ return mFlags.isOn(Flag::_2);
+}
+
+bool Handle::requestLoad(const sead::SafeString& path, const ILoadRequest* request,
+ Handle::Status* out_status) {
+ if (checkPathChange_(path)) {
+ mFlags.reset(Flag::_F);
+ mFlags.set(Flag::_2);
+ mStatus = Status::_0;
+
+ Handle::Status ret;
+ if (request) {
+ ret = ResourceMgrTask::instance()->requestLoad(this, path, *request);
+ } else {
+ LoadRequest temp_request;
+ ret = ResourceMgrTask::instance()->requestLoad(this, path, temp_request);
+ }
+
+ if (out_status)
+ *out_status = ret;
+
+ return ret == Status::_7;
+ }
+
+ if (out_status)
+ *out_status = Status::_8;
+
+ return false;
+}
+
+bool Handle::waitForReady() {
+ if (mTaskHandle.isTaskAttached())
+ mTaskHandle.wait();
+
+ if (mUnit)
+ mUnit->waitForTask1();
+
+ return true;
+}
+
+bool Handle::waitForReady(const sead::TickSpan& span) {
+ if (mTaskHandle.isTaskAttached() && !mTaskHandle.wait(span))
+ return false;
+
+ if (mUnit && !mUnit->waitForTask1(span))
+ return false;
+
+ return true;
+}
+
+bool Handle::parseResource(Context* context) {
+ if (mFlags.isOn(Flag::_8))
+ return true;
+
+ if (mFlags.isOn(Flag::_4))
+ return false;
+
+ if (mTaskHandle.getStatus() == util::ManagedTaskHandle::Status::TaskRemoved ||
+ (mUnit && mUnit->isTask1NotQueued())) {
+ stubbedLogFunction();
+ mStatus = Status::_14;
+ updateResourceMgrFlag_();
+ requestUnload();
+ mFlags.set(Flag::_8);
+ return true;
+ }
+
+ if (mStatus == Status::_1 || mStatus == Status::_2 || mStatus == Status::_3 ||
+ mStatus == Status::_8 || mStatus == Status::_9 || mStatus == Status::_10 ||
+ mStatus == Status::_11 || mStatus == Status::_12 || mStatus == Status::_13 ||
+ mStatus == Status::_14) {
+ updateResourceMgrFlag_();
+ requestUnload();
+ mFlags.set(Flag::_8);
+ return true;
+ }
+
+ if (mStatus == Status::_0)
+ return false;
+
+ if (!mUnit) {
+ stubbedLogFunction();
+ return false;
+ }
+
+ switch (mUnit->getStatus()) {
+ case ResourceUnit::Status::_0:
+ case ResourceUnit::Status::_7:
+ return false;
+ case ResourceUnit::Status::_8:
+ case ResourceUnit::Status::_10:
+ case ResourceUnit::Status::_11:
+ case ResourceUnit::Status::_13:
+ waitForResourceAndParse_(context);
+ break;
+ case ResourceUnit::Status::_9:
+ updateStatusAndUnload_();
+ break;
+ case ResourceUnit::Status::_12:
+ case ResourceUnit::Status::_15:
+ mStatus = Status::_9;
+ updateResourceMgrFlag_();
+ requestUnload();
+ mFlags.set(Flag::_8);
+ return true;
+ case ResourceUnit::Status::_14:
+ if (mStatus == Status::_7)
+ mStatus = Status::_4;
+ updateResourceMgrFlag_();
+ break;
+ default:
+ break;
+ }
+
+ mFlags.set(Flag::_8);
+ return true;
+}
+
+bool Handle::isFlag8Set() const {
+ return mFlags.isOn(Flag::_8);
+}
+
+// NON_MATCHING: switch
+void Handle::updateResourceMgrFlag_() {
+ sead::FixedSafeString<128> path("***");
+ if (mUnit)
+ path = mUnit->mPath;
+
+ bool warn = true;
+ switch (mStatus) {
+ case Status::_3:
+ if (!mUnit || !mUnit->mArena1->isFlag1Set())
+ break;
+ if (!returnFalse())
+ warn = false;
+ break;
+ case Status::_4:
+ static_cast<void>(static_cast<volatile ResourceUnit*>(mUnit)->mStatusFlags);
+ if (!returnFalse())
+ warn = false;
+ break;
+ case Status::_5:
+ case Status::_6:
+ case Status::_8:
+ if (!returnFalse())
+ warn = false;
+ break;
+ default:
+ break;
+ }
+
+ if (warn)
+ stubbedLogFunction();
+
+ if (mStatus != Status::_3 || !mUnit || !mUnit->mArena1)
+ return;
+
+ auto* heap = mUnit->mArena1->getHeap();
+
+ if (!mUnit->mArena1->isFlag1Set() || returnFalse())
+ stubbedLogFunction();
+
+ if (!mUnit->mArena1->isFlag10Set())
+ return;
+
+ const s32 type =
+ (heap->getName().startsWith("Sound") || heap->getName().startsWith("Audio")) ? 0 : 1;
+ res::ResourceMgrTask::instance()->setFlag2000Or5000(type);
+}
+
+void Handle::updateStatusAndUnload_() {
+ auto* unit = mUnit;
+ if (unit && unit->isStatus9_12_15()) {
+ mStatus = [&] {
+ if (unit->mStatusFlags.isOn(ResourceUnit::StatusFlag::FailedMaybe))
+ return Status::_1;
+ if (unit->mStatusFlags.isOn(ResourceUnit::StatusFlag::FileSizeIsZero))
+ return Status::_2;
+ if (unit->mStatusFlags.isOn(ResourceUnit::StatusFlag::_400))
+ return Status::_9;
+ if (unit->mStatusFlags.isOn(ResourceUnit::StatusFlag::FileSizeExceedsAllocSize))
+ return Status::_10;
+ if (unit->mStatusFlags.isOn(ResourceUnit::StatusFlag::_1000))
+ return Status::_11;
+ if (unit->mStatusFlags.isOn(ResourceUnit::StatusFlag::FileOrResInstanceTooLargeForHeap))
+ return Status::_12;
+ if (unit->mStatusFlags.isOn(ResourceUnit::StatusFlag::LoadFailed))
+ return Status::_13;
+
+#ifdef MATCHING_HACK_NX_CLANG
+ asm("");
+#endif
+ return Status::_3;
+ }();
+ }
+ updateResourceMgrFlag_();
+ requestUnload();
+}
+
+void Handle::requestUnload2() {
+ requestUnload();
+}
+
+void Handle::unload() {
+ if (!mFlags.isOn(Flag::_2))
+ return;
+
+ mFlags.reset(Flag::_7);
+ mFlags.set(Flag::_4);
+
+ if (mTaskHandle.hasTask()) {
+ mTaskHandle.removeTaskFromQueue();
+ if (!mUnit) {
+ stubbedLogFunction();
+ mStatus = Status::_14;
+ return;
+ }
+ }
+
+ if (mUnit)
+ ResourceMgrTask::instance()->requestUnloadForSync(this);
+}
+
+void Handle::unloadAndResetUnitFlag20000() {
+ if (!mFlags.isOn(Flag::_2))
+ return;
+
+ mFlags.reset(Flag::_7);
+ mFlags.set(Flag::_4);
+
+ if (mTaskHandle.hasTask()) {
+ mTaskHandle.removeTaskFromQueue();
+ if (!mUnit) {
+ stubbedLogFunction();
+ mStatus = Status::_14;
+ return;
+ }
+ }
+
+ ResourceUnit* unit = mUnit;
+ if (!unit)
+ return;
+
+ stubbedLogFunction();
+ unit->mStatusFlags.reset(ResourceUnit::StatusFlag::_20000);
+ ResourceMgrTask::instance()->requestUnloadForSync(this);
+}
+
+void Handle::resetUnitFlag20000IfSuccess() {
+ if (mFlags.isOff(Flag::_2))
+ return;
+
+ ResourceUnit* unit = mUnit;
+
+ if (isBusy())
+ return;
+
+ if (!mUnit || !mUnit->isParseOk())
+ return;
+
+ if (unit)
+ unit->mStatusFlags.reset(ResourceUnit::StatusFlag::_20000);
+}
+
+bool Handle::isBusy() const {
+ if (mTaskHandle.isTaskAttached())
+ return true;
+
+ if (mFlags.isOn(Flag::_2) && mUnit)
+ return mUnit->isTask1ActiveOrStatus7();
+
+ return false;
+}
+
+bool Handle::isReadyOrNeedsParse() const {
+ if ((mFlags.getDirect() & 0xA) != u32(Flag::_2) || isBusy())
+ return false;
+
+ if (isReady())
+ return true;
+
+ return mUnit && mUnit->needsParse();
+}
+
+bool Handle::isReady() const {
+ if (isSuccess())
+ return true;
+
+ return checkLoadStatus();
+}
+
+bool Handle::checkLoadStatus() const {
+ if (isBusy())
+ return false;
+
+ bool ok = false;
+ if (mFlags.isOn(Flag::_2) && mUnit)
+ ok = mUnit->isStatus9_12_15();
+
+ ok |= mStatus == Status::_1 || mStatus == Status::_2 || mStatus == Status::_3 ||
+ mStatus == Status::_8 || mStatus == Status::_9 || mStatus == Status::_10 ||
+ mStatus == Status::_11 || mStatus == Status::_12 || mStatus == Status::_13 ||
+ mStatus == Status::_14;
+
+ return ok;
+}
+
+sead::SafeString Handle::makeEmptyString() {
+ return sead::SafeString::cEmptyString;
+}
+
+void Handle::waitForResourceAndParse_(Context* context) {
+ if (!mUnit) {
+ updateResourceMgrFlag_();
+ return;
+ }
+
+ if (mUnit->waitForResourceAndParse(context)) {
+ if (mStatus == Status::_7)
+ mStatus = Status::_4;
+ updateResourceMgrFlag_();
+ return;
+ }
+
+ mStatus = Status::_9;
+ updateResourceMgrFlag_();
+ requestUnload();
+}
+
} // namespace ksys::res
diff --git a/src/KingSystem/Resource/resHandle.h b/src/KingSystem/Resource/resHandle.h
index c025a278..45d6af0b 100644
--- a/src/KingSystem/Resource/resHandle.h
+++ b/src/KingSystem/Resource/resHandle.h
@@ -13,6 +13,7 @@ class DirectResource;
namespace ksys::res {
+class Context;
class ILoadRequest;
class ResourceUnit;
@@ -43,15 +44,42 @@ public:
Status getStatus() const;
- sead::DirectResource* load(const sead::SafeString& path, const ILoadRequest& request,
+ sead::DirectResource* getResource() const;
+ bool isSuccess() const;
+ sead::DirectResource* getResourceUnchecked() const;
+
+ sead::DirectResource* load(const sead::SafeString& path, const ILoadRequest* request,
Status* out_status = nullptr);
+ bool isFlag2Set() const;
+ bool requestLoad(const sead::SafeString& path, const ILoadRequest* request,
+ Status* out_status = nullptr);
+
+ bool waitForReady();
+ bool waitForReady(const sead::TickSpan& span);
+ bool parseResource(Context* context);
+ bool isFlag8Set() const;
+
+ void requestUnload();
void unload();
+ // TODO: how does this differ?
+ void requestUnload2();
+ void unloadAndResetUnitFlag20000();
+ void resetUnitFlag20000IfSuccess();
+
+ bool isBusy() const;
+ bool isReadyOrNeedsParse() const;
+ bool isReady() const;
+ bool checkLoadStatus() const;
+
+ sead::SafeString makeEmptyString();
void setUnit(ResourceUnit* unit) { mUnit = unit; }
bool isLinked() const { return mListNode.isLinked(); }
+ void setStatusForResourceMgr_(const Status& status);
+
static size_t getListNodeOffset() { return offsetof(Handle, mListNode); }
private:
@@ -61,8 +89,15 @@ private:
_4 = 0x4,
_7 = 0x7,
_8 = 0x8,
+ _F = 0xF,
};
+ void updateResourceMgrFlag_();
+ void updateStatusAndUnload_();
+ void waitForResourceAndParse_(Context* context);
+
+ inline bool checkPathChange_(const sead::SafeString& path);
+
sead::TypedBitFlag<Flag> mFlags = Flag::_1;
Status mStatus = Status::_0;
ResourceUnit* mUnit = nullptr;
diff --git a/src/KingSystem/Resource/resInfoContainer.cpp b/src/KingSystem/Resource/resInfoContainer.cpp
index 00bf40b9..204e9dd7 100644
--- a/src/KingSystem/Resource/resInfoContainer.cpp
+++ b/src/KingSystem/Resource/resInfoContainer.cpp
@@ -34,7 +34,7 @@ bool ResourceInfoContainer::loadResourceSizeTable() {
req.mRequester = "ResourceInfoContainer";
req.mPath = "System/Resource/ResourceSizeTable.product.rsizetable";
req._c = 1;
- return sead::DynamicCast<Resource>(mRstbHandle.load(req.mPath, req));
+ return sead::DynamicCast<Resource>(mRstbHandle.load(req.mPath, &req));
};
const Resource* resource = load_res();
diff --git a/src/KingSystem/Resource/resLoadRequest.cpp b/src/KingSystem/Resource/resLoadRequest.cpp
deleted file mode 100644
index e8e2181f..00000000
--- a/src/KingSystem/Resource/resLoadRequest.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "KingSystem/Resource/resLoadRequest.h"
-
-namespace ksys::res {
-
-ILoadRequest::~ILoadRequest() {
- ;
-}
-
-LoadRequest::LoadRequest() = default;
-
-LoadRequest::LoadRequest(s32 load_data_alignment, u32 arg_c, bool arg_20)
- : _20(arg_20), mLoadDataAlignment(load_data_alignment) {
- _c = arg_c;
-}
-
-SimpleLoadRequest::SimpleLoadRequest() = default;
-
-SimplePackedLoadRequest::SimplePackedLoadRequest() = default;
-
-} // namespace ksys::res
diff --git a/src/KingSystem/Resource/resResourceMgrTask.h b/src/KingSystem/Resource/resResourceMgrTask.h
index 2544c8e1..df1117e9 100644
--- a/src/KingSystem/Resource/resResourceMgrTask.h
+++ b/src/KingSystem/Resource/resResourceMgrTask.h
@@ -137,11 +137,13 @@ public:
bool isFlag4Set() const;
- s32 requestLoad(Handle* handle, const sead::SafeString& path, const ILoadRequest& request);
+ Handle::Status requestLoad(Handle* handle, const sead::SafeString& path,
+ const ILoadRequest& request);
void addSExtensionPrefix(sead::StringBuilder& builder) const;
- s32 requestLoadForSync(Handle* handle, const sead::SafeString& path,
- const ILoadRequest& request);
- s32 requestUnload(Handle* handle);
+ Handle::Status requestLoadForSync(Handle* handle, const sead::SafeString& path,
+ const ILoadRequest& request);
+ void requestUnload(Handle* handle);
+ void requestUnloadForSync(Handle* handle);
void registerUnit(ResourceUnit* unit);
void deregisterUnit(ResourceUnit* unit);
diff --git a/src/KingSystem/Resource/resUnit.cpp b/src/KingSystem/Resource/resUnit.cpp
index a93e5266..ee252d84 100644
--- a/src/KingSystem/Resource/resUnit.cpp
+++ b/src/KingSystem/Resource/resUnit.cpp
@@ -50,7 +50,7 @@ bool ResourceUnit::init(const ResourceUnit::InitArg& arg) {
request.mRequester = "ResourceUnit";
request._c = 2;
request.mPack = arg.load_req->mPackHandle;
- mArchiveRes = sead::DynamicCast<sead::ArchiveRes>(mArchiveResHandle.load("", request));
+ mArchiveRes = sead::DynamicCast<sead::ArchiveRes>(mArchiveResHandle.load("", &request));
}
mMapNode.key().setKey(mPath);
@@ -123,7 +123,7 @@ ResourceUnit::~ResourceUnit() {
void ResourceUnit::unloadArchiveRes() {
if (mArchiveRes) {
mArchiveRes = nullptr;
- mArchiveResHandle.unload();
+ mArchiveResHandle.requestUnload();
}
}
@@ -141,11 +141,16 @@ ResourceUnit::Status ResourceUnit::getStatus() const {
return mStatus;
}
+static const ResourceUnit::Status sUnitStatusTransitionTable[] = {
+ ResourceUnit::Status::_8, ResourceUnit::Status::_11, ResourceUnit::Status::_11,
+ ResourceUnit::Status::_14, ResourceUnit::Status::_14,
+};
+
// NON_MATCHING: ldr + sxtw -> ldrsw
void ResourceUnit::updateStatus() {
- static const Status sMap[] = {Status::_8, Status::_11, Status::_11, Status::_14, Status::_14};
- if (Status::_2 <= mStatus && mStatus <= Status::_6)
- mStatus = sMap[s32(mStatus)];
+ const s32 idx = mStatus;
+ if (Status::_2 <= idx && idx <= Status::_6)
+ mStatus = sUnitStatusTransitionTable[idx];
}
bool ResourceUnit::isTask1NotQueued() const {
@@ -168,6 +173,13 @@ bool ResourceUnit::isStatus1() const {
return mStatus == Status::_1;
}
+bool ResourceUnit::needsParse() const {
+ auto* res = sead::DynamicCast<Resource>(mResource);
+ if (mStatus != Status::_8 && mStatus != Status::_11)
+ return false;
+ return res && res->needsParse();
+}
+
bool ResourceUnit::isStatus9_12_15() const {
return mStatus == Status::_9 || mStatus == Status::_12 || mStatus == Status::_15;
}
@@ -176,13 +188,15 @@ bool ResourceUnit::isStatus9_12_15() const {
bool ResourceUnit::isParseOk() const {
auto* ksys_res = sead::DynamicCast<res::Resource>(mResource);
- if (mStatus == Status::_14)
+ const auto status = mStatus.value();
+
+ if (status == Status::_14)
return true;
- if (mStatus == Status::_8 && !ksys_res)
+ if (status == Status::_8 && !ksys_res)
return mResource != nullptr;
- if (mStatus == Status::_8 && ksys_res)
+ if (status == Status::_8 && ksys_res)
return !ksys_res->needsParse();
return false;
diff --git a/src/KingSystem/Resource/resUnit.h b/src/KingSystem/Resource/resUnit.h
index 20e6f85e..8cbfa907 100644
--- a/src/KingSystem/Resource/resUnit.h
+++ b/src/KingSystem/Resource/resUnit.h
@@ -2,6 +2,7 @@
#include <KingSystem/Utils/StrTreeMap.h>
#include <hostio/seadHostIONode.h>
+#include <prim/seadEnum.h>
#include <prim/seadRuntimeTypeInfo.h>
#include <prim/seadSafeString.h>
#include <prim/seadTypedBitFlag.h>
@@ -48,24 +49,7 @@ private:
class ResourceUnit : public sead::hostio::Node {
SEAD_RTTI_BASE(ResourceUnit)
public:
- enum class Status {
- _0 = 0,
- _1 = 1,
- _2 = 2,
- _3 = 3,
- _4 = 4,
- _5 = 5,
- _6 = 6,
- _7 = 7,
- _8 = 8,
- _9 = 9,
- _10 = 10,
- _11 = 11,
- _12 = 12,
- _13 = 13,
- _14 = 14,
- _15 = 15,
- };
+ SEAD_ENUM(Status, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15)
struct InitArg {
InitArg() = default;
@@ -119,6 +103,7 @@ public:
bool isStatus0() const;
bool isTask1ActiveOrStatus7() const;
bool isStatus1() const;
+ bool needsParse() const;
bool isStatus9_12_15() const;
bool isParseOk() const;
bool isStatusFlag8000Set() const;