Skip to content

Commit

Permalink
Further build optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
Exit-9B committed Nov 10, 2024
1 parent 6b1d588 commit 251b482
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 127 deletions.
1 change: 0 additions & 1 deletion include/RE/B/BGSDefaultObjectManager.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include "RE/B/BSTSingleton.h"
#include "RE/F/FormTraits.h"
#include "RE/F/FormTypes.h"
#include "RE/T/TESForm.h"

Expand Down
1 change: 0 additions & 1 deletion include/RE/B/BGSEntryPointPerkEntry.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include "RE/B/BGSPerkEntry.h"
#include "RE/F/FormTypes.h"
#include "RE/M/MemoryManager.h"

namespace RE
Expand Down
119 changes: 19 additions & 100 deletions include/RE/B/BSFixedString.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,88 +20,26 @@ namespace RE

constexpr BSFixedString() noexcept = default;

inline BSFixedString(const BSFixedString& a_rhs) :
_data(a_rhs._data)
{
try_acquire();
}
BSFixedString(const BSFixedString& a_rhs);
BSFixedString(BSFixedString&& a_rhs) noexcept;
BSFixedString(const_pointer a_string);
BSFixedString(std::basic_string_view<CharT> a_view);

inline BSFixedString(BSFixedString&& a_rhs) :
_data(a_rhs._data)
inline BSFixedString(std::convertible_to<std::basic_string_view<CharT>> auto&& a_string) :
BSFixedString(static_cast<std::basic_string_view<CharT>>(a_string))
{
a_rhs._data = nullptr;
}

inline BSFixedString(const_pointer a_string)
{
if (a_string) {
ctor(a_string);
}
}

template <
class T,
std::enable_if_t<
std::conjunction_v<
std::is_convertible<const T&, std::basic_string_view<value_type>>,
std::negation<
std::is_convertible<const T&, const_pointer>>>,
int> = 0>
inline BSFixedString(const T& a_string)
{
const auto view = static_cast<std::basic_string_view<value_type>>(a_string);
if (!view.empty()) {
ctor(view.data());
}
}
~BSFixedString();

inline ~BSFixedString() { try_release(); }
BSFixedString& operator=(const BSFixedString& a_rhs);
BSFixedString& operator=(BSFixedString&& a_rhs) noexcept;
BSFixedString& operator=(const_pointer a_string);
BSFixedString& operator=(std::basic_string_view<CharT> a_view);

inline BSFixedString& operator=(const BSFixedString& a_rhs)
inline BSFixedString& operator=(std::convertible_to<std::basic_string_view<CharT>> auto&& a_string)
{
if (this != std::addressof(a_rhs)) {
try_release();
_data = a_rhs._data;
try_acquire();
}
return *this;
}

inline BSFixedString& operator=(BSFixedString&& a_rhs)
{
if (this != std::addressof(a_rhs)) {
try_release();
_data = a_rhs._data;
a_rhs._data = nullptr;
}
return *this;
}

inline BSFixedString& operator=(const_pointer a_string)
{
try_release();
if (a_string) {
ctor(a_string);
}
return *this;
}

template <
class T,
std::enable_if_t<
std::conjunction_v<
std::is_convertible<const T&, std::basic_string_view<value_type>>,
std::negation<
std::is_convertible<const T&, const_pointer>>>,
int> = 0>
inline BSFixedString& operator=(const T& a_string)
{
const auto view = static_cast<std::basic_string_view<value_type>>(a_string);
try_release();
if (!view.empty()) {
ctor(view.data());
}
return *this;
return *this = static_cast<std::basic_string_view<CharT>>(a_string);
}

[[nodiscard]] inline const_reference operator[](size_type a_pos) const noexcept
Expand Down Expand Up @@ -172,22 +110,10 @@ namespace RE
return _wcsnicmp(a_lhs, a_rhs, a_length);
}

inline BSFixedString* ctor(const char* a_data) { return ctor8(a_data); }
inline BSFixedString* ctor(const wchar_t* a_data) { return ctor16(a_data); }

inline BSFixedString* ctor8(const char* a_data)
{
using func_t = decltype(&BSFixedString::ctor8);
REL::Relocation<func_t> func{ STATIC_OFFSET(BSFixedString::Ctor8) };
return func(this, a_data);
}

inline BSFixedString* ctor16(const wchar_t* a_data)
{
using func_t = decltype(&BSFixedString::ctor16);
REL::Relocation<func_t> func{ STATIC_OFFSET(BSFixedString::Ctor16) };
return func(this, a_data);
}
BSFixedString* ctor(const char* a_data);
BSFixedString* ctor(const wchar_t* a_data);
BSFixedString* ctor8(const char* a_data);
BSFixedString* ctor16(const wchar_t* a_data);

[[nodiscard]] inline BSStringPool::Entry* get_proxy() noexcept
{
Expand All @@ -203,15 +129,8 @@ namespace RE
nullptr;
}

inline void try_acquire()
{
const auto proxy = get_proxy();
if (proxy) {
proxy->acquire();
}
}

inline void try_release() { BSStringPool::Entry::release(_data); }
void try_acquire();
void try_release();

static constexpr const value_type EMPTY[]{ 0 };

Expand Down
21 changes: 17 additions & 4 deletions include/RE/F/FormTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,28 @@

namespace RE
{
template <class T, class>
T* TESForm::As() noexcept
template <class T>
requires(std::is_class_v<T>)
T* TESForm::As() noexcept
{
return const_cast<T*>(
static_cast<const TESForm*>(this)->As<T>());
}

template <class T, class>
const T* TESForm::As() const noexcept
template <class T>
requires(requires { T::FORMTYPE; })
const T* TESForm::As() const noexcept
{
if (GetFormType() == T::FORMTYPE) {
return static_cast<const T*>(this);
} else {
return nullptr;
}
}

template <std::derived_from<BaseFormComponent> T>
requires(!requires { T::FORMTYPE; })
const T* TESForm::As() const noexcept
{
switch (GetFormType()) {
SKSE_FORMTRAITS(TESForm);
Expand Down
32 changes: 11 additions & 21 deletions include/RE/T/TESForm.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,27 +206,17 @@ namespace RE
return form ? form->As<T>() : nullptr;
}

template <
class T,
class = std::enable_if_t<
std::negation_v<
std::disjunction<
std::is_pointer<T>,
std::is_reference<T>,
std::is_const<T>,
std::is_volatile<T>>>>>
[[nodiscard]] T* As() noexcept;

template <
class T,
class = std::enable_if_t<
std::negation_v<
std::disjunction<
std::is_pointer<T>,
std::is_reference<T>,
std::is_const<T>,
std::is_volatile<T>>>>>
[[nodiscard]] const T* As() const noexcept;
template <class T>
requires(std::is_class_v<T>)
[[nodiscard]] T* As() noexcept;

template <class T>
requires(requires { T::FORMTYPE; })
[[nodiscard]] const T* As() const noexcept;

template <std::derived_from<BaseFormComponent> T>
requires(!requires { T::FORMTYPE; })
[[nodiscard]] const T* As() const noexcept;

[[nodiscard]] TESObjectREFR* AsReference() { return AsReference1(); }
[[nodiscard]] const TESObjectREFR* AsReference() const { return AsReference2(); }
Expand Down
121 changes: 121 additions & 0 deletions src/RE/B/BSFixedString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,127 @@ namespace RE
{
namespace detail
{
template <class CharT>
BSFixedString<CharT>::BSFixedString(const BSFixedString& a_rhs) :
_data(a_rhs._data)
{
try_acquire();
}

template <class CharT>
BSFixedString<CharT>::BSFixedString(BSFixedString&& a_rhs) noexcept :
_data(a_rhs._data)
{
a_rhs._data = nullptr;
}

template <class CharT>
BSFixedString<CharT>::BSFixedString(const_pointer a_string)
{
if (a_string) {
ctor(a_string);
}
}

template <class CharT>
BSFixedString<CharT>::BSFixedString(std::basic_string_view<CharT> a_view)
{
if (!a_view.empty()) {
ctor(a_view.data());
}
}

template <class CharT>
BSFixedString<CharT>::~BSFixedString()
{
try_release();
}

template <class CharT>
BSFixedString<CharT>& BSFixedString<CharT>::operator=(const BSFixedString<CharT>& a_rhs)
{
if (this != std::addressof(a_rhs)) {
try_release();
_data = a_rhs._data;
try_acquire();
}
return *this;
}

template <class CharT>
BSFixedString<CharT>& BSFixedString<CharT>::operator=(BSFixedString&& a_rhs) noexcept
{
if (this != std::addressof(a_rhs)) {
try_release();
_data = a_rhs._data;
a_rhs._data = nullptr;
}
return *this;
}

template <class CharT>
BSFixedString<CharT>& BSFixedString<CharT>::operator=(const_pointer a_string)
{
try_release();
if (a_string) {
ctor(a_string);
}
return *this;
}

template <class CharT>
BSFixedString<CharT>& BSFixedString<CharT>::operator=(std::basic_string_view<CharT> a_view)
{
try_release();
if (!a_view.empty()) {
ctor(a_view.data());
}
return *this;
}

template <class CharT>
BSFixedString<CharT>* BSFixedString<CharT>::ctor(const char* a_data)
{
return ctor8(a_data);
}

template <class CharT>
BSFixedString<CharT>* BSFixedString<CharT>::ctor(const wchar_t* a_data)
{
return ctor16(a_data);
}

template <class CharT>
BSFixedString<CharT>* BSFixedString<CharT>::ctor8(const char* a_data)
{
using func_t = decltype(&BSFixedString::ctor8);
REL::Relocation<func_t> func{ STATIC_OFFSET(BSFixedString::Ctor8) };
return func(this, a_data);
}

template <class CharT>
BSFixedString<CharT>* BSFixedString<CharT>::ctor16(const wchar_t* a_data)
{
using func_t = decltype(&BSFixedString::ctor16);
REL::Relocation<func_t> func{ STATIC_OFFSET(BSFixedString::Ctor16) };
return func(this, a_data);
}

template <class CharT>
void BSFixedString<CharT>::try_acquire()
{
const auto proxy = get_proxy();
if (proxy) {
proxy->acquire();
}
}

template <class CharT>
void BSFixedString<CharT>::try_release()
{
BSStringPool::Entry::release(_data);
}

template class BSFixedString<char>;
static_assert(sizeof(BSFixedString<char>) == 0x8);

Expand Down
1 change: 1 addition & 0 deletions src/RE/T/TutorialMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "RE/B/BGSMessage.h"
#include "RE/B/BSTArray.h"
#include "RE/C/CRC.h"
#include "RE/F/FormTraits.h"
#include "RE/I/INISettingCollection.h"
#include "RE/T/TESFile.h"
#include "RE/T/TESFormUIData.h"
Expand Down

0 comments on commit 251b482

Please sign in to comment.