Skip to content

Commit

Permalink
feat!: add ExtraDataList, BSExtraData
Browse files Browse the repository at this point in the history
  • Loading branch information
powerof3 committed Oct 19, 2023
1 parent bc267f4 commit c1db748
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
29 changes: 29 additions & 0 deletions CommonLibSF/include/RE/B/BSExtraData.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include "RE/E/ExtraDataTypes.h"

namespace RE
{
class BSExtraData
{
public:
SF_RTTI_VTABLE(BSExtraData);
SF_EXTRADATATYPE(None);

virtual ~BSExtraData(); // 00

// add
virtual void Unk_01(); // 01
virtual void Unk_02(); // 02
virtual void Unk_03(); // 03
virtual void Unk_04(); // 04
virtual void Unk_05(); // 05
virtual void Unk_06(); // 06

// members
BSExtraData* next; // 08
std::uint16_t flags; // 10
stl::enumeration<ExtraDataType, std::uint8_t> type; // 12
};
static_assert(sizeof(BSExtraData) == 0x18);
}
85 changes: 85 additions & 0 deletions CommonLibSF/include/RE/E/ExtraDataList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#pragma once

#include "RE/B/BSExtraData.h"
#include "RE/B/BSIntrusiveRefCounted.h"
#include "RE/B/BSLock.h"
#include "RE/E/ExtraDataTypes.h"

namespace RE
{
class BaseExtraList
{
public:
void AddExtra(BSExtraData* a_extra)
{
using func_t = decltype(&BaseExtraList::AddExtra);
REL::Relocation<func_t> func{ REL::ID(83084) };
return func(this, a_extra);
}

[[nodiscard]] BSExtraData* GetByType(ExtraDataType a_type) const noexcept
{
using func_t = decltype(&BaseExtraList::GetByType);
REL::Relocation<func_t> func{ REL::ID(83208) };
return func(this, a_type);
}

private:
// members
BSExtraData* _head{ nullptr }; // 00
BSExtraData** _tail{ std::addressof(_head) }; // 08
std::uint8_t* _flags{ nullptr }; // 10
};
static_assert(sizeof(BaseExtraList) == 0x18);

namespace detail
{
template <class T>
concept ExtraDataListConstraint =
std::derived_from<T, BSExtraData> &&
!std::is_pointer_v<T> &&
!std::is_reference_v<T>;
}

class ExtraDataList :
public BSIntrusiveRefCounted // 00
{
public:
void AddExtra(BSExtraData* a_extra)
{
const BSAutoWriteLock l{ _extraRWLock };
_extraData.AddExtra(a_extra);
}

[[nodiscard]] BSExtraData* GetByType(ExtraDataType a_type) const noexcept
{
const BSAutoReadLock l{ _extraRWLock };
return _extraData.GetByType(a_type);
}

template <detail::ExtraDataListConstraint T>
[[nodiscard]] T* GetByType() const noexcept
{
return static_cast<T*>(GetByType(T::EXTRADATATYPE));
}

[[nodiscard]] bool HasType(ExtraDataType a_type) const noexcept
{
using func_t = bool(*)(const ExtraDataList*, ExtraDataType);
REL::Relocation<func_t> func{ REL::ID(83208) };
return func(this, a_type);
}

template <detail::ExtraDataListConstraint T>
[[nodiscard]] bool HasType() const noexcept
{
return HasType(T::EXTRADATATYPE);
}

private:
// members
BaseExtraList _extraData; // 08
mutable BSReadWriteLock _extraRWLock; // 20
};
static_assert(sizeof(ExtraDataList) == 0x28);
}
5 changes: 4 additions & 1 deletion CommonLibSF/include/RE/E/ExtraDataTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace RE
{
enum class EXTRA_DATA_TYPE
enum class ExtraDataType
{
kNone, // 0x00
kHavok, // 0x01 - ExtraHavok
Expand Down Expand Up @@ -260,3 +260,6 @@ namespace RE
kPlacedPlanetContent, // 0xFD - ExtraPlacedPlanetContent
};
}

#define SF_EXTRADATATYPE(TYPE) \
inline static constexpr auto EXTRADATATYPE = RE::ExtraDataType::k##TYPE

0 comments on commit c1db748

Please sign in to comment.