mirror of https://github.com/zeldaret/botw.git
ksys/act: Finish BaseProcInitializer
This commit is contained in:
parent
afb4e218fa
commit
10a7871227
|
|
@ -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.
|
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 = ⁢
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue