diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 61609093..df160d8a 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -96968,30 +96968,30 @@ 0x000000710130566c,sub_710130566C,92,_ZNK4sead10Delegate1RIN4ksys3act18BaseProcCreateTaskEPvbE5cloneEPNS_4HeapE 0x00000071013056c8,sub_71013056C8,64, 0x0000007101305708,BaseProcInitializer::ctor,40,_ZN4ksys3act19BaseProcInitializerC1Ev -0x0000007101305730,BaseProcInitializer::dtor,260, -0x0000007101305834,BaseProcInitializer::dtorDelete,36, -0x0000007101305858,BaseProcInitializer::init,960, -0x0000007101305c18,BaseProcInitializer::WorkerThread::init,224, -0x0000007101305cf8,BaseProcInitializer::stopAndDestroyThreadIfXXX,100, -0x0000007101305d5c,sub_7101305D5C,348, -0x0000007101305eb8,sub_7101305EB8,368, -0x0000007101306028,sub_7101306028,164, -0x00000071013060cc,sub_71013060CC,60, -0x0000007101306108,sub_7101306108,108, -0x0000007101306174,sub_7101306174,108, -0x00000071013061e0,sub_71013061E0,60, -0x000000710130621c,sub_710130621C,52, -0x0000007101306250,sub_7101306250,268, -0x000000710130635c,BaseProcInitializer::clearMessageQueuesMaybe,124, -0x00000071013063d8,sub_71013063D8,60, -0x0000007101306414,sub_7101306414,284, -0x0000007101306530,BaseProcInitializer::getQueueSize,92, -0x000000710130658c,sub_710130658C,160, -0x000000710130662c,sub_710130662C,12, -0x0000007101306638,BaseProcEvent::Request::rtti1,204, -0x0000007101306704,BaseProcEvent::Request::rtti2,92, -0x0000007101306760,BaseProcEvent::Request::dtorDelete,4, -0x0000007101306764,BaseProcEvent::make,60, +0x0000007101305730,BaseProcInitializer::dtor,260,_ZN4ksys3act19BaseProcInitializerD1Ev +0x0000007101305834,BaseProcInitializer::dtorDelete,36,_ZN4ksys3act19BaseProcInitializerD0Ev +0x0000007101305858,BaseProcInitializer::init,960,_ZN4ksys3act19BaseProcInitializer4initEPN4sead4HeapERKNS0_23BaseProcInitializerArgsE +0x0000007101305c18,BaseProcInitializer::WorkerThread::init,224,_ZN4ksys4util7TaskMgr16initAndCheckTypeINS_3act18BaseProcCreateTaskEEEviPN4sead4HeapE +0x0000007101305cf8,BaseProcInitializer::stopAndDestroyThreadIfXXX,100,_ZN4ksys3act19BaseProcInitializer20deleteThreadIfPausedEv +0x0000007101305d5c,sub_7101305D5C,348,_ZN4ksys3act19BaseProcInitializer21requestCreateBaseProcERKNS0_21BaseProcCreateRequestE +0x0000007101305eb8,sub_7101305EB8,368,_ZN4ksys3act19BaseProcInitializer14createBaseProcERKNS0_21BaseProcCreateRequestE +0x0000007101306028,sub_7101306028,164,_ZN4ksys3act19BaseProcInitializer14restartThreadsEv +0x00000071013060cc,sub_71013060CC,60,_ZN4ksys3act19BaseProcInitializer17blockPendingTasksEv +0x0000007101306108,sub_7101306108,108,_ZN4ksys3act19BaseProcInitializer12pauseThreadsEv +0x0000007101306174,sub_7101306174,108,_ZN4ksys3act19BaseProcInitializer13resumeThreadsEv +0x00000071013061e0,sub_71013061E0,60,_ZN4ksys3act19BaseProcInitializer19unblockPendingTasksEv +0x000000710130621c,sub_710130621C,52,_ZN4ksys3act19BaseProcInitializer15pauseMainThreadEv +0x0000007101306250,sub_7101306250,268,_ZN4ksys3act19BaseProcInitializer16resumeMainThreadEv +0x000000710130635c,BaseProcInitializer::clearMessageQueuesMaybe,124,_ZNK4ksys3act19BaseProcInitializer17isAnyThreadActiveEv +0x00000071013063d8,sub_71013063D8,60,_ZN4ksys3act19BaseProcInitializer24waitForTaskQueuesToEmptyEv +0x0000007101306414,sub_7101306414,284,_ZN4ksys3act19BaseProcInitializer11cancelTasksEv +0x0000007101306530,BaseProcInitializer::getQueueSize,92,_ZNK4ksys3act19BaseProcInitializer12getQueueSizeEi +0x000000710130658c,sub_710130658C,160,_ZN4ksys3act19BaseProcInitializer13removeTasksIfERN4sead11IDelegate1RIPNS_4util4TaskEbEE +0x000000710130662c,sub_710130662C,12,_ZN4ksys3act19BaseProcInitializer25setActorGenerationEnabledEb +0x0000007101306638,BaseProcEvent::Request::rtti1,204,_ZNK4ksys3act25BaseProcCreateTaskRequest27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE +0x0000007101306704,BaseProcEvent::Request::rtti2,92,_ZNK4ksys3act25BaseProcCreateTaskRequest18getRuntimeTypeInfoEv +0x0000007101306760,BaseProcEvent::Request::dtorDelete,4,_ZN4ksys3act25BaseProcCreateTaskRequestD0Ev +0x0000007101306764,BaseProcEvent::make,60,_ZN4ksys4util7TaskMgr13makeTaskType_INS_3act18BaseProcCreateTaskEEEvPPNS0_11ManagedTaskE 0x00000071013067a0,sub_71013067A0,64, 0x00000071013067e0,BaseProcJobQue::ctor,160,_ZN4ksys3act14BaseProcJobQueC1Ev 0x0000007101306880,BaseProcJobQue::dtor,108,_ZN4ksys3act14BaseProcJobQueD1Ev diff --git a/src/KingSystem/ActorSystem/actBaseProcCreateTask.h b/src/KingSystem/ActorSystem/actBaseProcCreateTask.h index c78cf091..50c1c966 100644 --- a/src/KingSystem/ActorSystem/actBaseProcCreateTask.h +++ b/src/KingSystem/ActorSystem/actBaseProcCreateTask.h @@ -49,7 +49,7 @@ public: map::Object* mMapObject{}; InstParamPack::Buffer* mParams{}; BaseProc* mOtherProc{}; - bool _60{}; + bool mSleepAfterInit{}; }; KSYS_CHECK_SIZE_NX150(BaseProcCreateTaskData, 0x68); @@ -66,6 +66,12 @@ class BaseProcCreateTask : public util::ManagedTask { SEAD_RTTI_OVERRIDE(BaseProcCreateTask, util::ManagedTask) public: + enum class LaneId : u8 { + _0 = 0, + _1 = 1, + _2 = 2, + }; + explicit BaseProcCreateTask(sead::Heap* heap); void onBaseProcCreationFailed(BaseProc* proc, bool set_flag_5); diff --git a/src/KingSystem/ActorSystem/actBaseProcCreateTaskSelector.cpp b/src/KingSystem/ActorSystem/actBaseProcCreateTaskSelector.cpp index 5b98aac6..3609d5a2 100644 --- a/src/KingSystem/ActorSystem/actBaseProcCreateTaskSelector.cpp +++ b/src/KingSystem/ActorSystem/actBaseProcCreateTaskSelector.cpp @@ -17,7 +17,7 @@ util::Task* BaseProcCreateTaskSelector::selectTask(const util::TaskSelectionCont if (!task) return ⁢ - if (task->getLaneId() == 2) + if (task->getLaneId() == u8(BaseProcCreateTask::LaneId::_2)) return ⁢ if (task->mMapObject && task->mMapObject->getFlags0().isOff(map::Object::Flag0::_4)) @@ -29,7 +29,7 @@ util::Task* BaseProcCreateTaskSelector::selectTask(const util::TaskSelectionCont if (task->mDistanceToLoadSphere >= 0.0 && min > task->mDistanceToLoadSphere) min = task->mDistanceToLoadSphere; - if (task->getLaneId() == 1) + if (task->getLaneId() == u8(BaseProcCreateTask::LaneId::_1)) lane1_task = ⁢ } diff --git a/src/KingSystem/ActorSystem/actBaseProcHandle.h b/src/KingSystem/ActorSystem/actBaseProcHandle.h index aa8da7cc..a9815995 100644 --- a/src/KingSystem/ActorSystem/actBaseProcHandle.h +++ b/src/KingSystem/ActorSystem/actBaseProcHandle.h @@ -5,8 +5,9 @@ namespace ksys::act { -class BaseProcUnit; class BaseProc; +class BaseProcCreateTask; +class BaseProcUnit; class BaseProcHandle { public: @@ -17,12 +18,17 @@ public: BaseProc* getProc(); BaseProcUnit* getUnit() const { return mUnit; } + bool allocUnit(); + BaseProcCreateTask* getCreateTask() const; + + bool getFlag() const { return mFlag; } + void setFlag(bool flag) { mFlag = flag; } static BaseProcHandle sDummyHandle; private: BaseProcUnit* mUnit; - u8 mFlag; + bool mFlag; }; KSYS_CHECK_SIZE_NX150(BaseProcHandle, 0x10); diff --git a/src/KingSystem/ActorSystem/actBaseProcInitializer.cpp b/src/KingSystem/ActorSystem/actBaseProcInitializer.cpp index ab6e2b6c..c69a009a 100644 --- a/src/KingSystem/ActorSystem/actBaseProcInitializer.cpp +++ b/src/KingSystem/ActorSystem/actBaseProcInitializer.cpp @@ -1,7 +1,288 @@ #include "KingSystem/ActorSystem/actBaseProcInitializer.h" +#include +#include +#include "KingSystem/ActorSystem/actBaseProcCreateTask.h" +#include "KingSystem/ActorSystem/actBaseProcMgr.h" +#include "KingSystem/Map/mapObject.h" +#include "KingSystem/Resource/resGameResourceSystem.h" +#include "KingSystem/Utils/Debug.h" +#include "KingSystem/Utils/SafeDelete.h" +#include "KingSystem/Utils/Thread/GameTaskThread.h" +#include "KingSystem/Utils/Thread/TaskMgr.h" +#include "KingSystem/Utils/Thread/TaskQueue.h" +#include "KingSystem/Utils/Thread/TaskQueueLock.h" +#include "KingSystem/Utils/Thread/TaskThread.h" namespace ksys::act { BaseProcInitializer::BaseProcInitializer() = default; +BaseProcInitializer::~BaseProcInitializer() { + mTaskMgr->finalize(); + mTaskMgr = nullptr; + + for (int i = 0; i < mThreads.size(); ++i) { + mThreads[i].thread->quitAndWaitDoneSingleThread(false); + if (mThreads[i].thread) + delete mThreads[i].thread; + mThreads[i].thread = nullptr; + } + + mThreads.freeBuffer(); + util::safeDelete(mTaskQueue); +} + +void BaseProcInitializer::init(sead::Heap* parent_heap, const BaseProcInitializerArgs& args) { + constexpr int NumThreads = 3; + + mHeap = sead::ExpHeap::create(0, "BaseProcInitializer", parent_heap, sizeof(void*), + sead::Heap::cHeapDirection_Forward, false); + + mThreads.allocBufferAssert(NumThreads, mHeap); + + const auto init_queue = [&] { + mTaskQueue = new (mHeap) util::TaskQueue(mHeap); + util::TaskQueue::InitArg arg; + arg.enable_locks = true; + arg.heap = mHeap; + arg.num_lanes = 5; + arg.max_num_threads = NumThreads; + arg.task_selection_delegate = args.task_selector; + mTaskQueue->init(arg); + }; + init_queue(); + + mTaskMgr = new (mHeap) util::TaskMgr(mHeap); + mTaskMgr->initAndCheckType(args.queue_size, mHeap); + + for (int i = 0; i < NumThreads; ++i) { + mThreads[i].thread_name.format("%s", args.thread_name.cstr()); + mThreads[i].thread = new (mHeap) util::GameTaskThread( + mThreads[i].thread_name, mHeap, sead::ThreadUtil::ConvertPrioritySeadToPlatform(20), + sead::MessageQueue::BlockType::Blocking, 0x7FFFFFFF, 0x100000, 64); + { + util::TaskThread::InitArg arg; + arg.num_lanes = 5; + arg.heap = mHeap; + arg.queue = mTaskQueue; + arg.batch_size = 1; + mThreads[i].thread->init(arg); + } + mThreads[i].thread->setAffinity(sead::CoreIdMask(i)); + mThreads[i].thread->start(); + mThreads[i].valid = true; + } + + mHeap->adjust(); + mThreads[0].thread->quitAndWaitDoneSingleThread(false); + util::safeDelete(mThreads[0].thread); +} + +void BaseProcInitializer::deleteThreadIfPaused() { + if (mThreads[0].thread && mThreads[0].thread->isPaused()) { + mThreads[0].thread->quitAndWaitDoneSingleThread(false); + util::safeDelete(mThreads[0].thread); + } +} + +bool BaseProcInitializer::requestCreateBaseProc(const BaseProcCreateRequest& req) { + if (!mActorGenerationEnabled) { + if (req.task_data->mProcHandle) + req.task_data->mProcHandle->setFlag(true); + return false; + } + + auto* data = req.task_data; + // XXX: was this meant to log the BaseProc class and its name, rather than print the name twice? + util::PrintDebugFmt("BaseProcInitializer::requestCreateBaseProc: actor %s (%s)", + data->mProcName.cstr(), data->mProcName.cstr()); + + BaseProcCreateTaskRequest task_req; + task_req.mHasHandle = req.task_data->mProcHandle != nullptr; + task_req.mSynchronous = false; + task_req.mLaneId = req.task_lane_id; + task_req.mQueue = mTaskQueue; + task_req.mUserData = nullptr; + task_req.mRemoveCallback = req.task_remove_callback; + task_req.mData = req.task_data; + if (req.task_data) + task_req.mName = req.task_data->mProcName; + + util::TaskMgrRequest mgr_req; + if (req.task_data->mProcHandle) { + if (!req.task_data->mProcHandle->allocUnit()) { + req.task_data->mProcHandle->setFlag(true); + return false; + } + + mgr_req.task = req.task_data->mProcHandle->getCreateTask(); + if (!mgr_req.task) { + req.task_data->mProcHandle->setFlag(true); + return false; + } + } else { + mgr_req.task = nullptr; + } + + mgr_req.request = &task_req; + mTaskMgr->submitRequest(mgr_req); + return true; +} + +BaseProc* BaseProcInitializer::createBaseProc(const BaseProcCreateRequest& req) { + res::GameResourceSystem::instance()->pauseCompaction(); + + BaseProcCreateArg arg; + arg.heap = req.task_data->mHeap; + arg.heap2 = req.task_data->mHeap; + arg.proc_class = req.task_data->mProcClass; + arg.proc_name = req.task_data->mProcName; + arg.mubin_iter = req.task_data->mMubinIter; + arg.map_object = req.task_data->mMapObject; + arg.params = req.task_data->mParams; + if (auto* other = req.task_data->mOtherProc) + arg.proc_link.acquire(other, false); + else + arg.proc_link.reset(); + + BaseProc* result = nullptr; + BaseProc* proc = req.task_data->mCreateDelegate->invoke(arg); + + if (proc && !proc->isDeletedOrDeleting()) { + if (proc->init(arg.heap2, req.task_data->mSleepAfterInit)) + result = proc; + } else if (arg.map_object) { + arg.map_object->onBaseProcCreated(proc); + } + + if (proc) + proc->setInitializedFlag(); + + res::GameResourceSystem::instance()->resumeCompaction(); + return result; +} + +void BaseProcInitializer::restartThreads() { + for (int i = 0; i < mThreads.size(); ++i) { + if (!mThreads[i].thread) + continue; + + if (i == 0 && mThreads[0].valid) { + mThreads[0].thread->pauseAndWaitForAck(); + mThreads[0].thread->resume(); + } else if (i != 0) { + mThreads[i].thread->pauseAndWaitForAck(); + mThreads[i].thread->resume(); + } + } +} + +void BaseProcInitializer::blockPendingTasks() { + mTaskQueue->blockTasks(u8(BaseProcCreateTask::LaneId::_0)); + mTaskQueue->blockTasks(u8(BaseProcCreateTask::LaneId::_1)); + mTaskQueue->blockTasks(u8(BaseProcCreateTask::LaneId::_2)); +} + +void BaseProcInitializer::pauseThreads() { + for (int i = 0; i < mThreads.size(); ++i) { + if (mThreads[i].thread) + mThreads[i].thread->pauseAndWaitForAck(); + } +} + +void BaseProcInitializer::resumeThreads() { + for (int i = 0; i < mThreads.size(); ++i) { + if (mThreads[i].thread) + mThreads[i].thread->resume(); + } +} + +void BaseProcInitializer::unblockPendingTasks() { + mTaskQueue->unblockTasks(u8(BaseProcCreateTask::LaneId::_2)); + mTaskQueue->unblockTasks(u8(BaseProcCreateTask::LaneId::_1)); + mTaskQueue->unblockTasks(u8(BaseProcCreateTask::LaneId::_0)); +} + +void BaseProcInitializer::pauseMainThread() { + if (mThreads[0].thread) { + mThreads[0].thread->pause(); + mThreads[0].valid = false; + } +} + +void BaseProcInitializer::resumeMainThread() { + mThreads[0].valid = true; + if (!mThreads[0].thread) { + mThreads[0].thread = new (mHeap) util::GameTaskThread( + mThreads[0].thread_name, mHeap, sead::ThreadUtil::ConvertPrioritySeadToPlatform(20), + sead::MessageQueue::BlockType::Blocking, 0x7FFFFFFF, 0x100000, 64); + { + util::TaskThread::InitArg arg; + arg.num_lanes = 5; + arg.heap = mHeap; + arg.queue = mTaskQueue; + arg.batch_size = 1; + mThreads[0].thread->init(arg); + } + mThreads[0].thread->setAffinity(sead::CoreIdMask(sead::CoreId::cMain)); + mThreads[0].thread->start(); + } + mThreads[0].thread->resume(); +} + +bool BaseProcInitializer::isAnyThreadActive() const { + for (int i = 0; i < mThreads.size(); ++i) { + if (mThreads[i].thread && mThreads[i].thread->isActiveAndReceivedQueueUpdateMsg()) + return true; + } + return false; +} + +void BaseProcInitializer::waitForTaskQueuesToEmpty() { + mTaskQueue->waitForLaneToEmpty(u8(BaseProcCreateTask::LaneId::_2)); + mTaskQueue->waitForLaneToEmpty(u8(BaseProcCreateTask::LaneId::_1)); + mTaskQueue->waitForLaneToEmpty(u8(BaseProcCreateTask::LaneId::_0)); +} + +void BaseProcInitializer::cancelTasks() { + int n = 0; + n += mThreads[1].thread->getTaskQueue()->countTasksInLane(u8(BaseProcCreateTask::LaneId::_0)); + n += mThreads[1].thread->getTaskQueue()->countTasksInLane(u8(BaseProcCreateTask::LaneId::_1)); + n += mThreads[1].thread->getTaskQueue()->countTasksInLane(u8(BaseProcCreateTask::LaneId::_2)); + util::PrintDebugFmt("Cancelling %d tasks", n); + + for (int i = 0; i < mThreads.size(); ++i) { + if (!mThreads[i].thread) + continue; + mThreads[i].thread->cancelTasks(u8(BaseProcCreateTask::LaneId::_0)); + mThreads[i].thread->cancelTasks(u8(BaseProcCreateTask::LaneId::_1)); + mThreads[i].thread->cancelTasks(u8(BaseProcCreateTask::LaneId::_2)); + } +} + +int BaseProcInitializer::getQueueSize(int x) const { + if (x != -1) + return -1; + + int count = 0; + count += mTaskQueue->countTasksInLane(u8(BaseProcCreateTask::LaneId::_2)); + count += mTaskQueue->countTasksInLane(u8(BaseProcCreateTask::LaneId::_1)); + count += mTaskQueue->countTasksInLane(u8(BaseProcCreateTask::LaneId::_0)); + return count; +} + +void BaseProcInitializer::removeTasksIf(sead::IDelegate1R& predicate) { + util::TaskQueueLock lock; + auto it = mTaskQueue->activeTasksRobustBegin(&lock); + const auto end = mTaskQueue->activeTasksRobustEnd(); + for (; it != end; ++it) { + if (predicate(std::addressof(*it))) + it->removeFromQueue(); + } +} + +void BaseProcInitializer::setActorGenerationEnabled(bool enabled) { + mActorGenerationEnabled = enabled; +} + } // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actBaseProcInitializer.h b/src/KingSystem/ActorSystem/actBaseProcInitializer.h index 3510d513..bd410fb9 100644 --- a/src/KingSystem/ActorSystem/actBaseProcInitializer.h +++ b/src/KingSystem/ActorSystem/actBaseProcInitializer.h @@ -1,6 +1,10 @@ #pragma once #include +#include +#include +#include "KingSystem/Utils/Thread/TaskQueueBase.h" +#include "KingSystem/Utils/Types.h" namespace sead { class Heap; @@ -9,31 +13,71 @@ class Heap; namespace ksys::util { class TaskMgr; class TaskQueue; +class TaskThread; } // namespace ksys::util namespace ksys::act { +class BaseProc; +struct BaseProcCreateRequest; + +struct BaseProcInitializerArgs { + u32 queue_size = 1024; + sead::SafeString thread_name = "BaseProcCreate"; + util::TaskSelectionDelegate* task_selector = nullptr; +}; + class BaseProcInitializer { public: + struct ThreadInfo { + bool valid = false; + util::TaskThread* thread = nullptr; + sead::FixedSafeString<32> thread_name; + }; + KSYS_CHECK_SIZE_NX150(ThreadInfo, 0x48); + BaseProcInitializer(); virtual ~BaseProcInitializer(); BaseProcInitializer(const BaseProcInitializer&) = delete; + BaseProcInitializer(BaseProcInitializer&&) = delete; auto operator=(const BaseProcInitializer&) = delete; + auto operator=(BaseProcInitializer&&) = delete; - u32 get8() const { return _8; } - void set8(u32 value) { _8 = value; } + const sead::Buffer& getThreads() const { return mThreads; } bool isActorGenerationEnabled() const { return mActorGenerationEnabled; } - void setActorGenerationEnabled(bool enabled) { mActorGenerationEnabled = enabled; } + + void init(sead::Heap* parent_heap, const BaseProcInitializerArgs& args); + void deleteThreadIfPaused(); + + bool requestCreateBaseProc(const BaseProcCreateRequest& req); + BaseProc* createBaseProc(const BaseProcCreateRequest& req); + + void restartThreads(); + void blockPendingTasks(); + void pauseThreads(); + void resumeThreads(); + void unblockPendingTasks(); + + void pauseMainThread(); + void resumeMainThread(); + + bool isAnyThreadActive() const; + void waitForTaskQueuesToEmpty(); + void cancelTasks(); + int getQueueSize(int x = -1) const; + + void removeTasksIf(sead::IDelegate1R& predicate); + void setActorGenerationEnabled(bool enabled); private: - u32 _8 = 0; - void* _10 = nullptr; + sead::Buffer mThreads; util::TaskMgr* mTaskMgr = nullptr; util::TaskQueue* mTaskQueue = nullptr; sead::Heap* mHeap = nullptr; bool mActorGenerationEnabled = true; }; +KSYS_CHECK_SIZE_NX150(BaseProcInitializer, 0x38); } // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actBaseProcMgr.h b/src/KingSystem/ActorSystem/actBaseProcMgr.h index 0ebb4f39..752da5b5 100644 --- a/src/KingSystem/ActorSystem/actBaseProcMgr.h +++ b/src/KingSystem/ActorSystem/actBaseProcMgr.h @@ -15,6 +15,7 @@ #include "KingSystem/ActorSystem/actBaseProcJob.h" #include "KingSystem/ActorSystem/actBaseProcMap.h" #include "KingSystem/Utils/StrTreeMap.h" +#include "KingSystem/Utils/Thread/Task.h" #include "KingSystem/Utils/Types.h" namespace sead { @@ -26,19 +27,24 @@ class WorkerMgr; namespace ksys::act { +class BaseProcCreateTaskData; class BaseProcDeleter; class BaseProcInitializer; -class BaseProcInitializerArgs; +struct BaseProcInitializerArgs; class BaseProcJobLists; class BaseProcJobQue; +struct BaseProcCreateRequest { + u32 task_lane_id; + BaseProcCreateTaskData* task_data; + util::TaskRemoveCallback* task_remove_callback; +}; + class BaseProcMgr { SEAD_SINGLETON_DISPOSER(BaseProcMgr) BaseProcMgr(); public: - class ProcCreateRequest; - enum class Status : u8 { Idle = 0, _1 = 1, @@ -62,7 +68,7 @@ public: virtual ~BaseProcMgr(); void init(sead::Heap* heap, s32 num_job_types, u32 main_thread_id, u32 havok_thread_id1, - u32 havok_thread_id2, BaseProcInitializerArgs* initializer_args); + u32 havok_thread_id2, const BaseProcInitializerArgs& initializer_args); // region BaseProc management @@ -133,8 +139,8 @@ public: // region BaseProc creation - bool requestCreateProc(ProcCreateRequest& req); - BaseProc* createProc(ProcCreateRequest& req); + bool requestCreateProc(const BaseProcCreateRequest& req); + BaseProc* createProc(const BaseProcCreateRequest& req); // endregion diff --git a/src/KingSystem/Utils/Debug.h b/src/KingSystem/Utils/Debug.h index 72e4ab5b..3027d828 100644 --- a/src/KingSystem/Utils/Debug.h +++ b/src/KingSystem/Utils/Debug.h @@ -6,4 +6,7 @@ namespace ksys::util { inline void PrintDebug([[maybe_unused]] const sead::SafeString& message) {} +template +inline void PrintDebugFmt(const char* format, const Args&...) {} + } // namespace ksys::util diff --git a/src/KingSystem/Utils/Thread/Task.h b/src/KingSystem/Utils/Thread/Task.h index 2010ac77..5c9d95c3 100644 --- a/src/KingSystem/Utils/Thread/Task.h +++ b/src/KingSystem/Utils/Thread/Task.h @@ -53,8 +53,14 @@ KSYS_CHECK_SIZE_NX150(TaskRemoveCallbackContext, 0x18); using TaskDelegate = sead::IDelegate1R; template using TaskDelegateT = sead::Delegate1R; + using TaskPostRunCallback = sead::IDelegate2; +template +using TaskPostRunCallbackT = sead::Delegate2; + using TaskRemoveCallback = sead::IDelegate1; +template +using TaskRemoveCallbackT = sead::Delegate1; class TaskDelegateSetter { SEAD_RTTI_BASE(TaskDelegateSetter) diff --git a/src/KingSystem/Utils/Thread/TaskMgr.h b/src/KingSystem/Utils/Thread/TaskMgr.h index 8b94e53e..a6cc2960 100644 --- a/src/KingSystem/Utils/Thread/TaskMgr.h +++ b/src/KingSystem/Utils/Thread/TaskMgr.h @@ -42,8 +42,20 @@ public: void init(s32 num_tasks, sead::Heap* heap, ManagedTaskFactory& factory); template - void init(s32 num_tasks, sead::Heap* heap, bool check_task_type = false) { - initImpl_(num_tasks, heap, check_task_type); + void init(s32 num_tasks, sead::Heap* heap) { + initImpl_(num_tasks, heap); + } + + template + void initAndCheckType(s32 num_tasks, sead::Heap* heap) { + initImpl_(num_tasks, heap); + if (hasTasks()) { + Task* task = nullptr; + if (mFreeTaskLists[0].size() >= 1) + task = mFreeTaskLists[0].front(); + const bool is_derived_from_managed_task = sead::IsDerivedFrom(task); + SEAD_ASSERT(is_derived_from_managed_task); + } } void finalize(); @@ -87,17 +99,9 @@ protected: } template - void initImpl_(s32 num_tasks, sead::Heap* heap, bool check_task_type) { + void initImpl_(s32 num_tasks, sead::Heap* heap) { sead::Delegate1 factory{this, &TaskMgr::makeTaskType_}; init(num_tasks, heap, factory); - - if (check_task_type && hasTasks()) { - Task* task = nullptr; - if (mFreeTaskLists[0].size() >= 1) - task = mFreeTaskLists[0].front(); - const bool is_derived_from_managed_task = sead::IsDerivedFrom(task); - SEAD_ASSERT(is_derived_from_managed_task); - } } sead::TypedBitFlag mFlags;