Files
botw/src/KingSystem/System/OverlayArena.cpp
T
2021-07-26 23:05:19 +12:00

174 lines
4.4 KiB
C++

#include "KingSystem/System/OverlayArena.h"
#include <heap/seadExpHeap.h>
#include "KingSystem/Resource/resResourceMgrTask.h"
#include "KingSystem/Resource/resSystem.h"
#include "KingSystem/Resource/resUnit.h"
#include "KingSystem/Utils/HeapUtil.h"
namespace ksys {
OverlayArena::OverlayArena() {
mUnits.initOffset(res::ResourceUnit::getArenaUnitListNodeOffset());
mUnits2.initOffset(res::ResourceUnit::getArenaUnitListNode2Offset());
}
OverlayArena::~OverlayArena() {
destroy();
}
// branching at the end (csel instead of a branch)
#ifdef NON_MATCHING
bool OverlayArena::init(const OverlayArena::InitArg& arg) {
if (!arg.heap) {
res::stubbedLogFunction();
return false;
}
if (arg.size == 0)
res::stubbedLogFunction();
mFlags.change(Flag::_1, arg.set_flag_1);
mHeap = sead::ExpHeap::create(arg.size, arg.name, arg.heap, arg.alignment,
sead::Heap::cHeapDirection_Forward, true);
if (arg.use_best_fit_alloc_mode)
mHeap->setAllocMode(sead::ExpHeap::AllocMode::BestFit);
mHeapSize = mHeap->getSize();
_cc = 0;
mHeapFreeSize = mHeap->getFreeSize();
mHeapName = mHeap->getName();
mUsagePercentage = 0.0;
_c8 = 0;
mMinFreePercentage = arg.min_free_percentage;
if (res::ResourceMgrTask::instance())
res::ResourceMgrTask::instance()->insertOverlayArena(this);
mFlags.change(Flag::_20, arg.set_flag_20);
mFlags.change(Flag::_10, arg.set_flag_10);
struct UnusedTemp {
sead::SafeString str;
void* _10 = nullptr;
};
[[maybe_unused]] UnusedTemp temp;
temp.str = arg.name;
mFlags.change(Flag::_8, arg.set_flag_8);
return true;
}
#endif
void OverlayArena::stubbed() {}
void OverlayArena::updateFlag8(bool on) {
if (on != mFlags.isOn(Flag::_8) && mHeap)
mFlags.change(Flag::_8, on);
}
void OverlayArena::clearUnits() {
if (!mHeap)
return;
res::stubbedLogFunction();
auto lock = sead::makeScopedLock(mCS);
for (auto it = mUnits.robustBegin(), end = mUnits.robustEnd(); it != end; ++it) {
res::ResourceUnit* unit = std::addressof(*it);
res::stubbedLogFunction();
res::ResourceMgrTask::instance()->deregisterUnit(unit);
res::ResourceMgrTask::instance()->requestClearCacheForSync(&unit, true, false);
}
res::stubbedLogFunction();
}
bool OverlayArena::isFlag1Set() const {
return mFlags.isOn(Flag::_1);
}
bool OverlayArena::hasNoUnits() const {
return mUnits.isEmpty();
}
s32 OverlayArena::getNumUnits() const {
return mUnits.size();
}
bool OverlayArena::isFlag10Set() const {
return mFlags.isOn(Flag::_10);
}
bool OverlayArena::isFlag8Set() const {
return mFlags.isOn(Flag::_8);
}
bool OverlayArena::checkIsOom() const {
if (!mHeap)
return false;
const f32 used_size = mUsage1 + mUsage2;
const size_t heap_size = mHeap->getSize();
const f32 free_percentage =
100.0f *
std::max<f32>(1.0 - used_size / (heap_size - sead::ExpHeap::getManagementAreaSize(8)), 0);
if (free_percentage < mMinFreePercentage) {
if (res::returnFalse())
res::stubbedLogFunction();
setBloodyMoonReasonForOom_();
return true;
}
return false;
}
// FIXME: figure out what sead function this is
bool seadCheckPointer(void* ptr);
// branching
#ifdef NON_MATCHING
util::DualHeap* OverlayArena::makeDualHeap(u32 size, const sead::SafeString& name,
sead::Heap::HeapDirection direction,
res::ResourceUnit* unit, bool) {
if (!mHeap)
return nullptr;
const auto alignment = res::getDefaultAlignment();
const auto lock = sead::makeScopedLock(mCS);
auto* heap = util::DualHeap::tryCreate(size, name, mHeap, mHeap2, alignment, direction, false);
if (!heap) {
if (res::returnFalse())
res::stubbedLogFunction();
if (!x_1(size))
return nullptr;
heap = util::DualHeap::tryCreate(size, name, mHeap, mHeap2, alignment, direction, false);
if (!heap)
return nullptr;
}
if (unit && !seadCheckPointer(unit)) {
mUnits.pushBack(unit);
mFlags.set(Flag::_2);
}
mFlags.set(Flag::_4);
return heap;
}
#endif
void OverlayArena::addSize(s32 size) {
mSize += size;
}
void OverlayArena::addSize2(s32 size) {
mUsage1 += size;
}
} // namespace ksys