mirror of https://github.com/zeldaret/botw.git
ksys: Implement ActorLimiter
This commit is contained in:
parent
1f12ab9237
commit
3f9172043c
|
@ -78175,13 +78175,13 @@
|
|||
0x0000007100e4d1a8,GlobalParameter::loadActorPack,84,
|
||||
0x0000007100e4d1fc,GlobalParameter::resIsReady,60,
|
||||
0x0000007100e4d238,GlobalParameter::loadActorFiles,256,
|
||||
0x0000007100e4d338,ActorLimiter::List::init,236,
|
||||
0x0000007100e4d424,ActorLimiter::List::addActor,428,
|
||||
0x0000007100e4d5d0,ActorLimiter::Disposer::dtor,204,
|
||||
0x0000007100e4d69c,ActorLimiter::Disposer::dtorDelete,212,
|
||||
0x0000007100e4d770,ActorLimiter::createInstance,148,
|
||||
0x0000007100e4d804,ActorLimiter::init,212,
|
||||
0x0000007100e4d8d8,ActorLimiter_::ctor,320,
|
||||
0x0000007100e4d338,ActorLimiter::List::init,236,_ZN4ksys3act12ActorLimiter4List4initEPN4sead4HeapEi
|
||||
0x0000007100e4d424,ActorLimiter::List::addActor,428,_ZN4ksys3act12ActorLimiter4List8addActorEPNS0_8BaseProcEb
|
||||
0x0000007100e4d5d0,ActorLimiter::Disposer::dtor,204,_ZN4ksys3act12ActorLimiter18SingletonDisposer_D2Ev
|
||||
0x0000007100e4d69c,ActorLimiter::Disposer::dtorDelete,212,_ZN4ksys3act12ActorLimiter18SingletonDisposer_D0Ev
|
||||
0x0000007100e4d770,ActorLimiter::createInstance,148,_ZN4ksys3act12ActorLimiter14createInstanceEPN4sead4HeapE
|
||||
0x0000007100e4d804,ActorLimiter::init,212,_ZN4ksys3act12ActorLimiter4initEPN4sead4HeapERKNS2_9SafeArrayIiLi8EEE
|
||||
0x0000007100e4d8d8,ActorLimiter_::ctor,320,_ZN4sead9SafeArrayIN4ksys3act12ActorLimiter4ListELi8EEC2Ev
|
||||
0x0000007100e4da18,sub_7100E4DA18,60,
|
||||
0x0000007100e4da54,sub_7100E4DA54,296,
|
||||
0x0000007100e4db7c,sub_7100E4DB7C,128,
|
||||
|
|
Can't render this file because it is too large.
|
2
lib/sead
2
lib/sead
|
@ -1 +1 @@
|
|||
Subproject commit 09f3cdd5c83e0bcf6e67eb983e3f992e17f44b39
|
||||
Subproject commit d0635a9d2fdcaa6b5b9446de22c6691f05b4adef
|
|
@ -13,6 +13,8 @@ target_sources(uking PRIVATE
|
|||
actActorFactory.h
|
||||
actActorHeapUtil.cpp
|
||||
actActorHeapUtil.h
|
||||
actActorLimiter.cpp
|
||||
actActorLimiter.h
|
||||
actActorLinkConstDataAccess.cpp
|
||||
actActorLinkConstDataAccess.h
|
||||
actActorParam.cpp
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <prim/seadRuntimeTypeInfo.h>
|
||||
#include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h"
|
||||
#include "KingSystem/ActorSystem/actBaseProc.h"
|
||||
#include "KingSystem/ActorSystem/actBaseProcLink.h"
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
|
||||
|
@ -42,6 +43,11 @@ public:
|
|||
bool acquireConnectedCalcChild(ActorLinkConstDataAccess* accessor) const;
|
||||
bool hasConnectedCalcParent() const;
|
||||
|
||||
bool deleteLater(BaseProc::DeleteReason reason) const;
|
||||
bool fadeOutDelete(BaseProc::DeleteReason reason) const;
|
||||
bool sleep(BaseProc::SleepWakeReason reason) const;
|
||||
bool wakeUp(BaseProc::SleepWakeReason reason) const;
|
||||
|
||||
bool isAttClientEnabled(const sead::SafeString& client) const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#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.fadeOutDelete(BaseProc::DeleteReason::_15);
|
||||
}
|
||||
|
||||
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<int, NumCategories>& capacities) {
|
||||
for (s32 i = 0; i < NumCategories; ++i) {
|
||||
if (!mLists.ref()[i].init(heap, capacities[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ksys::act
|
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
|
||||
#include <container/seadBuffer.h>
|
||||
#include <container/seadOffsetList.h>
|
||||
#include <container/seadSafeArray.h>
|
||||
#include <heap/seadDisposer.h>
|
||||
#include <prim/seadStorageFor.h>
|
||||
#include <thread/seadCriticalSection.h>
|
||||
#include "KingSystem/ActorSystem/actBaseProcLink.h"
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
|
||||
namespace ksys::act {
|
||||
|
||||
class ActorLimiter {
|
||||
SEAD_SINGLETON_DISPOSER(ActorLimiter)
|
||||
ActorLimiter() = default;
|
||||
~ActorLimiter() { mLists.destruct(); }
|
||||
|
||||
public:
|
||||
enum class Category {
|
||||
LumberjackTreeDrops = 0,
|
||||
DroppedItems = 1,
|
||||
PlayerTrash = 2,
|
||||
Drops = 3,
|
||||
SandSeal = 4,
|
||||
Bullets = 5,
|
||||
AmiiboDrops = 6,
|
||||
_7 = 7,
|
||||
};
|
||||
static constexpr int NumCategories = 8;
|
||||
|
||||
class List {
|
||||
public:
|
||||
List() { mActorList.initOffset(offsetof(Node, node)); }
|
||||
~List() { mNodes.freeBuffer(); }
|
||||
|
||||
bool init(sead::Heap* heap, int capacity);
|
||||
bool addActor(BaseProc* proc, bool allow_evicting_old_actors);
|
||||
|
||||
private:
|
||||
struct Node {
|
||||
sead::ListNode node;
|
||||
BaseProcLink proc_link;
|
||||
};
|
||||
|
||||
sead::Buffer<Node> mNodes;
|
||||
sead::OffsetList<Node> mActorList;
|
||||
sead::CriticalSection mCritSection;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(List, 0x68);
|
||||
|
||||
bool init(sead::Heap* heap, const sead::SafeArray<int, NumCategories>& capacities);
|
||||
|
||||
List& get(Category category) { return mLists.ref()[s32(category)]; }
|
||||
const List& get(Category category) const { return mLists.ref()[s32(category)]; }
|
||||
|
||||
private:
|
||||
sead::StorageFor<sead::SafeArray<List, NumCategories>> mLists{sead::ZeroInitializeTag{}};
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(ActorLimiter, 0x360);
|
||||
|
||||
} // namespace ksys::act
|
|
@ -44,6 +44,7 @@ public:
|
|||
_0 = 0,
|
||||
_1 = 1,
|
||||
_2 = 2,
|
||||
_15 = 15,
|
||||
};
|
||||
|
||||
enum class SleepWakeReason : u32 {
|
||||
|
|
Loading…
Reference in New Issue