docs: add plugin setup guide
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
#pragma once
|
||||
|
||||
#include "RE/N/NiPointer.h"
|
||||
|
||||
namespace RE
|
||||
{
|
||||
class HandleManager;
|
||||
|
||||
template <std::uint32_t = 21, std::uint32_t = 5>
|
||||
class BSUntypedPointerHandle;
|
||||
|
||||
template <class, class = BSUntypedPointerHandle<>>
|
||||
class BSPointerHandle;
|
||||
|
||||
template <class, class = HandleManager>
|
||||
class BSPointerHandleManagerInterface;
|
||||
|
||||
template <std::uint32_t FREE_LIST_BITS, std::uint32_t AGE_SHIFT>
|
||||
class BSUntypedPointerHandle
|
||||
{
|
||||
public:
|
||||
using HandleType = std::uint32_t;
|
||||
|
||||
enum : std::uint32_t
|
||||
{
|
||||
kFreeListBits = FREE_LIST_BITS,
|
||||
kAgeShift = AGE_SHIFT,
|
||||
};
|
||||
|
||||
BSUntypedPointerHandle() noexcept = default;
|
||||
BSUntypedPointerHandle(const BSUntypedPointerHandle&) noexcept = default;
|
||||
|
||||
explicit BSUntypedPointerHandle(HandleType a_handle) noexcept :
|
||||
_handle(a_handle)
|
||||
{}
|
||||
|
||||
~BSUntypedPointerHandle() noexcept { reset(); }
|
||||
|
||||
BSUntypedPointerHandle& operator=(const BSUntypedPointerHandle&) noexcept = default;
|
||||
|
||||
BSUntypedPointerHandle& operator=(HandleType a_rhs) noexcept
|
||||
{
|
||||
_handle = a_rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] explicit operator bool() const noexcept { return has_value(); }
|
||||
[[nodiscard]] bool has_value() const noexcept { return _handle != 0; }
|
||||
|
||||
[[nodiscard]] HandleType value() const noexcept { return _handle; }
|
||||
|
||||
void reset() noexcept { _handle = 0; }
|
||||
|
||||
[[nodiscard]] friend bool operator==(const BSUntypedPointerHandle& a_lhs, const BSUntypedPointerHandle& a_rhs) noexcept
|
||||
{
|
||||
return a_lhs.value() == a_rhs.value();
|
||||
}
|
||||
|
||||
private:
|
||||
// members
|
||||
HandleType _handle{ 0 }; // 0
|
||||
};
|
||||
|
||||
extern template class BSUntypedPointerHandle<>;
|
||||
|
||||
template <class T, class Handle>
|
||||
class BSPointerHandle
|
||||
{
|
||||
public:
|
||||
BSPointerHandle() noexcept = default;
|
||||
|
||||
template <class Y>
|
||||
BSPointerHandle(BSPointerHandle<Y, Handle> a_rhs) noexcept
|
||||
requires(std::convertible_to<Y*, T*>)
|
||||
:
|
||||
_handle(a_rhs._handle)
|
||||
{}
|
||||
|
||||
template <class Y>
|
||||
explicit BSPointerHandle(Y* a_rhs)
|
||||
requires(std::convertible_to<Y*, T*>)
|
||||
{
|
||||
get_handle(a_rhs);
|
||||
}
|
||||
|
||||
~BSPointerHandle() noexcept = default;
|
||||
|
||||
template <class Y>
|
||||
BSPointerHandle& operator=(BSPointerHandle<Y, Handle> a_rhs) noexcept
|
||||
requires(std::convertible_to<Y*, T*>)
|
||||
{
|
||||
_handle = a_rhs._handle;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Y>
|
||||
BSPointerHandle& operator=(Y* a_rhs)
|
||||
requires(std::convertible_to<Y*, T*>)
|
||||
{
|
||||
get_handle(a_rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset() noexcept { _handle.reset(); }
|
||||
|
||||
[[nodiscard]] NiPointer<T> get() const
|
||||
{
|
||||
return BSPointerHandleManagerInterface<T>::GetSmartPointer(*this);
|
||||
}
|
||||
|
||||
[[nodiscard]] Handle::HandleType get_handle() noexcept
|
||||
{
|
||||
return _handle.value();
|
||||
}
|
||||
|
||||
[[nodiscard]] explicit operator bool() const noexcept { return _handle.has_value(); }
|
||||
|
||||
[[nodiscard]] friend bool operator==(const BSPointerHandle& a_lhs, const BSPointerHandle& a_rhs) noexcept
|
||||
{
|
||||
return a_lhs._handle == a_rhs._handle;
|
||||
}
|
||||
|
||||
[[nodiscard]] NiPointer<T> operator*() const noexcept
|
||||
{
|
||||
assert(static_cast<bool>(*this));
|
||||
return get();
|
||||
}
|
||||
|
||||
[[nodiscard]] NiPointer<T> operator->() const noexcept
|
||||
{
|
||||
assert(static_cast<bool>(*this));
|
||||
return get();
|
||||
}
|
||||
|
||||
private:
|
||||
template <class, class>
|
||||
friend class BSPointerHandle;
|
||||
|
||||
Handle _handle; // 00
|
||||
};
|
||||
|
||||
extern template class BSPointerHandle<Actor>;
|
||||
extern template class BSPointerHandle<Projectile>;
|
||||
extern template class BSPointerHandle<TESObjectREFR>;
|
||||
|
||||
using ActorHandle = BSPointerHandle<Actor>;
|
||||
using ProjectileHandle = BSPointerHandle<Projectile>;
|
||||
using ObjectRefHandle = BSPointerHandle<TESObjectREFR>;
|
||||
|
||||
template <class T>
|
||||
struct BSCRC32<BSPointerHandle<T>>
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] std::uint32_t operator()(const BSPointerHandle<T>& a_handle) const noexcept
|
||||
{
|
||||
return BSCRC32<typename BSPointerHandle<T>::native_handle_type>()(a_handle.native_handle());
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class Manager>
|
||||
class BSPointerHandleManagerInterface
|
||||
{
|
||||
public:
|
||||
static BSPointerHandle<T> CreateHandle(T* a_ptr)
|
||||
{
|
||||
using func_t = decltype(&BSPointerHandleManagerInterface<T, Manager>::CreateHandle);
|
||||
static REL::Relocation<func_t> func{ ID::BSPointerHandle::BSPointerHandleManagerInterface::CreateHandle };
|
||||
return func(a_ptr);
|
||||
}
|
||||
|
||||
static BSPointerHandle<T> GetHandle(T* a_ptr)
|
||||
{
|
||||
using func_t = decltype(&BSPointerHandleManagerInterface<T, Manager>::GetHandle);
|
||||
static REL::Relocation<func_t> func{ ID::BSPointerHandle::BSPointerHandleManagerInterface::GetHandle };
|
||||
return func(a_ptr);
|
||||
}
|
||||
|
||||
static bool GetSmartPointer(const BSPointerHandle<T>& a_in, NiPointer<T>& a_out)
|
||||
{
|
||||
using func_t = bool (*)(const BSPointerHandle<T>& a_in, NiPointer<T>& a_out);
|
||||
static REL::Relocation<func_t> func{ ID::BSPointerHandle::BSPointerHandleManagerInterface::GetSmartPointer };
|
||||
return func(a_in, a_out);
|
||||
}
|
||||
|
||||
static NiPointer<T> GetSmartPointer(const BSPointerHandle<T>& a_in)
|
||||
{
|
||||
NiPointer<T> out;
|
||||
GetSmartPointer(a_in, out);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
extern template class BSPointerHandleManagerInterface<Actor>;
|
||||
extern template class BSPointerHandleManagerInterface<Projectile>;
|
||||
extern template class BSPointerHandleManagerInterface<TESObjectREFR>;
|
||||
}
|
||||
Reference in New Issue
Block a user