#include "KingSystem/ActorSystem/actActorLimiter.h" #include "KingSystem/ActorSystem/actActorConstDataAccess.h" #include "KingSystem/ActorSystem/actTag.h" namespace ksys::act { bool ActorLimiter::List::init(sead::Heap* heap, int capacity) { mNodes.allocBufferAssert(capacity, heap); if (!mNodes.isBufferReady()) return false; for (auto& node : mNodes) mActorList.pushBack(&node); return true; } bool ActorLimiter::List::addActor(BaseProc* proc, bool allow_evicting_old_actors) { const auto lock = sead::makeScopedLock(mCritSection); // Find a free node. Node* target_node = nullptr; for (auto& node : mActorList) { if (node.proc_link.hasProc()) continue; mActorList.erase(&node); target_node = &node; break; } if (target_node == nullptr) { if (!allow_evicting_old_actors) return false; target_node = mActorList.popFront(); if (target_node) { ActorConstDataAccess acc; acquireActor(&target_node->proc_link, &acc); // Priority material actors will not be evicted if possible. if (acc.hasTag(tags::PriorityMaterial)) { mActorList.pushBack(target_node); target_node = mActorList.popFront(); if (target_node) acquireActor(&target_node->proc_link, &acc); } acc.deleteEx(BaseProc::DeleteReason::_f); } if (target_node == nullptr) return false; } target_node->proc_link.acquire(proc, false); mActorList.pushBack(target_node); return true; } SEAD_SINGLETON_DISPOSER_IMPL(ActorLimiter) bool ActorLimiter::init(sead::Heap* heap, const sead::SafeArray& capacities) { for (s32 i = 0; i < NumCategories; ++i) { if (!mLists.ref()[i].init(heap, capacities[i])) return false; } return true; } } // namespace ksys::act