diff options
| author | Léo Lam <leo@leolam.fr> | 2025-05-15 23:47:38 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-15 23:47:38 +0100 |
| commit | 883e2da96aaceb1865e8fe7c4a8a2a5fd42df7a9 (patch) | |
| tree | 3a9c5b46904701268f09f47a40c327a1a344446d /src/KingSystem | |
| parent | 47d5304c06ab48aa15073ffaaaf2efa06bbeb346 (diff) | |
| parent | 81feab300b56913c624e72e8c348df93da1cdcf4 (diff) | |
Merge pull request #142 from Pistonight/merge_base_proc_handle_unit
Merge BaseProcHandle and BaseProcUnit TU
Diffstat (limited to 'src/KingSystem')
| -rw-r--r-- | src/KingSystem/ActorSystem/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actBaseProc.cpp | 5 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actBaseProcCreateTask.cpp | 1 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actBaseProcHandle.cpp | 165 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actBaseProcHandle.h | 72 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actBaseProcUnit.cpp | 141 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actBaseProcUnit.h | 78 |
7 files changed, 220 insertions, 244 deletions
diff --git a/src/KingSystem/ActorSystem/CMakeLists.txt b/src/KingSystem/ActorSystem/CMakeLists.txt index 2c4514ea..d956ebfa 100644 --- a/src/KingSystem/ActorSystem/CMakeLists.txt +++ b/src/KingSystem/ActorSystem/CMakeLists.txt @@ -96,8 +96,6 @@ target_sources(uking PRIVATE actBaseProcMap.h actBaseProcMgr.cpp actBaseProcMgr.h - actBaseProcUnit.cpp - actBaseProcUnit.h actCCAccessor.h actClusteredRenderer.cpp actClusteredRenderer.h diff --git a/src/KingSystem/ActorSystem/actBaseProc.cpp b/src/KingSystem/ActorSystem/actBaseProc.cpp index 528766d3..ea4f8884 100644 --- a/src/KingSystem/ActorSystem/actBaseProc.cpp +++ b/src/KingSystem/ActorSystem/actBaseProc.cpp @@ -2,14 +2,17 @@ #include <thread/seadThread.h> #include <time/seadTickSpan.h> #include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h" +#include "KingSystem/ActorSystem/actBaseProcHandle.h" #include "KingSystem/ActorSystem/actBaseProcJobHandler.h" #include "KingSystem/ActorSystem/actBaseProcLink.h" #include "KingSystem/ActorSystem/actBaseProcMgr.h" -#include "KingSystem/ActorSystem/actBaseProcUnit.h" #include "KingSystem/Terrain/teraSystem.h" +#include "KingSystem/Utils/InitTimeInfo.h" namespace ksys::act { +static util::InitTimeInfo sInfo; + BaseProc::BaseProc(const CreateArg& arg) : mName(arg.actor_name), mPriority(arg.class_info->priority) { BaseProcMgr* mgr = BaseProcMgr::instance(); diff --git a/src/KingSystem/ActorSystem/actBaseProcCreateTask.cpp b/src/KingSystem/ActorSystem/actBaseProcCreateTask.cpp index 9573ee6c..b2d623fc 100644 --- a/src/KingSystem/ActorSystem/actBaseProcCreateTask.cpp +++ b/src/KingSystem/ActorSystem/actBaseProcCreateTask.cpp @@ -1,7 +1,6 @@ #include "KingSystem/ActorSystem/actBaseProcCreateTask.h" #include "KingSystem/ActorSystem/actBaseProc.h" #include "KingSystem/ActorSystem/actBaseProcHandle.h" -#include "KingSystem/ActorSystem/actBaseProcUnit.h" #include "KingSystem/Map/mapObject.h" namespace ksys::act { 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 diff --git a/src/KingSystem/ActorSystem/actBaseProcHandle.h b/src/KingSystem/ActorSystem/actBaseProcHandle.h index 0e3f9e38..5911cb64 100644 --- a/src/KingSystem/ActorSystem/actBaseProcHandle.h +++ b/src/KingSystem/ActorSystem/actBaseProcHandle.h @@ -1,6 +1,10 @@ #pragma once #include <basis/seadTypes.h> +#include <container/seadSafeArray.h> +#include <thread/seadAtomic.h> +#include <thread/seadCriticalSection.h> +#include "KingSystem/ActorSystem/actBaseProcCreateTask.h" #include "KingSystem/Utils/Types.h" namespace ksys::act { @@ -12,7 +16,7 @@ class BaseProcUnit; class BaseProcHandle { public: BaseProcHandle(); - ~BaseProcHandle(); + ~BaseProcHandle() { deleteProc(); } BaseProcHandle(const BaseProcHandle&) = delete; BaseProcHandle(BaseProcHandle&&) = delete; @@ -42,4 +46,70 @@ private: }; KSYS_CHECK_SIZE_NX150(BaseProcHandle, 0x10); +/// Glue code between a BaseProcHandle and its associated BaseProc. +/// Used while a BaseProc is being created. +class BaseProcUnit { +public: + enum class Status : u32 { + Unused = 0, + Initializing = 1, + Ready = 2, + NoProc = 3, + _4 = 4, + Cancelled = 5, + }; + + BaseProcUnit() = default; + ~BaseProcUnit(); + + BaseProcUnit(const BaseProcUnit&) = delete; + BaseProcUnit(BaseProcUnit&&) = delete; + auto operator=(const BaseProcUnit&) = delete; + auto operator=(BaseProcUnit&&) = delete; + + bool deleteProc(u32, BaseProcHandle* handle); + bool setProc(BaseProc* proc); + void unlinkProc(BaseProc* proc); + void cleanUp(BaseProc* proc, bool is_cancellation); + bool isParentHandleDefault() const; + + Status getStatus() const { return mStatus; } + BaseProc* getProc() const { return mProc; } + BaseProcCreateTask& getCreateTask() { return mCreateTask; } + const BaseProcCreateTask& getCreateTask() const { return mCreateTask; } + sead::CriticalSection& getCS() { return mCS; } + + bool isReady() const { return mStatus == Status::Ready; } + + bool compareExchangeHandle(BaseProcHandle* expected, BaseProcHandle* desired) { + return mHandle.compareExchange(expected, desired); + } + + void setInitializingStatus() { mStatus = Status::Initializing; } + +private: + void reset(); + + BaseProcHandle* getHandle() const { return mHandle.load(); } + + sead::Atomic<Status> mStatus = Status::Unused; + sead::Atomic<BaseProcHandle*> mHandle; + BaseProc* mProc{}; + BaseProcCreateTask mCreateTask{nullptr}; + sead::CriticalSection mCS; +}; +KSYS_CHECK_SIZE_NX150(BaseProcUnit, 0x2f0); + +struct BaseProcUnitPool { + struct Impl { + sead::SafeArray<BaseProcUnit, 256> array; + } units{}; + int next = 0; + + BaseProcUnit* alloc(BaseProcHandle* handle); +}; + +extern BaseProcUnitPool gUnitPool; +extern BaseProcHandle gDummyProcHandle; + } // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actBaseProcUnit.cpp b/src/KingSystem/ActorSystem/actBaseProcUnit.cpp deleted file mode 100644 index 23baa4ea..00000000 --- a/src/KingSystem/ActorSystem/actBaseProcUnit.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include "KingSystem/ActorSystem/actBaseProcUnit.h" -#include <prim/seadSafeString.h> -#include <prim/seadScopedLock.h> -#include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h" -#include "KingSystem/ActorSystem/actBaseProc.h" -#include "KingSystem/ActorSystem/actBaseProcHandle.h" -#include "KingSystem/Utils/Debug.h" - -namespace ksys::act { - -BaseProcUnitPool gUnitPool{}; -BaseProcHandle gDummyProcHandle; - -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); - } - } - - 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 diff --git a/src/KingSystem/ActorSystem/actBaseProcUnit.h b/src/KingSystem/ActorSystem/actBaseProcUnit.h deleted file mode 100644 index 4e406b9b..00000000 --- a/src/KingSystem/ActorSystem/actBaseProcUnit.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include <basis/seadTypes.h> -#include <container/seadSafeArray.h> -#include <thread/seadAtomic.h> -#include <thread/seadCriticalSection.h> -#include "KingSystem/ActorSystem/actBaseProcCreateTask.h" - -namespace ksys::act { - -class BaseProc; -class BaseProcHandle; - -/// Glue code between a BaseProcHandle and its associated BaseProc. -/// Used while a BaseProc is being created. -class BaseProcUnit { -public: - enum class Status : u32 { - Unused = 0, - Initializing = 1, - Ready = 2, - NoProc = 3, - _4 = 4, - Cancelled = 5, - }; - - BaseProcUnit() = default; - ~BaseProcUnit(); - - BaseProcUnit(const BaseProcUnit&) = delete; - BaseProcUnit(BaseProcUnit&&) = delete; - auto operator=(const BaseProcUnit&) = delete; - auto operator=(BaseProcUnit&&) = delete; - - bool deleteProc(u32, BaseProcHandle* handle); - bool setProc(BaseProc* proc); - void unlinkProc(BaseProc* proc); - void cleanUp(BaseProc* proc, bool is_cancellation); - bool isParentHandleDefault() const; - - Status getStatus() const { return mStatus; } - BaseProc* getProc() const { return mProc; } - BaseProcCreateTask& getCreateTask() { return mCreateTask; } - const BaseProcCreateTask& getCreateTask() const { return mCreateTask; } - sead::CriticalSection& getCS() { return mCS; } - - bool isReady() const { return mStatus == Status::Ready; } - - bool compareExchangeHandle(BaseProcHandle* expected, BaseProcHandle* desired) { - return mHandle.compareExchange(expected, desired); - } - - void setInitializingStatus() { mStatus = Status::Initializing; } - -private: - void reset(); - - BaseProcHandle* getHandle() const { return mHandle.load(); } - - sead::Atomic<Status> mStatus = Status::Unused; - sead::Atomic<BaseProcHandle*> mHandle{}; - BaseProc* mProc{}; - BaseProcCreateTask mCreateTask{nullptr}; - sead::CriticalSection mCS; -}; -KSYS_CHECK_SIZE_NX150(BaseProcUnit, 0x2f0); - -struct BaseProcUnitPool { - BaseProcUnit* get(int i) { return &units[i]; } - - sead::SafeArray<BaseProcUnit, 256> units; - int idx = 0; -}; - -extern BaseProcUnitPool gUnitPool; -extern BaseProcHandle gDummyProcHandle; - -} // namespace ksys::act |
