mirror of https://github.com/zeldaret/botw.git
ksys/act: Implement BaseProcLink
This commit is contained in:
parent
f92ab2f559
commit
afde5b2775
|
@ -35,8 +35,8 @@ add_executable(uking
|
||||||
src/KingSystem/ActorSystem/actBaseProcJob.h
|
src/KingSystem/ActorSystem/actBaseProcJob.h
|
||||||
src/KingSystem/ActorSystem/actBaseProcJobHandler.cpp
|
src/KingSystem/ActorSystem/actBaseProcJobHandler.cpp
|
||||||
src/KingSystem/ActorSystem/actBaseProcJobHandler.h
|
src/KingSystem/ActorSystem/actBaseProcJobHandler.h
|
||||||
src/KingSystem/ActorSystem/actBaseProcLinkDataMgr.cpp
|
src/KingSystem/ActorSystem/actBaseProcLink.cpp
|
||||||
src/KingSystem/ActorSystem/actBaseProcLinkDataMgr.h
|
src/KingSystem/ActorSystem/actBaseProcLink.h
|
||||||
src/KingSystem/ActorSystem/actBaseProcMap.cpp
|
src/KingSystem/ActorSystem/actBaseProcMap.cpp
|
||||||
src/KingSystem/ActorSystem/actBaseProcMap.h
|
src/KingSystem/ActorSystem/actBaseProcMap.h
|
||||||
src/KingSystem/ActorSystem/actBaseProcMgr.cpp
|
src/KingSystem/ActorSystem/actBaseProcMgr.cpp
|
||||||
|
|
|
@ -74114,7 +74114,7 @@
|
||||||
0x0000007100dca6d4,_ZN15ActorInstParams3BufaSERS0_,56,
|
0x0000007100dca6d4,_ZN15ActorInstParams3BufaSERS0_,56,
|
||||||
0x0000007100dca70c,_ZN13ActorAccessorD2Ev,56,_ZN4ksys3act24ActorLinkConstDataAccessD1Ev
|
0x0000007100dca70c,_ZN13ActorAccessorD2Ev,56,_ZN4ksys3act24ActorLinkConstDataAccessD1Ev
|
||||||
0x0000007100dca744,ActorAccessor::acquire,88,_ZN4ksys3act24ActorLinkConstDataAccess7acquireEPNS0_8BaseProcE
|
0x0000007100dca744,ActorAccessor::acquire,88,_ZN4ksys3act24ActorLinkConstDataAccess7acquireEPNS0_8BaseProcE
|
||||||
0x0000007100dca79c,act::acquireActorFromGameOrHavokThread,256,_ZN4ksys3act11acquireProcEPNS0_24ActorLinkConstDataAccessEPNS0_8BaseProcERKN4sead14SafeStringBaseIcEE
|
0x0000007100dca79c,act::acquireActorFromGameOrHavokThread,256,_ZN4ksys3act11acquireProcEPNS0_24ActorLinkConstDataAccessEPNS0_8BaseProcERKN4sead14SafeStringBaseIcEEi
|
||||||
0x0000007100dca89c,GameFramework::ctor,96,
|
0x0000007100dca89c,GameFramework::ctor,96,
|
||||||
0x0000007100dca8fc,GameFramework::dtor,64,
|
0x0000007100dca8fc,GameFramework::dtor,64,
|
||||||
0x0000007100dca93c,GameFramework::dtorDelete,72,
|
0x0000007100dca93c,GameFramework::dtorDelete,72,
|
||||||
|
@ -89523,18 +89523,18 @@
|
||||||
0x00000071011bc42c,sub_71011BC42C,56,
|
0x00000071011bc42c,sub_71011BC42C,56,
|
||||||
0x00000071011bc464,sinitBaseProcHandle,172,
|
0x00000071011bc464,sinitBaseProcHandle,172,
|
||||||
0x00000071011bc510,_ZN12BaseProcLinkC2Ev,20,_ZN4ksys3act12BaseProcLinkC1Ev
|
0x00000071011bc510,_ZN12BaseProcLinkC2Ev,20,_ZN4ksys3act12BaseProcLinkC1Ev
|
||||||
0x00000071011bc524,_ZN12BaseProcLink12acquireActorER13ActorAccessorP9ActorBase,308,
|
0x00000071011bc524,_ZN12BaseProcLink12acquireActorER13ActorAccessorP9ActorBase,308,_ZN4ksys3act12BaseProcLink7getProcEPNS0_24ActorLinkConstDataAccessEPNS0_8BaseProcE
|
||||||
0x00000071011bc658,BaseProcLinkData::lockCritSectionOnGameThreadOrHavokThread,68,_ZN4ksys3act16BaseProcLinkData12lockIfNeededEv
|
0x00000071011bc658,BaseProcLinkData::lockCritSectionOnGameThreadOrHavokThread,68,_ZN4ksys3act16BaseProcLinkData12lockIfNeededEv
|
||||||
0x00000071011bc69c,BaseProcLinkData::checkIdAndEngaged,52,_ZNK4ksys3act16BaseProcLinkData7getProcEjb
|
0x00000071011bc69c,BaseProcLinkData::checkIdAndEngaged,52,_ZNK4ksys3act16BaseProcLinkData7getProcEjb
|
||||||
0x00000071011bc6d0,_ZN12BaseProcLink12fromAccessorER13ActorAccessor,276,
|
0x00000071011bc6d0,_ZN12BaseProcLink12fromAccessorER13ActorAccessor,276,_ZN4ksys3act12BaseProcLink7getProcEPNS0_24ActorLinkConstDataAccessE
|
||||||
0x00000071011bc7e4,BaseProcLink::checkHasActorById,40,
|
0x00000071011bc7e4,BaseProcLink::checkHasActorById,40,_ZNK4ksys3act12BaseProcLink11hasProcByIdEPNS0_8BaseProcE
|
||||||
0x00000071011bc80c,_ZN12BaseProcLinkeqERS_,152,
|
0x00000071011bc80c,_ZN12BaseProcLinkeqERS_,152,_ZNK4ksys3act12BaseProcLinkeqERKS1_
|
||||||
0x00000071011bc8a4,BaseProcLink::hasAcquiredActor,100,
|
0x00000071011bc8a4,BaseProcLink::hasAcquiredActor,100,_ZNK4ksys3act12BaseProcLink7hasProcEv
|
||||||
0x00000071011bc908,BaseProcLink::fromActor,328,
|
0x00000071011bc908,BaseProcLink::fromActor,328,_ZN4ksys3act12BaseProcLink7acquireEPNS0_8BaseProcEb
|
||||||
0x00000071011bca50,BaseProcLink::reset,52,
|
0x00000071011bca50,BaseProcLink::reset,52,_ZN4ksys3act12BaseProcLink5resetEv
|
||||||
0x00000071011bca84,BaseProcLink::isStateCalc,204,
|
0x00000071011bca84,BaseProcLink::isStateCalc,204,_ZNK4ksys3act12BaseProcLink18hasProcInCalcStateEv
|
||||||
0x00000071011bcb50,BaseProcLink::isActor,228,
|
0x00000071011bcb50,BaseProcLink::isActor,228,_ZNK4ksys3act12BaseProcLink30isAccessingSpecifiedProcUnsafeEPNS0_8BaseProcE
|
||||||
0x00000071011bcc34,_ZN12BaseProcLinkaSERS_,80,
|
0x00000071011bcc34,_ZN12BaseProcLinkaSERS_,80,_ZN4ksys3act12BaseProcLinkaSERKS1_
|
||||||
0x00000071011bcc84,BaseProcLinkDataMgr::deleteInstance,132,_ZN4ksys3act19BaseProcLinkDataMgr18SingletonDisposer_D2Ev
|
0x00000071011bcc84,BaseProcLinkDataMgr::deleteInstance,132,_ZN4ksys3act19BaseProcLinkDataMgr18SingletonDisposer_D2Ev
|
||||||
0x00000071011bcd08,BaseProcLinkDataMgr::deleteInstance2,140,_ZN4ksys3act19BaseProcLinkDataMgr18SingletonDisposer_D0Ev
|
0x00000071011bcd08,BaseProcLinkDataMgr::deleteInstance2,140,_ZN4ksys3act19BaseProcLinkDataMgr18SingletonDisposer_D0Ev
|
||||||
0x00000071011bcd94,BaseProcLinkDataMgr::createInstance,212,_ZN4ksys3act19BaseProcLinkDataMgr14createInstanceEPN4sead4HeapE
|
0x00000071011bcd94,BaseProcLinkDataMgr::createInstance,212,_ZN4ksys3act19BaseProcLinkDataMgr14createInstanceEPN4sead4HeapE
|
||||||
|
|
Can't render this file because it is too large.
|
2
lib/sead
2
lib/sead
|
@ -1 +1 @@
|
||||||
Subproject commit c53aff46fc42344958c42d0b69b27f992fc8d979
|
Subproject commit 9f70679d4cfbce260d967b27adf4c17f17ac8e34
|
|
@ -33,7 +33,8 @@ void ActorLinkConstDataAccess::debugLog(s32, const sead::SafeString&) {
|
||||||
// Intentionally left empty.
|
// Intentionally left empty.
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acquireProc(ActorLinkConstDataAccess* accessor, BaseProc* proc, const sead::SafeString& from) {
|
bool acquireProc(ActorLinkConstDataAccess* accessor, BaseProc* proc, const sead::SafeString& from,
|
||||||
|
s32) {
|
||||||
bool acquired = false;
|
bool acquired = false;
|
||||||
|
|
||||||
if (accessor) {
|
if (accessor) {
|
||||||
|
|
|
@ -35,7 +35,8 @@ private:
|
||||||
|
|
||||||
/// Acquire the specified BaseProc using `accessor`. Using ActorLinkConstDataAccess is mandatory
|
/// Acquire the specified BaseProc using `accessor`. Using ActorLinkConstDataAccess is mandatory
|
||||||
/// when acquiring from a low priority thread (see BaseProcMgr for a definition).
|
/// when acquiring from a low priority thread (see BaseProcMgr for a definition).
|
||||||
bool acquireProc(ActorLinkConstDataAccess* accessor, BaseProc* proc, const sead::SafeString& from);
|
bool acquireProc(ActorLinkConstDataAccess* accessor, BaseProc* proc, const sead::SafeString& from,
|
||||||
|
s32 = 2);
|
||||||
|
|
||||||
} // namespace act
|
} // namespace act
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <prim/seadSafeString.h>
|
#include <prim/seadSafeString.h>
|
||||||
|
|
||||||
#include "KingSystem/ActorSystem/actBaseProc.h"
|
#include "KingSystem/ActorSystem/actBaseProc.h"
|
||||||
|
#include "KingSystem/ActorSystem/actBaseProcLink.h"
|
||||||
#include "KingSystem/MessageSystem/mesTransceiver.h"
|
#include "KingSystem/MessageSystem/mesTransceiver.h"
|
||||||
#include "KingSystem/Utils/Types.h"
|
#include "KingSystem/Utils/Types.h"
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
#include "KingSystem/ActorSystem/actBaseProc.h"
|
#include "KingSystem/ActorSystem/actBaseProc.h"
|
||||||
#include "KingSystem/ActorSystem/actBaseProcJobHandler.h"
|
#include "KingSystem/ActorSystem/actBaseProcJobHandler.h"
|
||||||
#include "KingSystem/ActorSystem/actBaseProcLinkDataMgr.h"
|
#include "KingSystem/ActorSystem/actBaseProcLink.h"
|
||||||
#include "KingSystem/ActorSystem/actBaseProcMgr.h"
|
#include "KingSystem/ActorSystem/actBaseProcMgr.h"
|
||||||
#include "KingSystem/ActorSystem/actBaseProcUnit.h"
|
#include "KingSystem/ActorSystem/actBaseProcUnit.h"
|
||||||
#include "KingSystem/Terrain/teraSystem.h"
|
#include "KingSystem/Terrain/teraSystem.h"
|
||||||
|
|
||||||
namespace ksys::act {
|
namespace ksys::act {
|
||||||
|
|
||||||
BaseProcLink::BaseProcLink() = default;
|
|
||||||
|
|
||||||
BaseProc::BaseProc(const CreateArg& arg)
|
BaseProc::BaseProc(const CreateArg& arg)
|
||||||
: mName(arg.actor_name), mPriority(arg.class_info->priority) {
|
: mName(arg.actor_name), mPriority(arg.class_info->priority) {
|
||||||
BaseProcMgr* mgr = BaseProcMgr::instance();
|
BaseProcMgr* mgr = BaseProcMgr::instance();
|
||||||
|
|
|
@ -22,25 +22,6 @@ class ActorLinkConstDataAccess;
|
||||||
class BaseProc;
|
class BaseProc;
|
||||||
class BaseProcLinkData;
|
class BaseProcLinkData;
|
||||||
class BaseProcJobHandler;
|
class BaseProcJobHandler;
|
||||||
|
|
||||||
class BaseProcLink {
|
|
||||||
public:
|
|
||||||
BaseProcLink();
|
|
||||||
~BaseProcLink() { reset(); }
|
|
||||||
BaseProcLink& operator=(const BaseProcLink&);
|
|
||||||
bool operator==(const BaseProcLink&) const;
|
|
||||||
bool operator!=(const BaseProcLink& rhs) const { return !operator==(rhs); }
|
|
||||||
BaseProc* fromAccessorAndActor(ActorLinkConstDataAccess&, BaseProc*);
|
|
||||||
BaseProc* fromAccessor(ActorLinkConstDataAccess&);
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
private:
|
|
||||||
BaseProcLinkData* mData = nullptr;
|
|
||||||
u32 mId = -1;
|
|
||||||
bool mAcquired = false;
|
|
||||||
};
|
|
||||||
KSYS_CHECK_SIZE_NX150(BaseProcLink, 0x10);
|
|
||||||
|
|
||||||
class BaseProcUnit;
|
class BaseProcUnit;
|
||||||
|
|
||||||
class BaseProcHandle {
|
class BaseProcHandle {
|
||||||
|
@ -108,6 +89,9 @@ public:
|
||||||
bool deleteLater(DeleteReason reason);
|
bool deleteLater(DeleteReason reason);
|
||||||
void freeLinkData();
|
void freeLinkData();
|
||||||
|
|
||||||
|
u32 getId() const { return mId; }
|
||||||
|
const sead::SafeString& getName() const { return mName; }
|
||||||
|
|
||||||
u8 getPriority() const { return mPriority; }
|
u8 getPriority() const { return mPriority; }
|
||||||
void setPriority(u8 priority) { mPriority = priority; }
|
void setPriority(u8 priority) { mPriority = priority; }
|
||||||
|
|
||||||
|
@ -118,6 +102,7 @@ public:
|
||||||
|
|
||||||
/// For BaseProcLink or ActorLinkConstDataAccess.
|
/// For BaseProcLink or ActorLinkConstDataAccess.
|
||||||
bool acquire(ActorLinkConstDataAccess& accessor);
|
bool acquire(ActorLinkConstDataAccess& accessor);
|
||||||
|
BaseProcLinkData* getBaseProcLinkData() const { return mBaseProcLinkData; }
|
||||||
/// For BaseProcLink or ActorLinkConstDataAccess.
|
/// For BaseProcLink or ActorLinkConstDataAccess.
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
#include "KingSystem/ActorSystem/actBaseProcLink.h"
|
||||||
|
#include <prim/seadScopedLock.h>
|
||||||
|
#include <thread/seadThread.h>
|
||||||
|
#include "KingSystem/ActorSystem/actActorLinkConstDataAccess.h"
|
||||||
|
#include "KingSystem/ActorSystem/actBaseProc.h"
|
||||||
|
#include "KingSystem/ActorSystem/actBaseProcMgr.h"
|
||||||
|
|
||||||
|
namespace ksys::act {
|
||||||
|
|
||||||
|
BaseProcLink::BaseProcLink() = default;
|
||||||
|
|
||||||
|
BaseProcLink& BaseProcLink::operator=(const BaseProcLink& rhs) {
|
||||||
|
if (this == &rhs)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
if (rhs.mData)
|
||||||
|
mData = rhs.mData;
|
||||||
|
mId = rhs.mId;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseProcLink::operator==(const BaseProcLink& rhs) const {
|
||||||
|
return (!hasProc() && !rhs.hasProc()) || mId == rhs.mId;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseProcLink::hasProc() const {
|
||||||
|
return getProc();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseProcLink::hasProcInCalcState() const {
|
||||||
|
return getProcInContext(
|
||||||
|
[](BaseProc* proc) { return proc && proc->getState() == BaseProc::State::Calc; });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseProcLink::hasProcById(BaseProc* proc) const {
|
||||||
|
return proc != nullptr & mId != cInvalidId && mId == proc->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseProc* BaseProcLink::getProc(ActorLinkConstDataAccess* accessor, BaseProc* other_proc) {
|
||||||
|
return getProcInContext([&](BaseProc* proc) -> BaseProc* {
|
||||||
|
if (proc && acquireProc(accessor, proc, "frm::BaseProcLink") &&
|
||||||
|
BaseProcMgr::instance()->isAccessingProcSafe(proc, other_proc)) {
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseProc* BaseProcLink::getProc(ActorLinkConstDataAccess* accessor) {
|
||||||
|
return getProcInContext([&](BaseProc* proc) -> BaseProc* {
|
||||||
|
if (proc && acquireProc(accessor, proc, "frm::BaseProcLink"))
|
||||||
|
return proc;
|
||||||
|
return nullptr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseProcLink::acquire(BaseProc* proc, bool acquire_immediately) {
|
||||||
|
reset();
|
||||||
|
|
||||||
|
if (!proc || proc->isDeletedOrDeleting())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mData = proc->getBaseProcLinkData();
|
||||||
|
|
||||||
|
if (!mData) {
|
||||||
|
static constexpr const char* sStateNames[] = {"Init", "Calc", "Sleep", "Delete"};
|
||||||
|
sead::FixedSafeString<256> message;
|
||||||
|
message.format("%s:%s", proc->getName().cstr(), sStateNames[u8(proc->getState())]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mId = proc->getId();
|
||||||
|
if (acquire_immediately) {
|
||||||
|
mData->mRefCount.increment();
|
||||||
|
mAcquired = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseProcLink::reset() {
|
||||||
|
if (mAcquired) {
|
||||||
|
mAcquired = false;
|
||||||
|
if (mData)
|
||||||
|
mData->mRefCount.decrement();
|
||||||
|
}
|
||||||
|
mId = cInvalidId;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseProcLink::isAccessingSpecifiedProcUnsafe(BaseProc* other) const {
|
||||||
|
return getProcInContext([&](BaseProc* proc) {
|
||||||
|
return proc && !BaseProcMgr::instance()->isAccessingProcSafe(proc, other);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SEAD_SINGLETON_DISPOSER_IMPL(BaseProcLinkDataMgr)
|
||||||
|
|
||||||
|
BaseProc* BaseProcLinkData::getProc(u32 id, bool allow_deleted) const {
|
||||||
|
if (id == u32(-1) || mId != id)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (!allow_deleted && (!mProc || mProc->getState() == BaseProc::State::Delete))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return mProc;
|
||||||
|
}
|
||||||
|
|
||||||
|
sead::CriticalSection* BaseProcLinkData::lockIfNeeded() {
|
||||||
|
if (BaseProcMgr::instance()->isHighPriorityThread())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
mCS.lock();
|
||||||
|
return &mCS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseProcLinkDataMgr::acquireLink(BaseProc* proc) {
|
||||||
|
auto lock = sead::makeScopedLock(mCS);
|
||||||
|
s32 index = mIndex;
|
||||||
|
for (s32 i = 0; i < mData.size(); ++i) {
|
||||||
|
const s32 j = index == 0x800 ? 0 : index;
|
||||||
|
auto& data = mData[j];
|
||||||
|
if (data.mId == u32(-1)) {
|
||||||
|
{
|
||||||
|
auto data_lock = sead::makeScopedLock(data.mCS);
|
||||||
|
data.mProc = proc;
|
||||||
|
data.mId = proc->mId;
|
||||||
|
proc->mBaseProcLinkData = &data;
|
||||||
|
}
|
||||||
|
mIndex = j + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
index = j + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (s32 i = 0; i < mData.size(); ++i) {
|
||||||
|
auto data_lock = sead::makeScopedLock(mData[i].mCS);
|
||||||
|
// Debug code was probably here?
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseProcLinkDataMgr::releaseLink(BaseProc* proc) {
|
||||||
|
auto* data = proc->mBaseProcLinkData;
|
||||||
|
if (!data)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto thread = sead::ThreadMgr::instance()->getCurrentThread();
|
||||||
|
thread->getPriority();
|
||||||
|
|
||||||
|
auto lock = sead::makeScopedLock(data->mCS);
|
||||||
|
data->mProc = nullptr;
|
||||||
|
data->mId = -1;
|
||||||
|
proc->mBaseProcLinkData = nullptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ksys::act
|
|
@ -0,0 +1,119 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <basis/seadTypes.h>
|
||||||
|
#include <container/seadSafeArray.h>
|
||||||
|
#include <heap/seadDisposer.h>
|
||||||
|
#include <prim/seadScopeGuard.h>
|
||||||
|
#include <prim/seadScopedLock.h>
|
||||||
|
#include <thread/seadAtomic.h>
|
||||||
|
#include <thread/seadCriticalSection.h>
|
||||||
|
#include "KingSystem/Utils/Types.h"
|
||||||
|
|
||||||
|
namespace ksys::act {
|
||||||
|
|
||||||
|
class ActorLinkConstDataAccess;
|
||||||
|
class BaseProc;
|
||||||
|
class BaseProcLinkData;
|
||||||
|
|
||||||
|
class BaseProcLink {
|
||||||
|
public:
|
||||||
|
BaseProcLink();
|
||||||
|
~BaseProcLink() { reset(); }
|
||||||
|
BaseProcLink& operator=(const BaseProcLink& rhs);
|
||||||
|
|
||||||
|
bool operator==(const BaseProcLink& rhs) const;
|
||||||
|
bool operator!=(const BaseProcLink& rhs) const { return !operator==(rhs); }
|
||||||
|
explicit operator bool() const { return hasProc(); }
|
||||||
|
|
||||||
|
bool hasProc() const;
|
||||||
|
bool hasProcInCalcState() const;
|
||||||
|
bool hasProcById(BaseProc* proc) const;
|
||||||
|
|
||||||
|
BaseProc* getProc(ActorLinkConstDataAccess* accessor, BaseProc* other_proc);
|
||||||
|
BaseProc* getProc(ActorLinkConstDataAccess* accessor);
|
||||||
|
|
||||||
|
/// Acquire the specified BaseProc.
|
||||||
|
/// If a BaseProc has already been specified, it is released.
|
||||||
|
///
|
||||||
|
/// @param acquire_immediately If true, the BaseProc's reference count is immediately
|
||||||
|
/// incremented. Otherwise, full acquisition is delayed until
|
||||||
|
/// the next call to getProc(accessor[, proc]).
|
||||||
|
bool acquire(BaseProc* proc, bool acquire_immediately);
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
bool isAccessingSpecifiedProcUnsafe(BaseProc* other) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr u32 cInvalidId = -1;
|
||||||
|
|
||||||
|
BaseProc* getProc() const;
|
||||||
|
|
||||||
|
template <typename Function>
|
||||||
|
auto getProcInContext(const Function& function) const;
|
||||||
|
|
||||||
|
BaseProcLinkData* mData = nullptr;
|
||||||
|
u32 mId = cInvalidId;
|
||||||
|
bool mAcquired = false;
|
||||||
|
};
|
||||||
|
KSYS_CHECK_SIZE_NX150(BaseProcLink, 0x10);
|
||||||
|
|
||||||
|
class BaseProcLinkData {
|
||||||
|
public:
|
||||||
|
u32 id() const { return mId; }
|
||||||
|
s32 refCount() const { return mRefCount; }
|
||||||
|
|
||||||
|
/// Get the stored BaseProc.
|
||||||
|
BaseProc* getProc() const { return mProc; }
|
||||||
|
/// Get the stored BaseProc or nullptr if its ID or state are unexpected.
|
||||||
|
/// @param id The expected ID.
|
||||||
|
/// @param allow_deleted Whether to allow the BaseProc to be in the Delete state.
|
||||||
|
BaseProc* getProc(u32 id, bool allow_deleted) const;
|
||||||
|
|
||||||
|
/// Locks the critical section if on a low priority thread and returns it;
|
||||||
|
/// unlocking it is the responsibility of the caller.
|
||||||
|
/// Returns nullptr if on a high priority thread. In that case, nothing needs to be done.
|
||||||
|
sead::CriticalSection* lockIfNeeded();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class BaseProcLink;
|
||||||
|
friend class BaseProcLinkDataMgr;
|
||||||
|
|
||||||
|
sead::CriticalSection mCS;
|
||||||
|
u32 mId = -1;
|
||||||
|
BaseProc* mProc = nullptr;
|
||||||
|
sead::Atomic<s32> mRefCount = 0;
|
||||||
|
};
|
||||||
|
KSYS_CHECK_SIZE_NX150(BaseProcLinkData, 0x58);
|
||||||
|
|
||||||
|
class BaseProcLinkDataMgr {
|
||||||
|
SEAD_SINGLETON_DISPOSER(BaseProcLinkDataMgr)
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool acquireLink(BaseProc* proc);
|
||||||
|
bool releaseLink(BaseProc* proc);
|
||||||
|
|
||||||
|
private:
|
||||||
|
sead::CriticalSection mCS;
|
||||||
|
s32 mIndex = 0;
|
||||||
|
sead::SafeArray<BaseProcLinkData, 2048> mData{};
|
||||||
|
};
|
||||||
|
KSYS_CHECK_SIZE_NX150(BaseProcLinkDataMgr, 0x2C068);
|
||||||
|
|
||||||
|
inline BaseProc* BaseProcLink::getProc() const {
|
||||||
|
return mData->getProc(mId, mAcquired);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Function>
|
||||||
|
inline auto BaseProcLink::getProcInContext(const Function& function) const {
|
||||||
|
if (mId == cInvalidId)
|
||||||
|
return function(nullptr);
|
||||||
|
|
||||||
|
const auto guard = sead::makeScopeGuard([crit_section = mData->lockIfNeeded()] {
|
||||||
|
if (crit_section)
|
||||||
|
crit_section->unlock();
|
||||||
|
});
|
||||||
|
|
||||||
|
return function(getProc());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ksys::act
|
|
@ -1,71 +0,0 @@
|
||||||
#include "KingSystem/ActorSystem/actBaseProcLinkDataMgr.h"
|
|
||||||
#include <prim/seadScopedLock.h>
|
|
||||||
#include <thread/seadThread.h>
|
|
||||||
#include "KingSystem/ActorSystem/actBaseProc.h"
|
|
||||||
#include "KingSystem/ActorSystem/actBaseProcMgr.h"
|
|
||||||
|
|
||||||
namespace ksys::act {
|
|
||||||
|
|
||||||
SEAD_SINGLETON_DISPOSER_IMPL(BaseProcLinkDataMgr)
|
|
||||||
|
|
||||||
BaseProc* BaseProcLinkData::getProc(u32 id, bool allow_deleted) const {
|
|
||||||
if (id == u32(-1) || mId != id)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (!allow_deleted && mProc && mProc->getState() == BaseProc::State::Delete)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return mProc;
|
|
||||||
}
|
|
||||||
|
|
||||||
sead::CriticalSection* BaseProcLinkData::lockIfNeeded() {
|
|
||||||
if (BaseProcMgr::instance()->isHighPriorityThread())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
mCS.lock();
|
|
||||||
return &mCS;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BaseProcLinkDataMgr::acquireLink(BaseProc* proc) {
|
|
||||||
auto lock = sead::makeScopedLock(mCS);
|
|
||||||
s32 index = mIndex;
|
|
||||||
for (s32 i = 0; i < mData.size(); ++i) {
|
|
||||||
const s32 j = index == 0x800 ? 0 : index;
|
|
||||||
auto& data = mData[j];
|
|
||||||
if (data.mId == u32(-1)) {
|
|
||||||
{
|
|
||||||
auto data_lock = sead::makeScopedLock(data.mCS);
|
|
||||||
data.mProc = proc;
|
|
||||||
data.mId = proc->mId;
|
|
||||||
proc->mBaseProcLinkData = &data;
|
|
||||||
}
|
|
||||||
mIndex = j + 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
index = j + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (s32 i = 0; i < mData.size(); ++i) {
|
|
||||||
auto data_lock = sead::makeScopedLock(mData[i].mCS);
|
|
||||||
// Debug code was probably here?
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BaseProcLinkDataMgr::releaseLink(BaseProc* proc) {
|
|
||||||
auto* data = proc->mBaseProcLinkData;
|
|
||||||
if (!data)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const auto thread = sead::ThreadMgr::instance()->getCurrentThread();
|
|
||||||
thread->getPriority();
|
|
||||||
|
|
||||||
auto lock = sead::makeScopedLock(data->mCS);
|
|
||||||
data->mProc = nullptr;
|
|
||||||
data->mId = -1;
|
|
||||||
proc->mBaseProcLinkData = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ksys::act
|
|
|
@ -1,54 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <container/seadSafeArray.h>
|
|
||||||
#include <heap/seadDisposer.h>
|
|
||||||
#include <prim/seadScopedLock.h>
|
|
||||||
#include <thread/seadCriticalSection.h>
|
|
||||||
#include "KingSystem/Utils/Types.h"
|
|
||||||
|
|
||||||
namespace ksys::act {
|
|
||||||
|
|
||||||
class BaseProc;
|
|
||||||
|
|
||||||
class BaseProcLinkData {
|
|
||||||
public:
|
|
||||||
u32 id() const { return mId; }
|
|
||||||
s32 refCount() const { return mRefCount; }
|
|
||||||
|
|
||||||
/// Get the stored BaseProc.
|
|
||||||
BaseProc* getProc() const { return mProc; }
|
|
||||||
/// Get the stored BaseProc or nullptr if its ID or state are unexpected.
|
|
||||||
/// @param id The expected ID.
|
|
||||||
/// @param allow_deleted Whether to allow the BaseProc to be in the Delete state.
|
|
||||||
BaseProc* getProc(u32 id, bool allow_deleted) const;
|
|
||||||
|
|
||||||
/// Locks the critical section if on a low priority thread and returns it;
|
|
||||||
/// unlocking it is the responsibility of the caller.
|
|
||||||
/// Returns nullptr if on a high priority thread. In that case, nothing needs to be done.
|
|
||||||
sead::CriticalSection* lockIfNeeded();
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class BaseProcLinkDataMgr;
|
|
||||||
|
|
||||||
sead::CriticalSection mCS;
|
|
||||||
u32 mId = -1;
|
|
||||||
BaseProc* mProc = nullptr;
|
|
||||||
s32 mRefCount = 0;
|
|
||||||
};
|
|
||||||
KSYS_CHECK_SIZE_NX150(BaseProcLinkData, 0x58);
|
|
||||||
|
|
||||||
class BaseProcLinkDataMgr {
|
|
||||||
SEAD_SINGLETON_DISPOSER(BaseProcLinkDataMgr)
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool acquireLink(BaseProc* proc);
|
|
||||||
bool releaseLink(BaseProc* proc);
|
|
||||||
|
|
||||||
private:
|
|
||||||
sead::CriticalSection mCS;
|
|
||||||
s32 mIndex = 0;
|
|
||||||
sead::SafeArray<BaseProcLinkData, 2048> mData{};
|
|
||||||
};
|
|
||||||
KSYS_CHECK_SIZE_NX150(BaseProcLinkDataMgr, 0x2C068);
|
|
||||||
|
|
||||||
} // namespace ksys::act
|
|
Loading…
Reference in New Issue