summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-03-12 17:19:34 +0100
committerLéo Lam <leo@leolam.fr>2021-03-12 18:53:02 +0100
commitd072fcf7da93fcd03a10a169ac3e10476191916e (patch)
treec51e8152885bfbfedf60a020483fe612952015e0 /src
parentea79008db6ce92fb3a06ee60410ef92e62a3b96a (diff)
ksys/act: Start adding BaseProcCreateTask
Diffstat (limited to 'src')
-rw-r--r--src/KingSystem/ActorSystem/CMakeLists.txt2
-rw-r--r--src/KingSystem/ActorSystem/actBaseProc.h4
-rw-r--r--src/KingSystem/ActorSystem/actBaseProcCreateTask.cpp83
-rw-r--r--src/KingSystem/ActorSystem/actBaseProcCreateTask.h95
-rw-r--r--src/KingSystem/ActorSystem/actBaseProcHandle.h1
-rw-r--r--src/KingSystem/ActorSystem/actInstParamPack.h3
-rw-r--r--src/KingSystem/Map/mapObject.h2
7 files changed, 190 insertions, 0 deletions
diff --git a/src/KingSystem/ActorSystem/CMakeLists.txt b/src/KingSystem/ActorSystem/CMakeLists.txt
index cd6b64e9..f0448d05 100644
--- a/src/KingSystem/ActorSystem/CMakeLists.txt
+++ b/src/KingSystem/ActorSystem/CMakeLists.txt
@@ -52,6 +52,8 @@ target_sources(uking PRIVATE
actAttention.h
actBaseProc.cpp
actBaseProc.h
+ actBaseProcCreateTask.cpp
+ actBaseProcCreateTask.h
actBaseProcDeleter.cpp
actBaseProcDeleter.h
actBaseProcHandle.cpp
diff --git a/src/KingSystem/ActorSystem/actBaseProc.h b/src/KingSystem/ActorSystem/actBaseProc.h
index 34847d13..db4fa76d 100644
--- a/src/KingSystem/ActorSystem/actBaseProc.h
+++ b/src/KingSystem/ActorSystem/actBaseProc.h
@@ -134,6 +134,10 @@ public:
/// Actually pre-delete the actor. Called from BaseProcDeleter.
void doPreDelete(const PreDeleteArg& arg);
+ /// Set the BaseProcUnit. Only for use by BaseProcCreateTask.
+ void setUnitForBaseProcCreateTask(BaseProcUnit* unit) { mProcUnit = unit; }
+ void setInitializedFlag() { mFlags.set(Flags::Initialized); }
+
protected:
friend class BaseProcLinkDataMgr;
friend class BaseProcMgr;
diff --git a/src/KingSystem/ActorSystem/actBaseProcCreateTask.cpp b/src/KingSystem/ActorSystem/actBaseProcCreateTask.cpp
new file mode 100644
index 00000000..e69b0cb6
--- /dev/null
+++ b/src/KingSystem/ActorSystem/actBaseProcCreateTask.cpp
@@ -0,0 +1,83 @@
+#include "KingSystem/ActorSystem/actBaseProcCreateTask.h"
+#include "KingSystem/ActorSystem/actBaseProcHandle.h"
+#include "KingSystem/ActorSystem/actBaseProcUnit.h"
+#include "KingSystem/Map/mapObject.h"
+
+namespace ksys::act {
+
+BaseProcCreateTask::BaseProcCreateTask(sead::Heap* heap) : ManagedTask(heap) {}
+
+bool BaseProcCreateTask::onTaskDelegateInvoked(void*) {
+ BaseProcCreateArg arg;
+ arg.heap = mHeap;
+ arg.heap2 = arg.heap;
+ arg.proc_class = mClass;
+ arg.proc_name = mName;
+ mDistanceToLoadSphere = -1.0;
+ arg.params = mParams.getNumParams() != 0 ? &mParams : nullptr;
+ arg.mubin_iter = mMubinIter.isValid() ? &mMubinIter : nullptr;
+ arg.map_object = mMapObject;
+ arg.proc_link = mLink;
+ mLink.reset();
+ static_cast<void>(arg.heap2->getMaxAllocatableSize(sizeof(void*)));
+
+ BaseProc* proc = mCreateDelegate->invoke(arg);
+ if (proc) {
+ proc->setUnitForBaseProcCreateTask(mUnit);
+
+ if (proc->isDeletedOrDeleting() || !proc->init(arg.heap2, false))
+ onBaseProcCreationFailed(proc, false);
+
+ proc->setInitializedFlag();
+ } else {
+ onBaseProcCreationFailed(proc, false);
+ }
+
+ return true;
+}
+
+void BaseProcCreateTask::onBaseProcCreationFailed(BaseProc* proc, bool set_flag_5) {
+ if (mMapObject)
+ mMapObject->onBaseProcCreated(proc);
+
+ if (!proc && mUnit) {
+ mUnit->cleanUp(proc, set_flag_5);
+ mUnit = nullptr;
+ }
+}
+
+void BaseProcCreateTask::doPrepare(const BaseProcCreateTaskData* arg) {
+ auto data = sead::DynamicCast<const BaseProcCreateTaskData>(arg);
+ [&] {
+ mHeap = data->mHeap;
+ mClass = data->mProcClass;
+ mName = data->mProcName;
+
+ if (data->mMubinIter)
+ mMubinIter = *data->mMubinIter;
+ else
+ mMubinIter = {};
+
+ mMapObject = data->mMapObject;
+
+ if (data->mParams && data->mParams->getNumParams() != 0)
+ mParams = *data->mParams;
+ else
+ mParams.clearFast();
+
+ mCreateDelegate = data->mCreateDelegate;
+ mUnit = data->mProcHandle ? data->mProcHandle->getUnit() : nullptr;
+
+ if (data->mOtherProc)
+ mLink.acquire(data->mOtherProc, false);
+ else
+ mLink.reset();
+ }();
+}
+
+void BaseProcCreateTask::prepareImpl_(util::TaskRequest* req) {
+ doPrepare(sead::DynamicCast<BaseProcCreateTaskRequest>(req)->mData);
+ setDelegateInternal_(&mTaskDelegate);
+}
+
+} // namespace ksys::act
diff --git a/src/KingSystem/ActorSystem/actBaseProcCreateTask.h b/src/KingSystem/ActorSystem/actBaseProcCreateTask.h
new file mode 100644
index 00000000..0d1c28cb
--- /dev/null
+++ b/src/KingSystem/ActorSystem/actBaseProcCreateTask.h
@@ -0,0 +1,95 @@
+#pragma once
+
+#include <basis/seadTypes.h>
+#include <prim/seadDelegate.h>
+#include <prim/seadSafeString.h>
+#include "KingSystem/ActorSystem/actBaseProcLink.h"
+#include "KingSystem/ActorSystem/actInstParamPack.h"
+#include "KingSystem/Map/mapMubinIter.h"
+#include "KingSystem/Utils/Thread/ManagedTask.h"
+#include "KingSystem/Utils/Thread/Task.h"
+#include "KingSystem/Utils/Thread/TaskData.h"
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys::map {
+class Object;
+}
+
+namespace ksys::act {
+
+class BaseProc;
+class BaseProcHandle;
+class BaseProcUnit;
+
+struct BaseProcCreateArg {
+ sead::Heap* heap;
+ sead::Heap* heap2;
+ sead::SafeString proc_class;
+ sead::SafeString proc_name;
+ map::MubinIter* mubin_iter;
+ map::Object* map_object;
+ InstParamPack::Buffer* params;
+ BaseProcLink proc_link;
+};
+KSYS_CHECK_SIZE_NX150(BaseProcCreateArg, 0x58);
+
+class BaseProcCreateTaskData : public util::TaskData {
+ SEAD_RTTI_OVERRIDE(BaseProcCreateTaskData, util::TaskData)
+
+public:
+ BaseProcCreateTaskData() = default;
+ virtual ~BaseProcCreateTaskData() = default;
+
+ sead::Heap* mHeap{};
+ sead::SafeString mProcClass{};
+ sead::SafeString mProcName{};
+ sead::IDelegate1R<BaseProcCreateArg&, BaseProc*>* mCreateDelegate{};
+ BaseProcHandle* mProcHandle{};
+ map::MubinIter* mMubinIter{};
+ map::Object* mMapObject{};
+ InstParamPack::Buffer* mParams{};
+ BaseProc* mOtherProc{};
+ bool _60{};
+};
+KSYS_CHECK_SIZE_NX150(BaseProcCreateTaskData, 0x68);
+
+class BaseProcCreateTaskRequest : public util::TaskRequest {
+ SEAD_RTTI_OVERRIDE(BaseProcCreateTaskRequest, util::TaskRequest)
+
+public:
+ BaseProcCreateTaskRequest() = default;
+
+ BaseProcCreateTaskData* mData{};
+};
+
+class BaseProcCreateTask : public util::ManagedTask {
+ SEAD_RTTI_OVERRIDE(BaseProcCreateTask, util::ManagedTask)
+
+public:
+ explicit BaseProcCreateTask(sead::Heap* heap);
+
+ void onBaseProcCreationFailed(BaseProc* proc, bool set_flag_5);
+
+protected:
+ void prepareImpl_(util::TaskRequest* req) override;
+
+private:
+ bool onTaskDelegateInvoked(void* arg);
+ void doPrepare(const BaseProcCreateTaskData* data);
+
+ sead::Heap* mHeap;
+ sead::FixedSafeString<64> mClass;
+ sead::FixedSafeString<64> mName;
+ map::MubinIter mMubinIter;
+ sead::IDelegate1R<BaseProcCreateArg&, BaseProc*>* mCreateDelegate{};
+ BaseProcUnit* mUnit{};
+ map::Object* mMapObject{};
+ util::TaskDelegateT<BaseProcCreateTask> mTaskDelegate{
+ this, &BaseProcCreateTask::onTaskDelegateInvoked};
+ BaseProcLink mLink;
+ f32 mDistanceToLoadSphere = -1.0;
+ InstParamPack::Buffer mParams;
+};
+KSYS_CHECK_SIZE_NX150(BaseProcCreateTask, 0x298);
+
+} // namespace ksys::act
diff --git a/src/KingSystem/ActorSystem/actBaseProcHandle.h b/src/KingSystem/ActorSystem/actBaseProcHandle.h
index 7b0301a2..aa8da7cc 100644
--- a/src/KingSystem/ActorSystem/actBaseProcHandle.h
+++ b/src/KingSystem/ActorSystem/actBaseProcHandle.h
@@ -16,6 +16,7 @@ public:
bool procReady();
BaseProc* getProc();
+ BaseProcUnit* getUnit() const { return mUnit; }
static BaseProcHandle sDummyHandle;
diff --git a/src/KingSystem/ActorSystem/actInstParamPack.h b/src/KingSystem/ActorSystem/actInstParamPack.h
index 74865e3b..bbfdc74d 100644
--- a/src/KingSystem/ActorSystem/actInstParamPack.h
+++ b/src/KingSystem/ActorSystem/actInstParamPack.h
@@ -62,6 +62,9 @@ public:
Buffer() { clear(); }
Buffer& operator=(const Buffer& other);
+ auto getNumParams() const { return mNumItems; }
+ void clearFast() { mNumItems = 0; }
+
void clear();
void add(const void* data, const sead::SafeString& name, s32 byte_size, EntryType type);
void add(ActorCallback* callback, const sead::SafeString& name);
diff --git a/src/KingSystem/Map/mapObject.h b/src/KingSystem/Map/mapObject.h
index 6a4a2325..710c35c0 100644
--- a/src/KingSystem/Map/mapObject.h
+++ b/src/KingSystem/Map/mapObject.h
@@ -76,6 +76,8 @@ public:
void free();
+ void onBaseProcCreated(act::BaseProc* proc);
+
bool getActorWithAccessor(act::ActorLinkConstDataAccess& accessor) const;
act::Actor* getActor() const;
void registerBaseProc(act::BaseProc* proc);