From 113cc3bb53cacf51a7beab9c0c0d7056b9358a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 13 Mar 2021 15:42:45 +0100 Subject: [PATCH] ksys/act: Finish BaseProcUnit --- data/uking_functions.csv | 8 +- .../ActorSystem/actActorLinkConstDataAccess.h | 1 + .../ActorSystem/actBaseProcUnit.cpp | 126 ++++++++++++++---- src/KingSystem/ActorSystem/actBaseProcUnit.h | 28 +++- 4 files changed, 124 insertions(+), 39 deletions(-) diff --git a/data/uking_functions.csv b/data/uking_functions.csv index df160d8a..80ef2ff4 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -91741,15 +91741,15 @@ 0x00000071011bb924,BaseProcHandle::x,52, 0x00000071011bb958,BaseProcHandle::deleteActor,112, 0x00000071011bb9c8,BaseProcHandle::dtor,56,_ZN4ksys3act14BaseProcHandleD1Ev -0x00000071011bba00,BaseProcUnit::deleteActor,316, +0x00000071011bba00,BaseProcUnit::deleteActor,316,_ZN4ksys3act12BaseProcUnit10deleteProcEjPNS0_14BaseProcHandleE 0x00000071011bbb3c,BaseProcHandle::getActor,24,_ZN4ksys3act14BaseProcHandle7getProcEv 0x00000071011bbb54,BaseProcHandle::setProcStateFlag8000,184, 0x00000071011bbc0c,BaseProcHandle::wakeUpActorAndReleaseUnit,184, 0x00000071011bbcc4,BaseProcHandle::getBaseProcEvent,48, 0x00000071011bbcf4,BaseProcHandle::allocUnit,228, -0x00000071011bbdd8,BaseProcUnit::setActor,540,_ZN4ksys3act12BaseProcUnit7setProcEPNS0_8BaseProcE! -0x00000071011bbff4,BaseProcUnit::cleanUp,512, -0x00000071011bc1f4,BaseProcUnit::unlinkActor,412, +0x00000071011bbdd8,BaseProcUnit::setActor,540,_ZN4ksys3act12BaseProcUnit7setProcEPNS0_8BaseProcE +0x00000071011bbff4,BaseProcUnit::cleanUp,512,_ZN4ksys3act12BaseProcUnit7cleanUpEPNS0_8BaseProcEb +0x00000071011bc1f4,BaseProcUnit::unlinkActor,412,_ZN4ksys3act12BaseProcUnit10unlinkProcEPNS0_8BaseProcE 0x00000071011bc390,BaseProcUnit::isParentHandleDefault,24,_ZNK4ksys3act12BaseProcUnit21isParentHandleDefaultEv 0x00000071011bc3a8,sub_71011BC3A8,132, 0x00000071011bc42c,sub_71011BC42C,56, diff --git a/src/KingSystem/ActorSystem/actActorLinkConstDataAccess.h b/src/KingSystem/ActorSystem/actActorLinkConstDataAccess.h index 27b39190..c608f9ba 100644 --- a/src/KingSystem/ActorSystem/actActorLinkConstDataAccess.h +++ b/src/KingSystem/ActorSystem/actActorLinkConstDataAccess.h @@ -39,6 +39,7 @@ public: protected: friend class ActorConstDataAccess; friend class BaseProc; + friend class BaseProcUnit; bool mAcquired = false; BaseProc* mProc = nullptr; diff --git a/src/KingSystem/ActorSystem/actBaseProcUnit.cpp b/src/KingSystem/ActorSystem/actBaseProcUnit.cpp index b0b466b2..cac5c864 100644 --- a/src/KingSystem/ActorSystem/actBaseProcUnit.cpp +++ b/src/KingSystem/ActorSystem/actBaseProcUnit.cpp @@ -8,48 +8,118 @@ namespace ksys::act { -// NON_MATCHING: Equivalent but branches are off. +bool BaseProcUnit::deleteProc(u32, BaseProcHandle* handle) { + ActorLinkConstDataAccess accessor; + + { + const auto lock = sead::makeScopedLock(mCS); + BaseProcHandle* current_handle = mHandle; + if (current_handle == handle) { + if (mProc) + accessor.acquire(mProc); + + if (mStatus == Status::_1 || mProc) { + mHandle.compareExchange(handle, &BaseProcHandle::sDummyHandle); + } else { + mStatus = Status::Unused; + mHandle = nullptr; + } + } else { + sead::FixedSafeString<256> message; + message.format("BaseProcUnit:(%p, %p), 呼び出し(%p)", this, current_handle, handle); + util::PrintDebug(message); + } + } + + if (accessor.hasProc()) + accessor.mProc->deleteLater(BaseProc::DeleteReason::_2); + + return true; +} + bool BaseProcUnit::setProc(BaseProc* proc) { - bool ret; static constexpr const char* sStateNames[] = {"Init", "Calc", "Sleep", "Delete"}; auto lock = sead::makeScopedLock(mCS); + if (mProc) mProc = nullptr; - if (mHandle == &BaseProcHandle::sDummyHandle) + if (isParentHandleDefault()) return false; - if (mHandle) { - if (mFlags != 1) { - sead::FixedSafeString<64> message; - - if (proc) - message.format("%s, %d, %d, %s, ( %p:%p )", proc->getName().cstr(), mFlags, - proc->isInitialized(), sStateNames[u8(proc->getState())], this, - mHandle.load()); - else - message.format("なし, %d, ?, ?, ( %p:%p )", mFlags, this, mHandle.load()); - - util::PrintDebug(message); - } - mProc = proc; - mFlags = 2; - ret = true; - } else { + const auto print_info = [&] { sead::FixedSafeString<64> message; - - if (proc) - message.format("%s, %d, %d, %s, ( %p:%p )", proc->getName().cstr(), mFlags, + 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 )", mFlags, this, mHandle.load()); - + } else { + message.format("なし, %d, ?, ?, ( %p:%p )", u32(mStatus.load()), this, mHandle.load()); + } util::PrintDebug(message); - ret = false; + }; + + if (!mHandle) { + print_info(); + return false; } - return ret; + + if (mStatus != Status::_1) + print_info(); + + mProc = proc; + mStatus = Status::Ready; + return true; +} + +void BaseProcUnit::reset() { + auto* handle = getHandle(); + if (handle != &BaseProcHandle::sDummyHandle) { + 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 set_status_5) { + 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::_3 && status != Status::_5)) + print_info(); + mStatus = set_status_5 ? Status::_5 : Status::_3; + } +} + +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 { diff --git a/src/KingSystem/ActorSystem/actBaseProcUnit.h b/src/KingSystem/ActorSystem/actBaseProcUnit.h index 06045e1a..20309485 100644 --- a/src/KingSystem/ActorSystem/actBaseProcUnit.h +++ b/src/KingSystem/ActorSystem/actBaseProcUnit.h @@ -3,6 +3,7 @@ #include #include #include +#include "KingSystem/ActorSystem/actBaseProcCreateTask.h" namespace ksys::act { @@ -14,19 +15,32 @@ public: bool deleteProc(u32, BaseProcHandle* handle); bool setProc(BaseProc* proc); void unlinkProc(BaseProc* proc); - void cleanUp(BaseProc* proc, bool set_flag_5); + void cleanUp(BaseProc* proc, bool set_status_5); bool isParentHandleDefault() const; BaseProc* getProc() const { return mProc; } - bool isReady() const { return mFlags == 2; } + bool isReady() const { return mStatus == Status::Ready; } private: - u32 mFlags; - sead::Atomic mHandle; - BaseProc* mProc; - // FIXME: - // BaseProcRequest mRequest; + enum class Status : u32 { + Unused = 0, + _1 = 1, + Ready = 2, + _3 = 3, + _4 = 4, + _5 = 5, + }; + + void reset(); + + BaseProcHandle* getHandle() const { return mHandle.load(); } + + sead::Atomic mStatus = Status::Unused; + sead::Atomic mHandle{}; + BaseProc* mProc{}; + BaseProcCreateTask mCreateTask; sead::CriticalSection mCS; }; +KSYS_CHECK_SIZE_NX150(BaseProcUnit, 0x2f0); } // namespace ksys::act