ksys/phys: Add ScopedWorldLock to simplify world locking/unlocking

This commit is contained in:
Léo Lam 2022-03-20 15:08:26 +01:00
parent cc270ee3ff
commit a98e5f6557
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
3 changed files with 39 additions and 15 deletions

View File

@ -267,9 +267,7 @@ void RayCast::worldRayCastImpl(hkpWorldRayCastOutput* output, ContactLayerType l
hkpWorldRayCastInput input; hkpWorldRayCastInput input;
fillCastInput(input, layer_type); fillCastInput(input, layer_type);
System::instance()->lockWorld(layer_type, "raycast", 0, OnlyLockIfNeeded::Yes); ScopedWorldLock lock{layer_type, "raycast", 0, OnlyLockIfNeeded::Yes};
auto world_guard = sead::makeScopeGuard(
[&] { System::instance()->unlockWorld(layer_type, "raycast", 0, OnlyLockIfNeeded::Yes); });
if (mNormalCheckingMode == NormalCheckingMode::DoNotCheck) { if (mNormalCheckingMode == NormalCheckingMode::DoNotCheck) {
if (mIgnoredGroups.size() > 0 || int(mIgnoredGroundHit) != GroundHit::Ignore) { if (mIgnoredGroups.size() > 0 || int(mIgnoredGroundHit) != GroundHit::Ignore) {

View File

@ -86,22 +86,22 @@ bool ShapeCast::doExecuteQuery(hkpCdPointCollector& cast_collector,
OnlyLockIfNeeded only_lock_if_needed) { OnlyLockIfNeeded only_lock_if_needed) {
const auto layer_type = mBody->getLayerType(); const auto layer_type = mBody->getLayerType();
System::instance()->lockWorld(layer_type, "shape_cast", 0, only_lock_if_needed); {
ScopedWorldLock lock{layer_type, "shape_cast", 0, only_lock_if_needed};
hkpLinearCastInput input; hkpLinearCastInput input;
loadFromVec3(&input.m_to, mTo); loadFromVec3(&input.m_to, mTo);
// Reset internal state. // Reset internal state.
cast_collector.reset(); cast_collector.reset();
if (_44 == 1) if (_44 == 1)
reset(); reset();
System::instance()->getHavokWorld(layer_type)->m_collisionInput->m_weldClosestPoints = System::instance()->getHavokWorld(layer_type)->m_collisionInput->m_weldClosestPoints =
bool(weld_closest_points); bool(weld_closest_points);
doCast(input, cast_collector, start_collector); doCast(input, cast_collector, start_collector);
}
System::instance()->unlockWorld(layer_type, "shape_cast", 0, only_lock_if_needed);
// Register every point that is in start_collector. // Register every point that is in start_collector.
auto* body = mBody; auto* body = mBody;

View File

@ -86,8 +86,11 @@ public:
void removeSystemGroupHandler(SystemGroupHandler* handler); void removeSystemGroupHandler(SystemGroupHandler* handler);
hkpWorld* getHavokWorld(ContactLayerType type) const; hkpWorld* getHavokWorld(ContactLayerType type) const;
// 0x0000007101215754
void lockWorld(ContactLayerType type, const char* description = nullptr, int b = 0, void lockWorld(ContactLayerType type, const char* description = nullptr, int b = 0,
OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No); OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No);
// 0x0000007101215784
void unlockWorld(ContactLayerType type, const char* description = nullptr, int b = 0, void unlockWorld(ContactLayerType type, const char* description = nullptr, int b = 0,
OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No); OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No);
@ -146,4 +149,27 @@ private:
}; };
KSYS_CHECK_SIZE_NX150(System, 0x480); KSYS_CHECK_SIZE_NX150(System, 0x480);
class ScopedWorldLock {
public:
explicit ScopedWorldLock(ContactLayerType type, const char* description = nullptr, int unk = 0,
OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No)
: mType(type), mDescription(description), mUnk(unk),
mOnlyLockIfNeeded(only_lock_if_needed) {
System::instance()->lockWorld(mType, mDescription, mUnk, mOnlyLockIfNeeded);
}
~ScopedWorldLock() {
System::instance()->unlockWorld(mType, mDescription, mUnk, mOnlyLockIfNeeded);
}
ScopedWorldLock(const ScopedWorldLock&) = delete;
auto operator=(const ScopedWorldLock&) = delete;
private:
ContactLayerType mType;
const char* mDescription;
int mUnk;
OnlyLockIfNeeded mOnlyLockIfNeeded;
};
} // namespace ksys::phys } // namespace ksys::phys