summaryrefslogtreecommitdiff
path: root/src/KingSystem/ActorSystem
diff options
context:
space:
mode:
Diffstat (limited to 'src/KingSystem/ActorSystem')
-rw-r--r--src/KingSystem/ActorSystem/CMakeLists.txt2
-rw-r--r--src/KingSystem/ActorSystem/actBaseProc.cpp5
-rw-r--r--src/KingSystem/ActorSystem/actBaseProcCreateTask.cpp1
-rw-r--r--src/KingSystem/ActorSystem/actBaseProcHandle.cpp165
-rw-r--r--src/KingSystem/ActorSystem/actBaseProcHandle.h72
-rw-r--r--src/KingSystem/ActorSystem/actBaseProcUnit.cpp141
-rw-r--r--src/KingSystem/ActorSystem/actBaseProcUnit.h78
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