diff options
Diffstat (limited to 'src/KingSystem/ActorSystem/actBaseProcMgr.cpp')
| -rw-r--r-- | src/KingSystem/ActorSystem/actBaseProcMgr.cpp | 297 |
1 files changed, 277 insertions, 20 deletions
diff --git a/src/KingSystem/ActorSystem/actBaseProcMgr.cpp b/src/KingSystem/ActorSystem/actBaseProcMgr.cpp index 9f0044f7..0aaaaf69 100644 --- a/src/KingSystem/ActorSystem/actBaseProcMgr.cpp +++ b/src/KingSystem/ActorSystem/actBaseProcMgr.cpp @@ -1,6 +1,14 @@ #include "KingSystem/ActorSystem/actBaseProcMgr.h" +#include <mc/seadWorkerMgr.h> #include <prim/seadScopedLock.h> #include <thread/seadThread.h> +#include "KingSystem/ActorSystem/actActorSystem.h" +#include "KingSystem/ActorSystem/actBaseProcDeleter.h" +#include "KingSystem/ActorSystem/actBaseProcHeapMgr.h" +#include "KingSystem/ActorSystem/actBaseProcInitializer.h" +#include "KingSystem/ActorSystem/actBaseProcJobHandler.h" +#include "KingSystem/ActorSystem/actBaseProcJobQue.h" +#include "KingSystem/ActorSystem/actBaseProcLink.h" namespace ksys::act { @@ -11,6 +19,54 @@ BaseProcMgr::BaseProcMgr() { mProcUpdateStateList.initOffset(offsetof(BaseProc, mUpdateStateListNode)); } +BaseProcMgr::~BaseProcMgr() { + if (mProcJobQue) { + delete mProcJobQue; + mProcJobQue = nullptr; + } + + mJobLists.freeBuffer(); + + if (mProcInitializer) { + delete mProcInitializer; + mProcInitializer = nullptr; + } + + if (mProcDeleter) { + delete mProcDeleter; + mProcDeleter = nullptr; + } + + BaseProcHeapMgr::deleteInstance(); +} + +// NON_MATCHING: mJobLists.allocBufferAssert - BaseProcJobLists ctor +void BaseProcMgr::init(sead::Heap* heap, s32 num_job_types, u32 main_thread_id, + u32 havok_thread_id1, u32 havok_thread_id2, + const BaseProcInitializerArgs& initializer_args) { + mProcJobQue = new (heap) BaseProcJobQue; + mProcJobQue->init(heap); + + mJobLists.allocBufferAssert(num_job_types, heap); + + mProcInitializer = new (heap) BaseProcInitializer; + mProcInitializer->init(heap, initializer_args); + + mProcDeleter = new (heap) BaseProcDeleter; + BaseProcDeleter::InitArg deleter_arg; + deleter_arg.heap = heap; + deleter_arg.task_queue = mProcInitializer->getTaskQueue(); + deleter_arg.task_queue_size = 2048; + mProcDeleter->init(deleter_arg); + + mMainThreadId = main_thread_id; + mHavokThreadId1 = havok_thread_id1; + mHavokThreadId2 = havok_thread_id2; + + BaseProcHeapMgr::createInstance(heap); + BaseProcLinkDataMgr::createInstance(heap); +} + void BaseProcMgr::generateProcId(u32* id) { *id = mCreatedProcCounter.increment(); } @@ -29,11 +85,52 @@ void BaseProcMgr::unregisterProc(BaseProc& proc) { mProcMap.erase(&proc.mMapNode); } +bool BaseProcMgr::requestPreDelete(BaseProc& proc) { + return mProcDeleter->requestPreDelete(&proc); +} + +void BaseProcMgr::requestUnloadActorParam(ActorParam* param) { + return mProcDeleter->requestUnloadActorParam(param); +} + void BaseProcMgr::addToPreDeleteList(BaseProc& proc) { auto lock = sead::makeScopedLock(mProcPreDeleteListCS); mProcPreDeleteList.pushFront(&proc); } +void BaseProcMgr::eraseFromPreDeleteList(BaseProc& proc) { + auto lock = sead::makeScopedLock(mProcPreDeleteListCS); + if (mProcPreDeleteList.isNodeLinked(&proc)) + mProcPreDeleteList.erase(&proc); +} + +void BaseProcMgr::pushJob(BaseProc& proc, JobType type) { + if (proc.isSleep() || !proc.hasJobType_(type)) + return; + + getJobLists(type).pushJob(proc.getJobHandler(type)->getLink()); +} + +void BaseProcMgr::pushJobs(BaseProc& proc) { + for (u32 i = 0; i < u32(mJobLists.size()); ++i) { + pushJob(proc, JobType(i)); + } +} + +void BaseProcMgr::eraseJob(BaseProc& proc, JobType type) { + auto* handler = proc.getJobHandler(type); + if (handler) + getJobLists(type).eraseJob(handler->getLink()); +} + +void BaseProcMgr::eraseJobs(BaseProc& proc) { + for (u32 i = 0; i < u32(mJobLists.size()); ++i) { + auto* handler = proc.getJobHandler(JobType(i)); + if (handler) + mJobLists[i].eraseJob(handler->getLink()); + } +} + void BaseProcMgr::doAddToUpdateStateList_(BaseProc& proc) { if (mProcUpdateStateList.isNodeLinked(&proc)) return; @@ -46,12 +143,6 @@ void BaseProcMgr::doAddToUpdateStateList_(BaseProc& proc) { } } -void BaseProcMgr::eraseFromPreDeleteList(BaseProc& proc) { - auto lock = sead::makeScopedLock(mProcPreDeleteListCS); - if (mProcPreDeleteList.isNodeLinked(&proc)) - mProcPreDeleteList.erase(&proc); -} - void BaseProcMgr::eraseFromUpdateStateList(BaseProc& proc) { auto lock = sead::makeScopedLock(mProcUpdateStateListCS); if (mProcUpdateStateList.isNodeLinked(&proc)) @@ -68,17 +159,100 @@ void BaseProcMgr::processPreDeleteList() { mStatus = Status::Idle; } -bool BaseProcMgr::hasExtraJobLink(BaseProcJobLink* job_link, s32 idx) { - for (auto& ptr : mExtraJobLinkArrays.ref()[idx]) { - if (&ptr == job_link) - return true; +BaseProcMgr::ExtraJobLinkArray& BaseProcMgr::getExtraJobs() { + return mExtraJobLinkArrays.ref()[mCurrentExtraJobArrayIdx]; +} + +void BaseProcMgr::swapExtraJobArray() { + mCurrentExtraJobArrayIdx ^= 1; + getExtraJobs().clear(); +} + +bool BaseProcMgr::checkJobPushState() const { + return mEnableExtraJobPush && mUnk4 != 1; +} + +void BaseProcMgr::pushJobQueues(sead::WorkerMgr* mgr, JobType type, bool x) { + if (!checkJobPushState()) + return; + + mJobType = type; + const auto type_ = mJobType; + mStatus = Status::ProcessingActorJobs; + mIsPushingJobs = true; + mUnk2 = x; + + int i = 0; + do { + mPushActorJobType3InsteadOf6 = false; + + auto& lists = getJobLists(type_); + for (int priority = 0; priority < 8; ++priority) { + mCurrentlyProcessingPrio = priority; + if (mProcJobQue->pushJobQueue(mgr, &lists, priority, type_)) { + mgr->run(); + mgr->sync(); + } + } + + mCurrentlyProcessingPrio = 8; + ++i; + } while (mPushActorJobType3InsteadOf6 && i < 8); + + mIsPushingJobs = false; + mUnk2 = false; + mStatus = Status::Idle; + mJobType = JobType::Invalid; +} + +bool BaseProcMgr::pushExtraJobsEx(sead::FixedSizeJQ* jq, JobType type, u8 priority, bool x, + bool y) { + if (!checkJobPushState()) + return false; + + if (x) { + mUnk2 = y; + auto* queue = mProcJobQue; + mStatus = Status::ProcessingActorJobs; + mJobType = type; + mCurrentlyProcessingPrio = priority; + queue->clear(); } - return false; + + const auto type_ = JobType(u8(type)); + mIsPushingJobs = true; + mProcJobQue->pushExtraJobs(jq, &getJobLists(type_), priority, type_); + return true; } -void BaseProcMgr::clearExtraJobArrays() { - mExtraJobLinkArrays.ref()[0].clear(); - mExtraJobLinkArrays.ref()[1].clear(); +bool BaseProcMgr::pushExtraJobsForCurrentTypeAndPrio(sead::FixedSizeJQ* jq, + ExtraJobLinkArray* array) { + if (!checkJobPushState()) + return false; + if (array) + mProcJobQue->pushExtraJobs(jq, *array); + return true; +} + +void BaseProcMgr::setJobType(JobType type) { + mProcJobQue->clear(); + mJobType = type; +} + +bool BaseProcMgr::pushPreCalcJobs(sead::FixedSizeJQ* jq, JobType type, u8 prio, bool x, bool y) { + if (!checkJobPushState()) + return false; + + if (x) { + mStatus = Status::ProcessingActorJobs; + mJobType = type; + mCurrentlyProcessingPrio = prio; + mUnk2 = y; + } + + const auto type_ = JobType(u8(type)); + mProcJobQue->pushExtraJobs(jq, &getJobLists(type_), prio, type_); + return true; } void BaseProcMgr::setActorJobTypeAndPrio(JobType type, s32 prio, bool x) { @@ -97,10 +271,90 @@ void BaseProcMgr::goIdle() { mCurrentlyProcessingPrio = 8; } +void BaseProcMgr::jobInvoked(BaseProcJobLink* link, s32 required_calc_rounds) { + if (required_calc_rounds == 1) { + link->getProc()->jobInvoked(mJobType); + return; + } + + const auto& lists = getJobLists(mJobType); + for (int i = 0; link && [&] { return i < required_calc_rounds; }(); ++i) { + link->getProc()->jobInvoked(mJobType); + link = static_cast<BaseProcJobLink*>(lists.getNextJob(link)); + } +} + +bool BaseProcMgr::isSpecialJobType(JobType type) const { + return mSpecialJobTypesMask.isOnBit(int(type)); +} + +void BaseProcMgr::addSpecialJobTypes(u16 mask) { + mSpecialJobTypesMask.set(mask); +} + +void BaseProcMgr::removeSpecialJobTypes(u16 mask) { + mSpecialJobTypesMask.reset(mask); +} + +void BaseProcMgr::calc() { + ActorSystem::instance()->onBaseProcMgrCalc(); + mProcInitializer->deleteThreadIfPaused(); + + if (mIsInitialisingQuestMgrMaybe) + return; + + if (!mProcUpdateStateList.isEmpty()) { + const auto lock = sead::makeScopedLock(mProcUpdateStateListCS); + mStatus = Status::ProcessingUpdateStateList; + + for (auto& proc : mProcUpdateStateList) + proc.processStateUpdate(mCounter); + + for (auto it = mProcUpdateStateList.robustBegin(), end = mProcUpdateStateList.robustEnd(); + it != end; ++it) { + it->afterUpdateState_(); + if (it->mStateFlags.isZero()) { + mProcUpdateStateList.erase(std::addressof(*it)); + } + } + + mStatus = Status::Idle; + } + + ++mCounter; +} + void BaseProcMgr::clearMode() { mMode = Mode::_0; } +sead::CriticalSection* BaseProcMgr::lockProcMap() { + mProcMapCS.lock(); + return &mProcMapCS; +} + +void BaseProcMgr::unlockProcMap() { + mLastProcMapNode = nullptr; + mProcMapCS.unlock(); +} + +void BaseProcMgr::deleteAllProcs() { + auto procs = getProcs(ProcFilter::_1 | ProcFilter::_4 | ProcFilter::_8); + while (auto* proc = procs.next()) { + if (!proc->mFlags.isOn(BaseProc::Flags::DoNotDelete)) + proc->deleteLater(BaseProc::DeleteReason::BaseProcMgrDeleteAll); + } +} + +bool BaseProcMgr::hasFinishedDeletingAllProcs() { + auto procs = getProcs(ProcFilter::_1 | ProcFilter::_2 | ProcFilter::_4 | ProcFilter::_8); + while (auto* proc = procs.next()) { + if (!proc->mFlags.isOn(BaseProc::Flags::DoNotDelete)) + return false; + } + return mNumPendingDeletions == 0; +} + bool BaseProcMgr::isHighPriorityThread() const { const auto current_thread = sead::ThreadMgr::instance()->getCurrentThread(); @@ -125,14 +379,17 @@ void BaseProcMgr::decrementUnk3() { --mUnk3; } -sead::CriticalSection* BaseProcMgr::lockProcMap() { - mProcMapCS.lock(); - return &mProcMapCS; +bool BaseProcMgr::hasExtraJobLink(BaseProcJobLink* job_link, s32 idx) { + for (auto& ptr : mExtraJobLinkArrays.ref()[idx]) { + if (&ptr == job_link) + return true; + } + return false; } -void BaseProcMgr::unlockProcMap() { - mLastProcMapNode = nullptr; - mProcMapCS.unlock(); +void BaseProcMgr::clearExtraJobArrays() { + mExtraJobLinkArrays.ref()[0].clear(); + mExtraJobLinkArrays.ref()[1].clear(); } } // namespace ksys::act |
