summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem/actBaseProcHandle.cpp
diff options
context:
space:
mode:
authorPistonight <pistonknight@outlook.com>2025-05-13 11:25:39 -0700
committerPistonight <pistonknight@outlook.com>2025-05-15 11:31:51 -0700
commit81feab300b56913c624e72e8c348df93da1cdcf4 (patch)
tree3a9c5b46904701268f09f47a40c327a1a344446d /src/KingSystem/ActorSystem/actBaseProcHandle.cpp
parent47d5304c06ab48aa15073ffaaaf2efa06bbeb346 (diff)
merge BaseProcHandle and BaseProcUnit TU
Diffstat (limited to 'src/KingSystem/ActorSystem/actBaseProcHandle.cpp')
-rw-r--r--src/KingSystem/ActorSystem/actBaseProcHandle.cpp165
1 files changed, 145 insertions, 20 deletions
diff --git a/src/KingSystem/ActorSystem/actBaseProcHandle.cpp b/src/KingSystem/ActorSystem/actBaseProcHandle.cpp
index 95cfa803..bdde1c62 100644
--- a/src/KingSystem/ActorSystem/actBaseProcHandle.cpp
+++ b/src/KingSystem/ActorSystem/actBaseProcHandle.cpp
@@ -2,19 +2,15 @@
#include <prim/seadScopedLock.h>
#include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h"
#include "KingSystem/ActorSystem/actBaseProc.h"
-#include "KingSystem/ActorSystem/actBaseProcUnit.h"
-#include "KingSystem/Utils/InitTimeInfo.h"
+#include "KingSystem/Utils/Debug.h"
namespace ksys::act {
-static util::InitTimeInfo sInfo;
+BaseProcUnitPool gUnitPool{};
+BaseProcHandle gDummyProcHandle;
BaseProcHandle::BaseProcHandle() = default;
-BaseProcHandle::~BaseProcHandle() {
- deleteProc();
-}
-
bool BaseProcHandle::isProcReady() const {
return mUnit && mUnit->isReady();
}
@@ -139,29 +135,158 @@ bool BaseProcHandle::allocUnit() {
if (mUnit)
return false;
- int idx = gUnitPool.idx;
- for (int i = 0; i < gUnitPool.units.size(); ++idx, ++i) {
- idx = (idx == gUnitPool.units.size()) ? 0 : idx;
- auto* unit = gUnitPool.get(idx);
+ mUnit = gUnitPool.alloc(this);
+ if (!mUnit)
+ return false;
+
+ mUnit->setInitializingStatus();
+ return true;
+}
+
+BaseProcUnit* BaseProcUnitPool::alloc(BaseProcHandle* handle) {
+ int idx = next;
+ for (int i = 0; i < units.array.size(); ++idx, ++i) {
+ idx = (idx == units.array.size()) ? 0 : idx;
+ auto* unit = &units.array[idx];
if (!unit->getCreateTask().canSubmitRequest())
continue;
if (unit->getProc() != nullptr)
continue;
- if (!unit->compareExchangeHandle(nullptr, this))
+ if (!unit->compareExchangeHandle(nullptr, handle))
continue;
- gUnitPool.idx = idx + 1;
- mUnit = unit;
- if (!mUnit)
- return false;
+ next = idx + 1;
+ return unit;
+ }
+ return nullptr;
+}
- mUnit->setInitializingStatus();
- return true;
+BaseProcUnit::~BaseProcUnit() {
+ deleteProc(0, nullptr);
+}
+
+bool BaseProcUnit::deleteProc([[maybe_unused]] u32 x, BaseProcHandle* handle) {
+#ifdef MATCHING_HACK_NX_CLANG
+ // Ensure x is not optimized out.
+ __builtin_assume(x);
+#endif
+
+ ActorLinkConstDataAccess accessor;
+
+ {
+ const auto lock = sead::makeScopedLock(mCS);
+ BaseProcHandle* current_handle = mHandle;
+ if (current_handle == handle) {
+ if (mProc)
+ accessor.acquire(mProc);
+
+ if (mStatus == Status::Initializing || mProc) {
+ mHandle.compareExchange(handle, &gDummyProcHandle);
+ } else {
+ mStatus = Status::Unused;
+ mHandle = nullptr;
+ }
+ } else {
+ sead::FixedSafeString<256> message;
+ message.format("BaseProcUnit:(%p, %p), 呼び出し(%p)", this, current_handle, handle);
+ util::PrintDebug(message);
+ }
}
- mUnit = nullptr;
- return false;
+ if (accessor.hasProc())
+ accessor.mProc->deleteLater(BaseProc::DeleteReason::_2);
+
+ return true;
+}
+
+bool BaseProcUnit::setProc(BaseProc* proc) {
+ static constexpr const char* sStateNames[] = {"Init", "Calc", "Sleep", "Delete"};
+
+ auto lock = sead::makeScopedLock(mCS);
+
+ if (mProc)
+ mProc = nullptr;
+
+ if (isParentHandleDefault())
+ return false;
+
+ const auto print_info = [&] {
+ sead::FixedSafeString<64> message;
+ if (proc) {
+ message.format("%s, %d, %d, %s, ( %p:%p )", proc->getName().cstr(), u32(mStatus.load()),
+ proc->isInitialized(), sStateNames[u8(proc->getState())], this,
+ mHandle.load());
+ } else {
+ message.format("なし, %d, ?, ?, ( %p:%p )", u32(mStatus.load()), this, mHandle.load());
+ }
+ util::PrintDebug(message);
+ };
+
+ if (!mHandle) {
+ print_info();
+ return false;
+ }
+
+ if (mStatus != Status::Initializing)
+ print_info();
+
+ mProc = proc;
+ mStatus = Status::Ready;
+ return true;
+}
+
+void BaseProcUnit::reset() {
+ auto* handle = getHandle();
+ if (handle != &gDummyProcHandle) {
+ sead::FixedSafeString<256> message;
+ message.format("BaseProcUnit:%p, %p", this, handle);
+ util::PrintDebug(message);
+ }
+ mProc = nullptr;
+ mStatus = Status::Unused;
+ mHandle = nullptr;
+}
+
+void BaseProcUnit::cleanUp(BaseProc* proc, bool is_cancellation) {
+ const auto lock = sead::makeScopedLock(mCS);
+
+ mProc = nullptr;
+
+ const auto print_info = [&] {
+ sead::FixedSafeString<64> message;
+ message.format("%d, ( %p:%p )", u32(mStatus.load()), this, mHandle.load());
+ util::PrintDebug(message);
+ };
+
+ if (isParentHandleDefault()) {
+ reset();
+ } else if (!mHandle) {
+ print_info();
+ } else {
+ const auto status = mStatus.load();
+ if (status == Status::Unused || (status > Status::NoProc && status != Status::Cancelled))
+ print_info();
+ mStatus = is_cancellation ? Status::Cancelled : Status::NoProc;
+ }
+}
+
+void BaseProcUnit::unlinkProc(BaseProc* proc) {
+ const auto lock = sead::makeScopedLock(mCS);
+
+ if (mProc != proc && mProc != nullptr) {
+ sead::FixedSafeString<256> message;
+ message.format("BaseProcUnit:(%p:%p), BaseProc:(%s:%p), 残りBaseProc(%s:%p)", this,
+ mHandle.load(), proc->getName().cstr(), proc, mProc->getName().cstr(),
+ mProc);
+ util::PrintDebug(message);
+ }
+
+ reset();
+}
+
+bool BaseProcUnit::isParentHandleDefault() const {
+ return mHandle == &gDummyProcHandle;
}
} // namespace ksys::act