diff options
Diffstat (limited to 'src/KingSystem/ActorSystem/actBaseProcHandle.h')
| -rw-r--r-- | src/KingSystem/ActorSystem/actBaseProcHandle.h | 72 |
1 files changed, 71 insertions, 1 deletions
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 |
