Skip to content

Commit

Permalink
feat: add BSGuarded (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
powerof3 authored Nov 22, 2023
1 parent fe9d605 commit 89fe996
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 15 deletions.
2 changes: 1 addition & 1 deletion CommonLibSF/include/RE/B/BGSInventoryItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace RE
public:
// members
BSTSmartPointer<ExtraDataList> extra; // 00
std::uint32_t unk10; // 10
std::uint32_t count; // 10
};
static_assert(sizeof(Stack) == 0x10);

Expand Down
47 changes: 47 additions & 0 deletions CommonLibSF/include/RE/B/BSLock.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,51 @@ namespace RE

using BSAutoWriteLock = BSAutoLock<BSReadWriteLock, BSAutoLockWriteLockPolicy>;
static_assert(sizeof(BSAutoWriteLock) == 0x8);

template <class T, class Mutex>
class BSGuarded
{
public:
template <class U, template <class> class Policy = BSAutoLockDefaultPolicy>
class Guard
{
public:
explicit Guard(U& a_data, Mutex& a_mutex) :
_guard(a_mutex),
_data(a_data)
{}

U& operator*() { return _data; }
U& operator->() { return _data; }
const U& operator*() const { return _data; }
const U& operator->() const { return _data; }

private:
// members
BSAutoLock<Mutex, Policy> _guard{}; // 0 - Lock guard is first here?
U& _data; // 8
};

auto lock()
{
return Guard<T>(_data, _lock);
}

auto lock_read() const
requires std::is_same_v<Mutex, BSReadWriteLock>
{
return Guard<const T, BSAutoLockReadLockPolicy>(_data, _lock);
}

auto lock_write()
requires std::is_same_v<Mutex, BSReadWriteLock>
{
return Guard<T, BSAutoLockWriteLockPolicy>(_data, _lock);
}

private:
// members
T _data{}; // ??
mutable Mutex _lock{}; // ??
};
}
20 changes: 9 additions & 11 deletions CommonLibSF/include/RE/T/TESObjectREFR.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,17 +386,15 @@ namespace RE
void Unlock();

// members
OBJ_REFR data; // 0A0
BGSInventoryList* inventoryList; // 0D0 - this + lock is one struct?
mutable BSReadWriteLock inventoryListLock; // 0D8
TESObjectCELL* parentCell; // 0E0
LOADED_REF_DATA* loadedData; // 0E8 - same as above
mutable BSReadWriteLock loadedDataLock; // 0F0
BSTSmartPointer<ExtraDataList> extraDataList; // 0F8
BGSLocalizedString unk100; // 100 - empty?
std::uint16_t scale; // 108
bool unk10A; // 10A
std::uint8_t flags; // 10B
OBJ_REFR data; // 0A0
BSGuarded<BGSInventoryList*, BSReadWriteLock> inventoryList; // 0D0
TESObjectCELL* parentCell; // 0E0
BSGuarded<LOADED_REF_DATA*, BSReadWriteLock> loadedData; // 0E8
BSTSmartPointer<ExtraDataList> extraDataList; // 0F8
BGSLocalizedString unk100; // 100 - empty?
std::uint16_t scale; // 108
std::uint8_t unk10A; // 10A
std::uint8_t flags; // 10B

private:
void AddLockChange();
Expand Down
5 changes: 2 additions & 3 deletions CommonLibSF/src/RE/T/TESObjectREFR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ namespace RE

void TESObjectREFR::ForEachInventoryItem(std::function<BSContainer::ForEachResult(const BGSInventoryItem&)> a_callback) const
{
BSAutoReadLock locker(inventoryListLock);
if (inventoryList) {
for (const auto& invItem : inventoryList->data) {
if (const auto invList = inventoryList.lock_read(); *invList) {
for (const auto& invItem : invList->data) {
if (invItem.object && a_callback(invItem) == BSContainer::ForEachResult::kStop) {
break;
}
Expand Down

0 comments on commit 89fe996

Please sign in to comment.