diff --git a/cmake/sourcelist.cmake b/cmake/sourcelist.cmake index a40704b11..3e730c988 100644 --- a/cmake/sourcelist.cmake +++ b/cmake/sourcelist.cmake @@ -310,7 +310,11 @@ set(SOURCES include/RE/B/BSPrecomputedNavmeshInfoPathMap.h include/RE/B/BSReloadShaderI.h include/RE/B/BSRenderPass.h + include/RE/B/BSResourceEntry.h + include/RE/B/BSResourceEntryCache.h include/RE/B/BSResourceEntryDB.h + include/RE/B/BSResourceEntryQueue.h + include/RE/B/BSResourceHandle.h include/RE/B/BSResourceNiBinaryStream.h include/RE/B/BSResponse.h include/RE/B/BSSaveDataSystemUtility.h @@ -510,7 +514,6 @@ set(SOURCES include/RE/C/CrosshairPickData.h include/RE/C/CureEffect.h include/RE/C/CursorMenu.h - include/RE/D/DBTraits.h include/RE/D/DamageImpactData.h include/RE/D/DarknessEffect.h include/RE/D/DecalData.h @@ -1218,7 +1221,6 @@ set(SOURCES include/RE/M/MissileProjectile.h include/RE/M/MistMenu.h include/RE/M/ModManagerMenu.h - include/RE/M/ModelProcessor.h include/RE/M/ModelReferenceEffect.h include/RE/M/Moon.h include/RE/M/MouseMoveEvent.h @@ -1556,6 +1558,7 @@ set(SOURCES include/RE/T/TESPackage.h include/RE/T/TESPackageData.h include/RE/T/TESPlayerBowShotEvent.h + include/RE/T/TESProcessor.h include/RE/T/TESProduceForm.h include/RE/T/TESQualityForm.h include/RE/T/TESQuest.h diff --git a/include/RE/B/BSAtomic.h b/include/RE/B/BSAtomic.h index 037376f49..1992b8377 100644 --- a/include/RE/B/BSAtomic.h +++ b/include/RE/B/BSAtomic.h @@ -4,6 +4,47 @@ namespace RE { + template + class BSTAtomicValue + { + public: + static_assert(std::is_integral_v); + + constexpr BSTAtomicValue() noexcept = default; + explicit constexpr BSTAtomicValue(T a_rhs) noexcept : + _value(a_rhs) + {} + + T operator++() + { + stl::atomic_ref value{ _value }; + return ++value; + } + [[nodiscard]] T operator++(int) + { + stl::atomic_ref value{ _value }; + return value++; + } + T operator--() + { + stl::atomic_ref value{ _value }; + return --value; + } + [[nodiscard]] T operator--(int) + { + stl::atomic_ref value{ _value }; + return value--; + } + + [[nodiscard]] T& load_unchecked() noexcept { return _value; } + [[nodiscard]] const T& load_unchecked() const noexcept { return _value; } + + private: + // members + T _value{ 0 }; // 0 + }; + static_assert(sizeof(BSTAtomicValue) == 0x4); + class BSCriticalSection { public: diff --git a/include/RE/B/BSModelDB.h b/include/RE/B/BSModelDB.h index 2626f0237..fb2280b74 100644 --- a/include/RE/B/BSModelDB.h +++ b/include/RE/B/BSModelDB.h @@ -1,6 +1,6 @@ #pragma once -#include "RE/D/DBTraits.h" +#include "RE/B/BSTSingleton.h" #include "RE/E/ErrorCodes.h" #include "RE/N/NiSmartPointer.h" @@ -10,6 +10,42 @@ namespace RE namespace BSModelDB { + struct DBTraits + { + public: + inline static constexpr auto RTTI = RTTI_BSModelDB__DBTraits; + inline static constexpr std::uint32_t LOAD_QUEUE_SIZE = 8; + inline static constexpr std::uint32_t RELEASE_QUEUE_SIZE = 2; + + using U_Type = NiPointer; + + struct ArgsType + { + public: + // members + std::uint32_t LODmult{ 0 }; // 0 + std::uint32_t texLoadLevel{ 3 }; // 4 + bool unk8{ true }; // 8 + bool unk9{ false }; // 9 + bool unkA{ true }; // A + bool postProcess{ true }; // B + }; + static_assert(sizeof(ArgsType) == 0xC); + }; + static_assert(std::is_empty_v); + + class BSModelProcessor : public BSTSingletonExplicit + { + public: + inline static constexpr auto RTTI = RTTI_BSModelDB__BSModelProcessor; + inline static constexpr auto VTABLE = VTABLE_BSModelDB__BSModelProcessor; + + virtual ~BSModelProcessor(); + + // add + virtual void PostCreate(const DBTraits::ArgsType& a_args, const char* modelName, NiPointer& a_root, std::uint32_t& a_typeOut); + }; + BSResource::ErrorCode Demand(const char* a_modelPath, NiPointer& a_modelOut, const DBTraits::ArgsType& a_args); } } diff --git a/include/RE/B/BSResourceEntry.h b/include/RE/B/BSResourceEntry.h new file mode 100644 index 000000000..68a4a9a96 --- /dev/null +++ b/include/RE/B/BSResourceEntry.h @@ -0,0 +1,37 @@ +#pragma once + +#include "RE/B/BSAtomic.h" +#include "RE/B/BSFixedString.h" +#include "RE/B/BSTSmartPointer.h" +#include "RE/I/ID.h" + +namespace RE +{ + namespace BSResource + { + class Stream; + + template + class Entry + { + public: + using U_Type = T_Type; + using U_EntryDBTraitsCArgs = T_EntryDBTraitsCArgs; + + union UserData + { + std::uint32_t flags; + T_EntryDBTraitsCArgs* traits; + }; + static_assert(sizeof(UserData) == 0x8); + + // members + ID name; // 00 + BSTAtomicValue ctrl; // 0C + UserData userData; // 10 + Entry* next; // 18 + BSTSmartPointer stream; // 20 + T_Type data; // 28 + }; + } +} diff --git a/include/RE/B/BSResourceEntryCache.h b/include/RE/B/BSResourceEntryCache.h new file mode 100644 index 000000000..7cb1b6af0 --- /dev/null +++ b/include/RE/B/BSResourceEntryCache.h @@ -0,0 +1,42 @@ +#pragma once + +#include "RE/B/BSAtomic.h" + +namespace RE +{ + namespace BSResource + { + template + class Entry; + + struct DAP + { + public: + }; + static_assert(std::is_empty_v); + + template + class EntryCacheTraits + { + public: + using U_Entry = Entry; + }; + static_assert(std::is_empty_v>); + + template + class REntryCache + { + public: + using U_EntryCacheTraits = T_EntryCacheTraits; + + // members + T_EntryCacheTraits::U_Entry** table; // 00 + std::uint32_t tableSize; // 08 + std::uint32_t tombstoneCount; // 10 + std::uint32_t active; // 14 + std::uint32_t maxActive; // 18 + std::uint32_t misses; // 1C + BSTAtomicValue ctrl; // 20 + }; + } +} diff --git a/include/RE/B/BSResourceEntryDB.h b/include/RE/B/BSResourceEntryDB.h index cffb14d65..a5c6c06a7 100644 --- a/include/RE/B/BSResourceEntryDB.h +++ b/include/RE/B/BSResourceEntryDB.h @@ -1,17 +1,75 @@ #pragma once +#include "RE/B/BSResourceEntry.h" +#include "RE/B/BSResourceEntryCache.h" +#include "RE/B/BSResourceEntryQueue.h" +#include "RE/B/BSTSingleton.h" + namespace RE { namespace BSResource { - // TBD + class Location; + class EntryBase; + + template + class EntryDB; + + template + class EntryDBTraits + { + public: + using U_DBTraits = T_DBTraits; + using U_EntryDB = T_EntryDB; + + class CArgs + { + public: + // members + T_DBTraits::ArgsType userArgs; // 00 + BSFixedString nameText; // ?? + }; + }; + static_assert(std::is_empty_v>); + class IEntryDB { public: inline static constexpr auto RTTI = RTTI_BSResource__IEntryDB; inline static constexpr auto VTABLE = VTABLE_BSResource__IEntryDB; - virtual ~IEntryDB(); + class NotifyLoadDone + { + public: + inline static constexpr auto RTTI = RTTI_BSResource__IEntryDB__NotifyLoadDone; + inline static constexpr auto VTABLE = VTABLE_BSResource__IEntryDB__NotifyLoadDone; + + virtual ~NotifyLoadDone(); // 00 + + // add + virtual void operator()() = 0; // 01 + }; + static_assert(sizeof(NotifyLoadDone) == 0x08); + + class PostFlushNotify + { + public: + inline static constexpr auto RTTI = RTTI_BSResource__IEntryDB__PostFlushNotify; + inline static constexpr auto VTABLE = VTABLE_BSResource__IEntryDB__PostFlushNotify; + + virtual ~PostFlushNotify(); // 00 + + // add + virtual bool DoOnNotify() = 0; // 01 + virtual void DoOnFinalize() = 0; // 02 + + // members + std::uint32_t state; // 08 + PostFlushNotify* next; // 10 + }; + static_assert(sizeof(PostFlushNotify) == 0x18); + + virtual ~IEntryDB(); // 00 // add virtual void Unk_01(void) = 0; // 01 @@ -21,8 +79,40 @@ namespace RE virtual void Unk_05(void) = 0; // 05 // members - std::uint8_t unk00[0xC8]; // 08 + EntryBucketQueue postFlushNotifyQueue; // 08 }; static_assert(sizeof(IEntryDB) == 0xD0); + + template + class EntryDBBase : + public T_EntryDBTraits::U_DBTraits + { + public: + // members + std::byte unk00[0x40]; // 00 + REntryCache> cache; // ?? + EntryBucketQueue, T_EntryDBTraits::U_DBTraits::LOAD_QUEUE_SIZE> loadQueue; // ?? + EntryBucketQueue, T_EntryDBTraits::U_DBTraits::RELEASE_QUEUE_SIZE> releaseQueue; // ?? + Location* rootLocation; // ?? + std::byte unk168[0x8170 - 0x168]; // ?? + std::uint64_t unk8170; // ?? + }; + + template + class EntryDB : + public IEntryDB, + public EntryDBBase>>, + public BSTSingletonSDM> + { + public: + ~EntryDB() override; // 00 + + // override (IEntryDB) + void Unk_01(void) override; // 01 + void Unk_02(void) override; // 02 + void Unk_03(void) override; // 03 + void Unk_04(void) override; // 04 + void Unk_05(void) override; // 05 + }; } } diff --git a/include/RE/B/BSResourceEntryQueue.h b/include/RE/B/BSResourceEntryQueue.h new file mode 100644 index 000000000..5fc695d6f --- /dev/null +++ b/include/RE/B/BSResourceEntryQueue.h @@ -0,0 +1,30 @@ +#pragma once + +#include "RE/B/BSAtomic.h" + +namespace RE +{ + namespace BSResource + { + template + class EntryQueue + { + public: + // members + BSNonReentrantSpinLock lock; // 00 + T* head; // 08 + T** tail; // 10 + }; + static_assert(sizeof(EntryQueue) == 0x18); + + template + class EntryBucketQueue + { + public: + // members + EntryQueue buckets[SIZE]; // 00 + volatile std::uint32_t step; // ?? + }; + static_assert(sizeof(EntryBucketQueue) == 0xC8); + } +} diff --git a/include/RE/B/BSResourceHandle.h b/include/RE/B/BSResourceHandle.h new file mode 100644 index 000000000..76b8e0651 --- /dev/null +++ b/include/RE/B/BSResourceHandle.h @@ -0,0 +1,30 @@ +#pragma once + +#include "RE/N/NiSmartPointer.h" +#include "RE/B/BSResourceEntryDB.h" + +namespace RE +{ + class NiNode; + + namespace BSModelDB + { + struct DBTraits; + } + + namespace BSResource + { + template + class RHandleType + { + public: + using U_Entry = T_Entry; + using U_EntryDB = T_EntryDB; + + // members + T_Entry* entry; // 00 + }; + } + + using ModelDBHandle = BSResource::RHandleType, BSResource::EntryDBTraits>::CArgs>, BSResource::EntryDB>; +} diff --git a/include/RE/D/DBTraits.h b/include/RE/D/DBTraits.h deleted file mode 100644 index fea8bcf45..000000000 --- a/include/RE/D/DBTraits.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -namespace RE -{ - namespace BSModelDB - { - struct DBTraits - { - public: - inline static constexpr auto RTTI = RTTI_BSModelDB__DBTraits; - - struct ArgsType - { - public: - // members - std::uint32_t LODmult{ 0 }; // 0 - std::uint32_t texLoadLevel{ 3 }; // 4 - bool unk8{ true }; // 8 - bool unk9{ false }; // 9 - bool unkA{ true }; // A - bool postProcess{ true }; // B - }; - static_assert(sizeof(ArgsType) == 0xC); - }; - } -} diff --git a/include/RE/M/ModelProcessor.h b/include/RE/M/ModelProcessor.h deleted file mode 100644 index 774edff9c..000000000 --- a/include/RE/M/ModelProcessor.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "RE/B/BSTSingleton.h" -#include "RE/D/DBTraits.h" -#include "RE/N/NiSmartPointer.h" - -namespace RE -{ - class NiNode; - - namespace BSModelDB - { - class BSModelProcessor : public BSTSingletonExplicit - { - public: - inline static constexpr auto RTTI = RTTI_BSModelDB__BSModelProcessor; - inline static constexpr auto VTABLE = VTABLE_BSModelDB__BSModelProcessor; - - virtual ~BSModelProcessor(); - - // add - virtual void PostCreate(const DBTraits::ArgsType& a_args, const char* modelName, NiPointer& a_root, std::uint32_t& a_typeOut); - }; - } - - namespace TESModelDB - { - class TESProcessor : public BSModelDB::BSModelProcessor - { - public: - inline static constexpr auto RTTI = RTTI_TESModelDB____TESProcessor; - inline static constexpr auto VTABLE = VTABLE_TESModelDB____TESProcessor; - - ~TESProcessor() override; - - // override (BSModelDM::BSModelProcessor) - void PostCreate(const BSModelDB::DBTraits::ArgsType& a_args, const char* modelName, NiPointer& a_root, std::uint32_t& a_typeOut) override; - }; - } -} diff --git a/include/RE/Skyrim.h b/include/RE/Skyrim.h index 59be7b364..b48409262 100644 --- a/include/RE/Skyrim.h +++ b/include/RE/Skyrim.h @@ -312,7 +312,11 @@ #include "RE/B/BSPrecomputedNavmeshInfoPathMap.h" #include "RE/B/BSReloadShaderI.h" #include "RE/B/BSRenderPass.h" +#include "RE/B/BSResourceEntry.h" +#include "RE/B/BSResourceEntryCache.h" #include "RE/B/BSResourceEntryDB.h" +#include "RE/B/BSResourceEntryQueue.h" +#include "RE/B/BSResourceHandle.h" #include "RE/B/BSResourceNiBinaryStream.h" #include "RE/B/BSResponse.h" #include "RE/B/BSSaveDataSystemUtility.h" @@ -512,7 +516,6 @@ #include "RE/C/CrosshairPickData.h" #include "RE/C/CureEffect.h" #include "RE/C/CursorMenu.h" -#include "RE/D/DBTraits.h" #include "RE/D/DamageImpactData.h" #include "RE/D/DarknessEffect.h" #include "RE/D/DecalData.h" @@ -1220,7 +1223,6 @@ #include "RE/M/MissileProjectile.h" #include "RE/M/MistMenu.h" #include "RE/M/ModManagerMenu.h" -#include "RE/M/ModelProcessor.h" #include "RE/M/ModelReferenceEffect.h" #include "RE/M/Moon.h" #include "RE/M/MouseMoveEvent.h" @@ -1553,6 +1555,7 @@ #include "RE/T/TESPackage.h" #include "RE/T/TESPackageData.h" #include "RE/T/TESPlayerBowShotEvent.h" +#include "RE/T/TESProcessor.h" #include "RE/T/TESProduceForm.h" #include "RE/T/TESQualityForm.h" #include "RE/T/TESQuest.h" diff --git a/include/RE/T/TESProcessor.h b/include/RE/T/TESProcessor.h new file mode 100644 index 000000000..67ff06cd0 --- /dev/null +++ b/include/RE/T/TESProcessor.h @@ -0,0 +1,21 @@ +#pragma once + +#include "RE/B/BSModelDB.h" + +namespace RE +{ + namespace TESModelDB + { + class TESProcessor : public BSModelDB::BSModelProcessor + { + public: + inline static constexpr auto RTTI = RTTI_TESModelDB____TESProcessor; + inline static constexpr auto VTABLE = VTABLE_TESModelDB____TESProcessor; + + ~TESProcessor() override; + + // override (BSModelDM::BSModelProcessor) + void PostCreate(const BSModelDB::DBTraits::ArgsType& a_args, const char* modelName, NiPointer& a_root, std::uint32_t& a_typeOut) override; + }; + } +}