ksys/act: Finish BaseProcInitializer

This commit is contained in:
Léo Lam 2021-03-12 21:11:49 +01:00
parent afb4e218fa
commit 10a7871227
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
10 changed files with 407 additions and 51 deletions

View File

@ -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

Can't render this file because it is too large.

View File

@ -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);

View File

@ -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 = ⁢
}

View File

@ -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);

View File

@ -1,7 +1,288 @@
#include "KingSystem/ActorSystem/actBaseProcInitializer.h"
#include <heap/seadExpHeap.h>
#include <thread/seadThreadUtil.h>
#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<BaseProcCreateTask>(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<util::Task*, bool>& 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

View File

@ -1,6 +1,10 @@
#pragma once
#include <basis/seadTypes.h>
#include <container/seadBuffer.h>
#include <prim/seadSafeString.h>
#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<ThreadInfo>& 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<util::Task*, bool>& predicate);
void setActorGenerationEnabled(bool enabled);
private:
u32 _8 = 0;
void* _10 = nullptr;
sead::Buffer<ThreadInfo> 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

View File

@ -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

View File

@ -6,4 +6,7 @@ namespace ksys::util {
inline void PrintDebug([[maybe_unused]] const sead::SafeString& message) {}
template <typename... Args>
inline void PrintDebugFmt(const char* format, const Args&...) {}
} // namespace ksys::util

View File

@ -53,8 +53,14 @@ KSYS_CHECK_SIZE_NX150(TaskRemoveCallbackContext, 0x18);
using TaskDelegate = sead::IDelegate1R<void*, bool>;
template <typename T>
using TaskDelegateT = sead::Delegate1R<T, void*, bool>;
using TaskPostRunCallback = sead::IDelegate2<TaskPostRunResult*, const TaskPostRunContext&>;
template <typename T>
using TaskPostRunCallbackT = sead::Delegate2<T, TaskPostRunResult*, const TaskPostRunContext&>;
using TaskRemoveCallback = sead::IDelegate1<const TaskRemoveCallbackContext&>;
template <typename T>
using TaskRemoveCallbackT = sead::Delegate1<T, const TaskRemoveCallbackContext&>;
class TaskDelegateSetter {
SEAD_RTTI_BASE(TaskDelegateSetter)

View File

@ -42,8 +42,20 @@ public:
void init(s32 num_tasks, sead::Heap* heap, ManagedTaskFactory& factory);
template <typename TaskType>
void init(s32 num_tasks, sead::Heap* heap, bool check_task_type = false) {
initImpl_<TaskType>(num_tasks, heap, check_task_type);
void init(s32 num_tasks, sead::Heap* heap) {
initImpl_<TaskType>(num_tasks, heap);
}
template <typename TaskType>
void initAndCheckType(s32 num_tasks, sead::Heap* heap) {
initImpl_<TaskType>(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<ManagedTask>(task);
SEAD_ASSERT(is_derived_from_managed_task);
}
}
void finalize();
@ -87,17 +99,9 @@ protected:
}
template <typename TaskType>
void initImpl_(s32 num_tasks, sead::Heap* heap, bool check_task_type) {
void initImpl_(s32 num_tasks, sead::Heap* heap) {
sead::Delegate1<TaskMgr, ManagedTask**> factory{this, &TaskMgr::makeTaskType_<TaskType>};
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<ManagedTask>(task);
SEAD_ASSERT(is_derived_from_managed_task);
}
}
sead::TypedBitFlag<Flag, u8> mFlags;