From 317481ba152f21fcc2cb120df4580b1016d51d33 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Tue, 12 Nov 2024 00:14:09 -0700 Subject: [PATCH 01/24] feat: REX: initial ini, toml support --- include/REX/REX.h | 267 ++++++++++++++++++++++++++++++++++++++++++++++ xmake.lua | 30 +++++- 2 files changed, 296 insertions(+), 1 deletion(-) diff --git a/include/REX/REX.h b/include/REX/REX.h index 6c9676e85..8c58c5872 100644 --- a/include/REX/REX.h +++ b/include/REX/REX.h @@ -270,3 +270,270 @@ namespace REX Singleton& operator=(Singleton&&) = delete; }; } + +namespace REX +{ + class ISetting + { + public: + virtual void Load(void* a_file) = 0; + virtual void Save(void* a_file) = 0; + }; + + class ISettingStore + { + public: + virtual void Init(const char* a_file, const char* a_fileCustom) = 0; + virtual void Load() = 0; + virtual void Save() = 0; + virtual void Register(ISetting* a_setting) = 0; + }; + + template + class TSetting : + public ISetting + { + public: + TSetting() = delete; + + TSetting(T a_default) : + m_value(a_default), + m_valueDefault(a_default) + { + Store::GetSingleton()->Register(this); + } + + public: + T GetValue() const { return m_value; } + + T GetValueDefault() const { return m_valueDefault; } + + void SetValue(T a_value) const { m_value = a_value; } + + protected: + T m_value; + T m_valueDefault; + }; + + template + class TSettingStore : + public ISettingStore, + public Singleton + { + public: + virtual void Init(const char* a_fileBase, const char* a_fileUser) override + { + m_fileBase = a_fileBase; + m_fileUser = a_fileUser; + } + + virtual void Register(ISetting* a_setting) override + { + m_settings.emplace_back(a_setting); + } + + protected: + std::string_view m_fileBase; + std::string_view m_fileUser; + std::vector m_settings; + }; +} + +#ifdef REX_OPTION_INI +# include + +namespace REX::INI +{ + class SettingStore : + public TSettingStore + { + public: + virtual void Load() override + { + CSimpleIniA ini; + ini.SetUnicode(true); + ini.SetQuotes(true); + + if (ini.LoadFile(m_fileBase.data()) == SI_OK) { + for (auto& setting : m_settings) { + setting->Load(&ini); + } + } + + if (ini.LoadFile(m_fileUser.data()) == SI_OK) { + for (auto& setting : m_settings) { + setting->Load(&ini); + } + } + } + + virtual void Save() override + { + CSimpleIniA ini; + ini.SetUnicode(true); + ini.SetQuotes(true); + + ini.LoadFile(m_fileBase.data()); + for (auto& setting : m_settings) { + setting->Save(&ini); + } + + ini.SaveFile(m_fileBase.data(), false); + } + }; + + template + class Setting : + public TSetting + { + public: + Setting(std::string_view a_section, std::string_view a_key, T a_default) : + TSetting(a_default), + m_section(a_section), + m_key(a_key) + {} + + public: + virtual void Load(void* a_file) override + { + auto file = static_cast(a_file); + if constexpr (std::is_same_v) { + this->m_value = file->GetBoolValue(m_section.data(), m_key.data(), this->m_valueDefault); + } else if constexpr (std::is_floating_point_v) { + this->m_value = static_cast(file->GetDoubleValue(m_section.data(), m_key.data(), this->m_valueDefault)); + } else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v) { + this->m_value = static_cast(file->GetLongValue(m_section.data(), m_key.data(), this->m_valueDefault)); + } else if constexpr (std::is_same_v) { + this->m_value = file->GetValue(m_section.data(), m_key.data(), this->m_valueDefault.c_str()); + } + } + + virtual void Save(void* a_file) override + { + auto file = static_cast(a_file); + if constexpr (std::is_same_v) { + file->SetBoolValue(m_section.data(), m_key.data(), this->m_value); + } else if constexpr (std::is_floating_point_v) { + file->SetDoubleValue(m_section.data(), m_key.data(), static_cast(this->m_value)); + } else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v) { + file->SetLongValue(m_section.data(), m_key.data(), static_cast(this->m_value)); + } else if constexpr (std::is_same_v) { + file->SetValue(m_section.data(), m_key.data(), this->m_value.c_str()); + } + } + + private: + std::string_view m_section; + std::string_view m_key; + }; + + template + using Bool = Setting; + + template + using F32 = Setting; + + template + using F64 = Setting; + + template + using I8 = Setting; + + template + using I16 = Setting; + + template + using I32 = Setting; + + template + using U8 = Setting; + + template + using U16 = Setting; + + template + using U32 = Setting; + + template + using Str = Setting; +} +#endif + +#ifdef REX_OPTION_TOML +# define TOML_EXCEPTIONS 0 +# include + +namespace REX::TOML +{ + class SettingStore : + public TSettingStore + { + public: + virtual void Load() override + { + if (auto result = toml::parse_file(m_file)) { + for (auto& setting : m_settings) + setting->Load(&result); + } + + if (auto result = toml::parse_file(m_fileCustom)) { + for (auto& setting : m_settings) + setting->Load(&result); + } + } + }; + + template + class Setting : + public TSetting + { + public: + Setting(std::string_view a_path, T a_default) : + TSetting(a_default), + m_path(a_path) + {} + + public: + virtual void Load(void* a_file) override + { + auto file = static_cast(a_file); + if (auto node = file->at_path(m_path)) { + this->m_value = node.value_or(this->m_valueDefault); + } + } + + private: + std::string_view m_path; + }; + + template + using Bool = Setting; + + template + using F32 = Setting; + + template + using F64 = Setting; + + template + using I8 = Setting; + + template + using I16 = Setting; + + template + using I32 = Setting; + + template + using U8 = Setting; + + template + using U16 = Setting; + + template + using U32 = Setting; + + template + using Str = Setting; +} +#endif diff --git a/xmake.lua b/xmake.lua index 710945be0..054da0a14 100644 --- a/xmake.lua +++ b/xmake.lua @@ -27,6 +27,18 @@ option("skse_xbyak", function() add_defines("SKSE_SUPPORT_XBYAK=1") end) +option("rex_ini") + set_default(false) + set_description("Enable ini config support for REX") + add_defines("REX_OPTION_INI=1") +option_end() + +option("rex_toml") + set_default(false) + set_description("Enable toml config support for REX") + add_defines("REX_OPTION_TOML=1") +option_end() + -- require packages add_requires("rsm-binary-io") add_requires("spdlog", { configs = { header_only = false, wchar = true, std_format = true } }) @@ -35,6 +47,14 @@ if has_config("skse_xbyak") then add_requires("xbyak") end +if has_config("rex_ini") then + add_requires("simpleini", { configs = { convert = "none" }}) +end + +if has_config("rex_toml") then + add_requires("toml++") +end + -- define targets target("commonlibsse", function() -- set target kind @@ -50,8 +70,16 @@ target("commonlibsse", function() add_packages("xbyak", { public = true }) end + if has_config("rex_ini") then + add_packages("simpleini", { public = true }) + end + + if has_config("rex_toml") then + add_packages("toml++", { public = true }) + end + -- add options - add_options("skyrim_ae", "skse_xbyak", { public = true }) + add_options("skyrim_ae", "skse_xbyak", "rex_ini", "rex_toml", { public = true }) -- add system links add_syslinks("advapi32", "bcrypt", "d3d11", "d3dcompiler", "dbghelp", "dxgi", "ole32", "shell32", "user32", "version") From cc0fe3cb1179ee9152387775b12e70cb676c49d3 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Tue, 12 Nov 2024 15:25:24 -0700 Subject: [PATCH 02/24] feat: separate REX defs; ini, toml, and json work --- cmake/sourcelist.cmake | 8 + include/REX/REX.h | 544 +-------------------------------- include/REX/REX/Enum.h | 68 +++++ include/REX/REX/EnumSet.h | 181 +++++++++++ include/REX/REX/INI.h | 90 ++++++ include/REX/REX/JSON.h | 87 ++++++ include/REX/REX/Setting.h | 71 +++++ include/REX/REX/Singleton.h | 25 ++ include/REX/REX/TOML.h | 88 ++++++ src/REX/REX.cpp | 583 ++++++++++++++++++++++++++++++++++++ xmake.lua | 18 +- 11 files changed, 1224 insertions(+), 539 deletions(-) create mode 100644 include/REX/REX/Enum.h create mode 100644 include/REX/REX/EnumSet.h create mode 100644 include/REX/REX/INI.h create mode 100644 include/REX/REX/JSON.h create mode 100644 include/REX/REX/Setting.h create mode 100644 include/REX/REX/Singleton.h create mode 100644 include/REX/REX/TOML.h create mode 100644 src/REX/REX.cpp diff --git a/cmake/sourcelist.cmake b/cmake/sourcelist.cmake index 9b758a083..6b3cdd065 100644 --- a/cmake/sourcelist.cmake +++ b/cmake/sourcelist.cmake @@ -1671,6 +1671,13 @@ set(SOURCES include/REX/PS4.h include/REX/PS4/SCEPAD.h include/REX/REX.h + include/REX/REX/Enum.h + include/REX/REX/EnumSet.h + include/REX/REX/INI.h + include/REX/REX/JSON.h + include/REX/REX/Setting.h + include/REX/REX/Singleton.h + include/REX/REX/TOML.h include/REX/W32.h include/REX/W32/ADVAPI32.h include/REX/W32/BASE.h @@ -2046,6 +2053,7 @@ set(SOURCES src/REL/Module.cpp src/REL/Relocation.cpp src/REL/Version.cpp + src/REX/REX.cpp src/REX/W32.cpp src/SKSE/API.cpp src/SKSE/IAT.cpp diff --git a/include/REX/REX.h b/include/REX/REX.h index 8c58c5872..43a000af9 100644 --- a/include/REX/REX.h +++ b/include/REX/REX.h @@ -1,539 +1,9 @@ #pragma once -namespace REX -{ - template < - class E, - class U = std::underlying_type_t> - class Enum - { - public: - using enum_type = E; - using underlying_type = U; - - static_assert(std::is_enum_v, "Enum must be an enum"); - static_assert(std::is_integral_v, "Enum<..., U> must be an integral"); - - constexpr Enum() noexcept = default; - constexpr Enum(const Enum&) noexcept = default; - constexpr Enum(Enum&&) noexcept = default; - - template // NOLINTNEXTLINE(google-explicit-constructor) - constexpr Enum(Enum a_rhs) noexcept : - _impl(static_cast(a_rhs.get())) - {} - - constexpr Enum(E a_value) noexcept : - _impl(static_cast(a_value)) - {} - - ~Enum() noexcept = default; - - constexpr Enum& operator=(const Enum&) noexcept = default; - constexpr Enum& operator=(Enum&&) noexcept = default; - - template - constexpr Enum& operator=(Enum a_rhs) noexcept - { - _impl = static_cast(a_rhs.get()); - } - - constexpr Enum& operator=(E a_value) noexcept - { - _impl = static_cast(a_value); - return *this; - } - - public: - [[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast(0); } - - [[nodiscard]] constexpr E operator*() const noexcept { return get(); } - [[nodiscard]] constexpr E get() const noexcept { return static_cast(_impl); } - [[nodiscard]] constexpr U underlying() const noexcept { return _impl; } - - public: - friend constexpr bool operator==(Enum a_lhs, Enum a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); } - friend constexpr bool operator==(Enum a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast(a_rhs); } - friend constexpr bool operator==(E a_lhs, Enum a_rhs) noexcept { return static_cast(a_lhs) == a_rhs.underlying(); } - - private: - U _impl{ 0 }; - }; - - template - Enum(Args...) -> Enum< - std::common_type_t, - std::underlying_type_t< - std::common_type_t>>; -} - -namespace REX -{ - template < - class E, - class U = std::underlying_type_t> - class EnumSet - { - public: - using enum_type = E; - using underlying_type = U; - - static_assert(std::is_enum_v, "EnumSet must be an enum"); - static_assert(std::is_integral_v, "EnumSet<..., U> must be an integral"); - - constexpr EnumSet() noexcept = default; - constexpr EnumSet(const EnumSet&) noexcept = default; - constexpr EnumSet(EnumSet&&) noexcept = default; - - template // NOLINTNEXTLINE(google-explicit-constructor) - constexpr EnumSet(EnumSet a_rhs) noexcept : - _impl(static_cast(a_rhs.get())) - {} - - template - constexpr EnumSet(Args... a_values) noexcept - requires(std::same_as&&...) : - _impl((static_cast(a_values) | ...)) - {} - - ~EnumSet() noexcept = default; - - constexpr EnumSet& operator=(const EnumSet&) noexcept = default; - constexpr EnumSet& operator=(EnumSet&&) noexcept = default; - - template - constexpr EnumSet& operator=(EnumSet a_rhs) noexcept - { - _impl = static_cast(a_rhs.get()); - } - - constexpr EnumSet& operator=(E a_value) noexcept - { - _impl = static_cast(a_value); - return *this; - } - - public: - [[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast(0); } - - [[nodiscard]] constexpr E operator*() const noexcept { return get(); } - [[nodiscard]] constexpr E get() const noexcept { return static_cast(_impl); } - [[nodiscard]] constexpr U underlying() const noexcept { return _impl; } - - public: - template - constexpr EnumSet& set(Args... a_args) noexcept - requires(std::same_as&&...) - { - _impl |= (static_cast(a_args) | ...); - return *this; - } - - template - constexpr EnumSet& set(bool a_set, Args... a_args) noexcept - requires(std::same_as&&...) - { - if (a_set) - _impl |= (static_cast(a_args) | ...); - else - _impl &= ~(static_cast(a_args) | ...); - - return *this; - } - - template - constexpr EnumSet& reset(Args... a_args) noexcept - requires(std::same_as&&...) - { - _impl &= ~(static_cast(a_args) | ...); - return *this; - } - - constexpr EnumSet& reset() noexcept - { - _impl = 0; - return *this; - } - - template - [[nodiscard]] constexpr bool any(Args... a_args) const noexcept - requires(std::same_as&&...) - { - return (_impl & (static_cast(a_args) | ...)) != static_cast(0); - } - - template - [[nodiscard]] constexpr bool all(Args... a_args) const noexcept - requires(std::same_as&&...) - { - return (_impl & (static_cast(a_args) | ...)) == (static_cast(a_args) | ...); - } - - template - [[nodiscard]] constexpr bool none(Args... a_args) const noexcept - requires(std::same_as&&...) - { - return (_impl & (static_cast(a_args) | ...)) == static_cast(0); - } - - public: - friend constexpr bool operator==(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); } - friend constexpr bool operator==(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast(a_rhs); } - friend constexpr bool operator==(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs) == a_rhs.underlying(); } - - friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() <=> a_rhs.underlying(); } - friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() <=> static_cast(a_rhs); } - friend constexpr std::strong_ordering operator<=>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs) <=> a_rhs.underlying(); } - - friend constexpr EnumSet operator&(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() & a_rhs.underlying()); } - friend constexpr EnumSet operator&(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() & static_cast(a_rhs)); } - friend constexpr EnumSet operator&(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) & a_rhs.underlying()); } - - friend constexpr EnumSet& operator&=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; } - friend constexpr EnumSet& operator&=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; } - - friend constexpr EnumSet operator|(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() | a_rhs.underlying()); } - friend constexpr EnumSet operator|(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() | static_cast(a_rhs)); } - friend constexpr EnumSet operator|(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) | a_rhs.underlying()); } - - friend constexpr EnumSet& operator|=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; } - friend constexpr EnumSet& operator|=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; } - - friend constexpr EnumSet operator^(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() ^ a_rhs.underlying()); } - friend constexpr EnumSet operator^(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() ^ static_cast(a_rhs)); } - friend constexpr EnumSet operator^(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) ^ a_rhs.underlying()); } - - friend constexpr EnumSet& operator^=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; } - friend constexpr EnumSet& operator^=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; } - - friend constexpr EnumSet operator+(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() + a_rhs.underlying()); } - friend constexpr EnumSet operator+(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() + static_cast(a_rhs)); } - friend constexpr EnumSet operator+(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) + a_rhs.underlying()); } - - friend constexpr EnumSet& operator+=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; } - friend constexpr EnumSet& operator+=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; } - - friend constexpr EnumSet operator-(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() - a_rhs.underlying()); } - friend constexpr EnumSet operator-(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() - static_cast(a_rhs)); } - friend constexpr EnumSet operator-(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) - a_rhs.underlying()); } - - friend constexpr EnumSet& operator-=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; } - friend constexpr EnumSet& operator-=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; } - - friend constexpr EnumSet operator<<(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() << a_rhs.underlying()); } - friend constexpr EnumSet operator<<(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() << static_cast(a_rhs)); } - friend constexpr EnumSet operator<<(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) << a_rhs.underlying()); } - - friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; } - friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; } - - friend constexpr EnumSet operator>>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() >> a_rhs.underlying()); } - friend constexpr EnumSet operator>>(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() >> static_cast(a_rhs)); } - friend constexpr EnumSet operator>>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) >> a_rhs.underlying()); } - - friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; } - friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; } - - friend constexpr EnumSet& operator~(EnumSet& a_lhs) noexcept { return a_lhs = ~a_lhs.underlying(); } - - private: - U _impl{ 0 }; - }; - - template - EnumSet(Args...) -> EnumSet< - std::common_type_t, - std::underlying_type_t< - std::common_type_t>>; -} - -namespace REX -{ - template - class Singleton - { - public: - static T* GetSingleton() - { - static T singleton; - return std::addressof(singleton); - } - - protected: - Singleton() = default; - ~Singleton() = default; - - Singleton(const Singleton&) = delete; - Singleton(Singleton&&) = delete; - - Singleton& operator=(const Singleton&) = delete; - Singleton& operator=(Singleton&&) = delete; - }; -} - -namespace REX -{ - class ISetting - { - public: - virtual void Load(void* a_file) = 0; - virtual void Save(void* a_file) = 0; - }; - - class ISettingStore - { - public: - virtual void Init(const char* a_file, const char* a_fileCustom) = 0; - virtual void Load() = 0; - virtual void Save() = 0; - virtual void Register(ISetting* a_setting) = 0; - }; - - template - class TSetting : - public ISetting - { - public: - TSetting() = delete; - - TSetting(T a_default) : - m_value(a_default), - m_valueDefault(a_default) - { - Store::GetSingleton()->Register(this); - } - - public: - T GetValue() const { return m_value; } - - T GetValueDefault() const { return m_valueDefault; } - - void SetValue(T a_value) const { m_value = a_value; } - - protected: - T m_value; - T m_valueDefault; - }; - - template - class TSettingStore : - public ISettingStore, - public Singleton - { - public: - virtual void Init(const char* a_fileBase, const char* a_fileUser) override - { - m_fileBase = a_fileBase; - m_fileUser = a_fileUser; - } - - virtual void Register(ISetting* a_setting) override - { - m_settings.emplace_back(a_setting); - } - - protected: - std::string_view m_fileBase; - std::string_view m_fileUser; - std::vector m_settings; - }; -} - -#ifdef REX_OPTION_INI -# include - -namespace REX::INI -{ - class SettingStore : - public TSettingStore - { - public: - virtual void Load() override - { - CSimpleIniA ini; - ini.SetUnicode(true); - ini.SetQuotes(true); - - if (ini.LoadFile(m_fileBase.data()) == SI_OK) { - for (auto& setting : m_settings) { - setting->Load(&ini); - } - } - - if (ini.LoadFile(m_fileUser.data()) == SI_OK) { - for (auto& setting : m_settings) { - setting->Load(&ini); - } - } - } - - virtual void Save() override - { - CSimpleIniA ini; - ini.SetUnicode(true); - ini.SetQuotes(true); - - ini.LoadFile(m_fileBase.data()); - for (auto& setting : m_settings) { - setting->Save(&ini); - } - - ini.SaveFile(m_fileBase.data(), false); - } - }; - - template - class Setting : - public TSetting - { - public: - Setting(std::string_view a_section, std::string_view a_key, T a_default) : - TSetting(a_default), - m_section(a_section), - m_key(a_key) - {} - - public: - virtual void Load(void* a_file) override - { - auto file = static_cast(a_file); - if constexpr (std::is_same_v) { - this->m_value = file->GetBoolValue(m_section.data(), m_key.data(), this->m_valueDefault); - } else if constexpr (std::is_floating_point_v) { - this->m_value = static_cast(file->GetDoubleValue(m_section.data(), m_key.data(), this->m_valueDefault)); - } else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v) { - this->m_value = static_cast(file->GetLongValue(m_section.data(), m_key.data(), this->m_valueDefault)); - } else if constexpr (std::is_same_v) { - this->m_value = file->GetValue(m_section.data(), m_key.data(), this->m_valueDefault.c_str()); - } - } - - virtual void Save(void* a_file) override - { - auto file = static_cast(a_file); - if constexpr (std::is_same_v) { - file->SetBoolValue(m_section.data(), m_key.data(), this->m_value); - } else if constexpr (std::is_floating_point_v) { - file->SetDoubleValue(m_section.data(), m_key.data(), static_cast(this->m_value)); - } else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v) { - file->SetLongValue(m_section.data(), m_key.data(), static_cast(this->m_value)); - } else if constexpr (std::is_same_v) { - file->SetValue(m_section.data(), m_key.data(), this->m_value.c_str()); - } - } - - private: - std::string_view m_section; - std::string_view m_key; - }; - - template - using Bool = Setting; - - template - using F32 = Setting; - - template - using F64 = Setting; - - template - using I8 = Setting; - - template - using I16 = Setting; - - template - using I32 = Setting; - - template - using U8 = Setting; - - template - using U16 = Setting; - - template - using U32 = Setting; - - template - using Str = Setting; -} -#endif - -#ifdef REX_OPTION_TOML -# define TOML_EXCEPTIONS 0 -# include - -namespace REX::TOML -{ - class SettingStore : - public TSettingStore - { - public: - virtual void Load() override - { - if (auto result = toml::parse_file(m_file)) { - for (auto& setting : m_settings) - setting->Load(&result); - } - - if (auto result = toml::parse_file(m_fileCustom)) { - for (auto& setting : m_settings) - setting->Load(&result); - } - } - }; - - template - class Setting : - public TSetting - { - public: - Setting(std::string_view a_path, T a_default) : - TSetting(a_default), - m_path(a_path) - {} - - public: - virtual void Load(void* a_file) override - { - auto file = static_cast(a_file); - if (auto node = file->at_path(m_path)) { - this->m_value = node.value_or(this->m_valueDefault); - } - } - - private: - std::string_view m_path; - }; - - template - using Bool = Setting; - - template - using F32 = Setting; - - template - using F64 = Setting; - - template - using I8 = Setting; - - template - using I16 = Setting; - - template - using I32 = Setting; - - template - using U8 = Setting; - - template - using U16 = Setting; - - template - using U32 = Setting; - - template - using Str = Setting; -} -#endif +#include "REX/REX/Enum.h" +#include "REX/REX/EnumSet.h" +#include "REX/REX/INI.h" +#include "REX/REX/JSON.h" +#include "REX/REX/Setting.h" +#include "REX/REX/Singleton.h" +#include "REX/REX/TOML.h" diff --git a/include/REX/REX/Enum.h b/include/REX/REX/Enum.h new file mode 100644 index 000000000..cc0482751 --- /dev/null +++ b/include/REX/REX/Enum.h @@ -0,0 +1,68 @@ +#pragma once + +namespace REX +{ + template < + class E, + class U = std::underlying_type_t> + class Enum + { + public: + using enum_type = E; + using underlying_type = U; + + static_assert(std::is_enum_v, "Enum must be an enum"); + static_assert(std::is_integral_v, "Enum<..., U> must be an integral"); + + constexpr Enum() noexcept = default; + constexpr Enum(const Enum&) noexcept = default; + constexpr Enum(Enum&&) noexcept = default; + + template // NOLINTNEXTLINE(google-explicit-constructor) + constexpr Enum(Enum a_rhs) noexcept : + _impl(static_cast(a_rhs.get())) + {} + + constexpr Enum(E a_value) noexcept : + _impl(static_cast(a_value)) + {} + + ~Enum() noexcept = default; + + constexpr Enum& operator=(const Enum&) noexcept = default; + constexpr Enum& operator=(Enum&&) noexcept = default; + + template + constexpr Enum& operator=(Enum a_rhs) noexcept + { + _impl = static_cast(a_rhs.get()); + } + + constexpr Enum& operator=(E a_value) noexcept + { + _impl = static_cast(a_value); + return *this; + } + + public: + [[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast(0); } + + [[nodiscard]] constexpr E operator*() const noexcept { return get(); } + [[nodiscard]] constexpr E get() const noexcept { return static_cast(_impl); } + [[nodiscard]] constexpr U underlying() const noexcept { return _impl; } + + public: + friend constexpr bool operator==(Enum a_lhs, Enum a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); } + friend constexpr bool operator==(Enum a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast(a_rhs); } + friend constexpr bool operator==(E a_lhs, Enum a_rhs) noexcept { return static_cast(a_lhs) == a_rhs.underlying(); } + + private: + U _impl{ 0 }; + }; + + template + Enum(Args...) -> Enum< + std::common_type_t, + std::underlying_type_t< + std::common_type_t>>; +} diff --git a/include/REX/REX/EnumSet.h b/include/REX/REX/EnumSet.h new file mode 100644 index 000000000..2bae12f3e --- /dev/null +++ b/include/REX/REX/EnumSet.h @@ -0,0 +1,181 @@ +#pragma once + +namespace REX +{ + template < + class E, + class U = std::underlying_type_t> + class EnumSet + { + public: + using enum_type = E; + using underlying_type = U; + + static_assert(std::is_enum_v, "EnumSet must be an enum"); + static_assert(std::is_integral_v, "EnumSet<..., U> must be an integral"); + + constexpr EnumSet() noexcept = default; + constexpr EnumSet(const EnumSet&) noexcept = default; + constexpr EnumSet(EnumSet&&) noexcept = default; + + template // NOLINTNEXTLINE(google-explicit-constructor) + constexpr EnumSet(EnumSet a_rhs) noexcept : + _impl(static_cast(a_rhs.get())) + {} + + template + constexpr EnumSet(Args... a_values) noexcept + requires(std::same_as&&...) : + _impl((static_cast(a_values) | ...)) + {} + + ~EnumSet() noexcept = default; + + constexpr EnumSet& operator=(const EnumSet&) noexcept = default; + constexpr EnumSet& operator=(EnumSet&&) noexcept = default; + + template + constexpr EnumSet& operator=(EnumSet a_rhs) noexcept + { + _impl = static_cast(a_rhs.get()); + } + + constexpr EnumSet& operator=(E a_value) noexcept + { + _impl = static_cast(a_value); + return *this; + } + + public: + [[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast(0); } + + [[nodiscard]] constexpr E operator*() const noexcept { return get(); } + [[nodiscard]] constexpr E get() const noexcept { return static_cast(_impl); } + [[nodiscard]] constexpr U underlying() const noexcept { return _impl; } + + public: + template + constexpr EnumSet& set(Args... a_args) noexcept + requires(std::same_as&&...) + { + _impl |= (static_cast(a_args) | ...); + return *this; + } + + template + constexpr EnumSet& set(bool a_set, Args... a_args) noexcept + requires(std::same_as&&...) + { + if (a_set) + _impl |= (static_cast(a_args) | ...); + else + _impl &= ~(static_cast(a_args) | ...); + + return *this; + } + + template + constexpr EnumSet& reset(Args... a_args) noexcept + requires(std::same_as&&...) + { + _impl &= ~(static_cast(a_args) | ...); + return *this; + } + + constexpr EnumSet& reset() noexcept + { + _impl = 0; + return *this; + } + + template + [[nodiscard]] constexpr bool any(Args... a_args) const noexcept + requires(std::same_as&&...) + { + return (_impl & (static_cast(a_args) | ...)) != static_cast(0); + } + + template + [[nodiscard]] constexpr bool all(Args... a_args) const noexcept + requires(std::same_as&&...) + { + return (_impl & (static_cast(a_args) | ...)) == (static_cast(a_args) | ...); + } + + template + [[nodiscard]] constexpr bool none(Args... a_args) const noexcept + requires(std::same_as&&...) + { + return (_impl & (static_cast(a_args) | ...)) == static_cast(0); + } + + public: + friend constexpr bool operator==(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); } + friend constexpr bool operator==(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast(a_rhs); } + friend constexpr bool operator==(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs) == a_rhs.underlying(); } + + friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() <=> a_rhs.underlying(); } + friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() <=> static_cast(a_rhs); } + friend constexpr std::strong_ordering operator<=>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs) <=> a_rhs.underlying(); } + + friend constexpr EnumSet operator&(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() & a_rhs.underlying()); } + friend constexpr EnumSet operator&(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() & static_cast(a_rhs)); } + friend constexpr EnumSet operator&(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) & a_rhs.underlying()); } + + friend constexpr EnumSet& operator&=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; } + friend constexpr EnumSet& operator&=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; } + + friend constexpr EnumSet operator|(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() | a_rhs.underlying()); } + friend constexpr EnumSet operator|(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() | static_cast(a_rhs)); } + friend constexpr EnumSet operator|(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) | a_rhs.underlying()); } + + friend constexpr EnumSet& operator|=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; } + friend constexpr EnumSet& operator|=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; } + + friend constexpr EnumSet operator^(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() ^ a_rhs.underlying()); } + friend constexpr EnumSet operator^(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() ^ static_cast(a_rhs)); } + friend constexpr EnumSet operator^(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) ^ a_rhs.underlying()); } + + friend constexpr EnumSet& operator^=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; } + friend constexpr EnumSet& operator^=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; } + + friend constexpr EnumSet operator+(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() + a_rhs.underlying()); } + friend constexpr EnumSet operator+(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() + static_cast(a_rhs)); } + friend constexpr EnumSet operator+(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) + a_rhs.underlying()); } + + friend constexpr EnumSet& operator+=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; } + friend constexpr EnumSet& operator+=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; } + + friend constexpr EnumSet operator-(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() - a_rhs.underlying()); } + friend constexpr EnumSet operator-(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() - static_cast(a_rhs)); } + friend constexpr EnumSet operator-(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) - a_rhs.underlying()); } + + friend constexpr EnumSet& operator-=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; } + friend constexpr EnumSet& operator-=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; } + + friend constexpr EnumSet operator<<(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() << a_rhs.underlying()); } + friend constexpr EnumSet operator<<(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() << static_cast(a_rhs)); } + friend constexpr EnumSet operator<<(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) << a_rhs.underlying()); } + + friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; } + friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; } + + friend constexpr EnumSet operator>>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast(a_lhs.underlying() >> a_rhs.underlying()); } + friend constexpr EnumSet operator>>(EnumSet a_lhs, E a_rhs) noexcept { return static_cast(a_lhs.underlying() >> static_cast(a_rhs)); } + friend constexpr EnumSet operator>>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast(static_cast(a_lhs) >> a_rhs.underlying()); } + + friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; } + friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; } + + friend constexpr EnumSet& operator~(EnumSet& a_lhs) noexcept { return a_lhs = ~a_lhs.underlying(); } + + private: + U _impl{ 0 }; + }; + + template + EnumSet(Args...) -> EnumSet< + std::common_type_t, + std::underlying_type_t< + std::common_type_t>>; +} diff --git a/include/REX/REX/INI.h b/include/REX/REX/INI.h new file mode 100644 index 000000000..e455eee73 --- /dev/null +++ b/include/REX/REX/INI.h @@ -0,0 +1,90 @@ +#pragma once + +#include "REX/REX/Setting.h" + +#ifdef REX_OPTION_INI +namespace REX::INI +{ + namespace detail + { + void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); + void StoreSaveImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); + template + void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_section, std::string_view& a_key); + template + void SettingSaveImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_section, std::string_view& a_key); + } + + class SettingStore : + public TSettingStore + { + public: + virtual void Load() override + { + detail::StoreLoadImpl(m_fileBase, m_fileUser, m_settings); + } + + virtual void Save() override + { + detail::StoreSaveImpl(m_fileBase, m_fileUser, m_settings); + } + }; + + template + class Setting : + public TSetting + { + public: + Setting(std::string_view a_section, std::string_view a_key, T a_default) : + TSetting(a_default), + m_section(a_section), + m_key(a_key) + {} + + public: + virtual void Load(void* a_file) override + { + detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, m_section, m_key); + } + + virtual void Save(void* a_file) override + { + detail::SettingSaveImpl(a_file, this->m_value, this->m_valueDefault, m_section, m_key); + } + + private: + std::string_view m_section; + std::string_view m_key; + }; + + template + using Bool = Setting; + + template + using F32 = Setting; + + template + using F64 = Setting; + + template + using I8 = Setting; + + template + using I16 = Setting; + + template + using I32 = Setting; + + template + using U8 = Setting; + + template + using U16 = Setting; + + template + using U32 = Setting; + + template + using Str = Setting; +} +#endif diff --git a/include/REX/REX/JSON.h b/include/REX/REX/JSON.h new file mode 100644 index 000000000..ff1aee468 --- /dev/null +++ b/include/REX/REX/JSON.h @@ -0,0 +1,87 @@ +#pragma once + +#include "REX/REX/Setting.h" + +#ifdef REX_OPTION_JSON +namespace REX::JSON +{ + namespace detail + { + void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); + void StoreSaveImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); + template + void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault); + template + void SettingSaveImpl(void* a_file, T& a_value, T& a_valueDefault); + } + + class SettingStore : + public TSettingStore + { + public: + virtual void Load() override + { + detail::StoreLoadImpl(m_fileBase, m_fileUser, m_settings); + } + + virtual void Save() override + { + detail::StoreSaveImpl(m_fileBase, m_fileUser, m_settings); + } + }; + + template + class Setting : + public TSetting + { + public: + Setting(T a_default) : + TSetting(a_default) + {} + + public: + virtual void Load(void* a_file) override + { + detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault); + } + + virtual void Save(void* a_file) override + { + detail::SettingSaveImpl(a_file, this->m_value, this->m_valueDefault); + } + + private: + // std::string_view m_path; + }; + + template + using Bool = Setting; + + template + using F32 = Setting; + + template + using F64 = Setting; + + template + using I8 = Setting; + + template + using I16 = Setting; + + template + using I32 = Setting; + + template + using U8 = Setting; + + template + using U16 = Setting; + + template + using U32 = Setting; + + template + using Str = Setting; +} +#endif diff --git a/include/REX/REX/Setting.h b/include/REX/REX/Setting.h new file mode 100644 index 000000000..f6217dd6b --- /dev/null +++ b/include/REX/REX/Setting.h @@ -0,0 +1,71 @@ +#pragma once + +#include "REX/REX/Singleton.h" + +namespace REX +{ + class ISetting + { + public: + virtual void Load(void* a_file) = 0; + virtual void Save(void* a_file) = 0; + }; + + class ISettingStore + { + public: + virtual void Init(const char* a_file, const char* a_fileCustom) = 0; + virtual void Load() = 0; + virtual void Save() = 0; + virtual void Register(ISetting* a_setting) = 0; + }; + + template + class TSetting : + public ISetting + { + public: + TSetting() = delete; + + TSetting(T a_default) : + m_value(a_default), + m_valueDefault(a_default) + { + Store::GetSingleton()->Register(this); + } + + public: + T GetValue() const { return m_value; } + + T GetValueDefault() const { return m_valueDefault; } + + void SetValue(T a_value) { m_value = a_value; } + + protected: + T m_value; + T m_valueDefault; + }; + + template + class TSettingStore : + public ISettingStore, + public Singleton + { + public: + virtual void Init(const char* a_fileBase, const char* a_fileUser) override + { + m_fileBase = a_fileBase; + m_fileUser = a_fileUser; + } + + virtual void Register(ISetting* a_setting) override + { + m_settings.emplace_back(a_setting); + } + + protected: + std::string_view m_fileBase; + std::string_view m_fileUser; + std::vector m_settings; + }; +} diff --git a/include/REX/REX/Singleton.h b/include/REX/REX/Singleton.h new file mode 100644 index 000000000..836ddb1ee --- /dev/null +++ b/include/REX/REX/Singleton.h @@ -0,0 +1,25 @@ +#pragma once + +namespace REX +{ + template + class Singleton + { + public: + static T* GetSingleton() + { + static T singleton; + return std::addressof(singleton); + } + + protected: + Singleton() = default; + ~Singleton() = default; + + Singleton(const Singleton&) = delete; + Singleton(Singleton&&) = delete; + + Singleton& operator=(const Singleton&) = delete; + Singleton& operator=(Singleton&&) = delete; + }; +} diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h new file mode 100644 index 000000000..862313bc8 --- /dev/null +++ b/include/REX/REX/TOML.h @@ -0,0 +1,88 @@ +#pragma once + +#include "REX/REX/Setting.h" + +#ifdef REX_OPTION_TOML +namespace REX::TOML +{ + namespace detail + { + void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); + void StoreSaveImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); + template + void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_path); + template + void SettingSaveImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_path); + } + + class SettingStore : + public TSettingStore + { + public: + virtual void Load() override + { + detail::StoreLoadImpl(m_fileBase, m_fileUser, m_settings); + } + + virtual void Save() override + { + detail::StoreSaveImpl(m_fileBase, m_fileUser, m_settings); + } + }; + + template + class Setting : + public TSetting + { + public: + Setting(std::string_view a_path, T a_default) : + TSetting(a_default), + m_path(a_path) + {} + + public: + virtual void Load(void* a_file) override + { + detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, m_path); + } + + virtual void Save(void* a_file) override + { + detail::SettingSaveImpl(a_file, this->m_value, this->m_valueDefault, m_path); + } + + private: + std::string_view m_path; + }; + + template + using Bool = Setting; + + template + using F32 = Setting; + + template + using F64 = Setting; + + template + using I8 = Setting; + + template + using I16 = Setting; + + template + using I32 = Setting; + + template + using U8 = Setting; + + template + using U16 = Setting; + + template + using U32 = Setting; + + template + using Str = Setting; +} +#endif diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp new file mode 100644 index 000000000..e7dfd42e2 --- /dev/null +++ b/src/REX/REX.cpp @@ -0,0 +1,583 @@ +#include "REX/REX.h" + +#include "SKSE/Logger.h" + +#ifdef REX_OPTION_INI +# include + +void REX::INI::detail::StoreLoadImpl( + [[maybe_unused]] std::string_view& a_fileBase, + [[maybe_unused]] std::string_view& a_fileUser, + [[maybe_unused]] std::vector& a_settings) +{ + CSimpleIniA ini; + ini.SetUnicode(true); + ini.SetQuotes(true); + + if (ini.LoadFile(a_fileBase.data()) == SI_OK) { + for (auto& setting : a_settings) { + setting->Load(&ini); + } + } + + if (ini.LoadFile(a_fileUser.data()) == SI_OK) { + for (auto& setting : a_settings) { + setting->Load(&ini); + } + } +} + +void REX::INI::detail::StoreSaveImpl( + [[maybe_unused]] std::string_view& a_fileBase, + [[maybe_unused]] std::string_view& a_fileUser, + [[maybe_unused]] std::vector& a_settings) +{ + CSimpleIniA ini; + ini.SetUnicode(true); + ini.SetQuotes(true); + + ini.LoadFile(a_fileBase.data()); + for (auto& setting : a_settings) { + setting->Save(&ini); + } + + ini.SaveFile(a_fileBase.data(), false); +} + +template <> +void REX::INI::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] bool& a_value, + [[maybe_unused]] bool& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + a_value = file->GetBoolValue(a_section.data(), a_key.data(), a_valueDefault); +} + +template <> +void REX::INI::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] bool& a_value, + [[maybe_unused]] bool& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + file->SetBoolValue(a_section.data(), a_key.data(), a_value); +} + +template <> +void REX::INI::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] float& a_value, + [[maybe_unused]] float& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + a_value = static_cast(file->GetDoubleValue(a_section.data(), a_key.data(), a_valueDefault)); +} + +template <> +void REX::INI::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] float& a_value, + [[maybe_unused]] float& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + file->SetDoubleValue(a_section.data(), a_key.data(), a_value); +} + +template <> +void REX::INI::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] double& a_value, + [[maybe_unused]] double& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + a_value = file->GetDoubleValue(a_section.data(), a_key.data(), a_valueDefault); +} + +template <> +void REX::INI::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] double& a_value, + [[maybe_unused]] double& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + file->SetDoubleValue(a_section.data(), a_key.data(), a_value); +} + +template <> +void REX::INI::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int8_t& a_value, + [[maybe_unused]] std::int8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); +} + +template <> +void REX::INI::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int8_t& a_value, + [[maybe_unused]] std::int8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + file->SetLongValue(a_section.data(), a_key.data(), a_value); +} + +template <> +void REX::INI::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int16_t& a_value, + [[maybe_unused]] std::int16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); +} + +template <> +void REX::INI::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int16_t& a_value, + [[maybe_unused]] std::int16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + file->SetLongValue(a_section.data(), a_key.data(), a_value); +} + +template <> +void REX::INI::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int32_t& a_value, + [[maybe_unused]] std::int32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); +} + +template <> +void REX::INI::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int32_t& a_value, + [[maybe_unused]] std::int32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + file->SetLongValue(a_section.data(), a_key.data(), a_value); +} + +template <> +void REX::INI::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint8_t& a_value, + [[maybe_unused]] std::uint8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); +} + +template <> +void REX::INI::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint8_t& a_value, + [[maybe_unused]] std::uint8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + file->SetLongValue(a_section.data(), a_key.data(), a_value); +} + +template <> +void REX::INI::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint16_t& a_value, + [[maybe_unused]] std::uint16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); +} + +template <> +void REX::INI::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint16_t& a_value, + [[maybe_unused]] std::uint16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + file->SetLongValue(a_section.data(), a_key.data(), a_value); +} + +template <> +void REX::INI::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint32_t& a_value, + [[maybe_unused]] std::uint32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); +} + +template <> +void REX::INI::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint32_t& a_value, + [[maybe_unused]] std::uint32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + file->SetLongValue(a_section.data(), a_key.data(), a_value); +} + +template <> +void REX::INI::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::string& a_value, + [[maybe_unused]] std::string& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + a_value = file->GetValue(a_section.data(), a_key.data(), a_valueDefault.c_str()); +} + +template <> +void REX::INI::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::string& a_value, + [[maybe_unused]] std::string& a_valueDefault, + [[maybe_unused]] std::string_view& a_section, + [[maybe_unused]] std::string_view& a_key) +{ + auto file = static_cast(a_file); + file->SetValue(a_section.data(), a_key.data(), a_value.c_str()); +} +#endif + +#ifdef REX_OPTION_JSON +//# include + +#endif + +#ifdef REX_OPTION_TOML +# include + +void REX::TOML::detail::StoreLoadImpl( + [[maybe_unused]] std::string_view& a_fileBase, + [[maybe_unused]] std::string_view& a_fileUser, + [[maybe_unused]] std::vector& a_settings) +{ + try { + auto result = toml::parse_file(a_fileBase); + for (auto& setting : a_settings) { + setting->Load(&result); + } + } catch (const toml::parse_error& e) { + SKSE::log::error("{}", e.description()); + } + + try { + auto result = toml::parse_file(a_fileUser); + for (auto& setting : a_settings) { + setting->Load(&result); + } + } catch (const toml::parse_error& e) { + SKSE::log::error("{}", e.description()); + } +} + +void REX::TOML::detail::StoreSaveImpl( + [[maybe_unused]] std::string_view& a_fileBase, + [[maybe_unused]] std::string_view& a_fileUser, + [[maybe_unused]] std::vector& a_settings) +{ + toml::parse_result output{}; + try { + output = toml::parse_file(a_fileBase); + } catch ([[maybe_unused]] const toml::parse_error& e) { + // ignore + } + + for (auto& setting : a_settings) { + setting->Save(&output); + } + + std::ofstream fileBase; + fileBase.open(a_fileBase, std::ios::ate | std::ios::trunc); + fileBase << toml::toml_formatter{ output }; + fileBase.close(); +} + +template <> +void REX::TOML::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + + [[maybe_unused]] bool& a_value, + [[maybe_unused]] bool& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + if (auto node = file->at_path(a_path)) { + a_value = node.value_or(a_valueDefault); + } +} + +template <> +void REX::TOML::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] bool& a_value, + [[maybe_unused]] bool& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + file->insert_or_assign(a_path, a_value); +} + +template <> +void REX::TOML::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] float& a_value, + [[maybe_unused]] float& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + if (auto node = file->at_path(a_path)) { + a_value = node.value_or(a_valueDefault); + } +} + +template <> +void REX::TOML::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] float& a_value, + [[maybe_unused]] float& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + file->insert_or_assign(a_path, a_value); +} + +template <> +void REX::TOML::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] double& a_value, + [[maybe_unused]] double& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + if (auto node = file->at_path(a_path)) { + a_value = node.value_or(a_valueDefault); + } +} + +template <> +void REX::TOML::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] double& a_value, + [[maybe_unused]] double& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + file->insert_or_assign(a_path, a_value); +} + +template <> +void REX::TOML::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int8_t& a_value, + [[maybe_unused]] std::int8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + if (auto node = file->at_path(a_path)) { + a_value = node.value_or(a_valueDefault); + } +} + +template <> +void REX::TOML::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + + [[maybe_unused]] std::int8_t& a_value, + [[maybe_unused]] std::int8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + file->insert_or_assign(a_path, a_value); +} + +template <> +void REX::TOML::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int16_t& a_value, + [[maybe_unused]] std::int16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + if (auto node = file->at_path(a_path)) { + a_value = node.value_or(a_valueDefault); + } +} + +template <> +void REX::TOML::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int16_t& a_value, + [[maybe_unused]] std::int16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + file->insert_or_assign(a_path, a_value); +} + +template <> +void REX::TOML::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int32_t& a_value, + [[maybe_unused]] std::int32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + if (auto node = file->at_path(a_path)) { + a_value = node.value_or(a_valueDefault); + } +} + +template <> +void REX::TOML::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int32_t& a_value, + [[maybe_unused]] std::int32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + file->insert_or_assign(a_path, a_value); +} + +template <> +void REX::TOML::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint8_t& a_value, + [[maybe_unused]] std::uint8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + if (auto node = file->at_path(a_path)) { + a_value = node.value_or(a_valueDefault); + } +} + +template <> +void REX::TOML::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint8_t& a_value, + [[maybe_unused]] std::uint8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + file->insert_or_assign(a_path, a_value); +} + +template <> +void REX::TOML::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint16_t& a_value, + [[maybe_unused]] std::uint16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + if (auto node = file->at_path(a_path)) { + a_value = node.value_or(a_valueDefault); + } +} + +template <> +void REX::TOML::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint16_t& a_value, + [[maybe_unused]] std::uint16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + file->insert_or_assign(a_path, a_value); +} + +template <> +void REX::TOML::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint32_t& a_value, + [[maybe_unused]] std::uint32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + if (auto node = file->at_path(a_path)) { + a_value = node.value_or(a_valueDefault); + } +} + +template <> +void REX::TOML::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint32_t& a_value, + [[maybe_unused]] std::uint32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + file->insert_or_assign(a_path, a_value); +} + +template <> +void REX::TOML::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::string& a_value, + [[maybe_unused]] std::string& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + if (auto node = file->at_path(a_path)) { + a_value = node.value_or(a_valueDefault); + } +} + +template <> +void REX::TOML::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::string& a_value, + [[maybe_unused]] std::string& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + file->insert_or_assign(a_path, a_value); +} +#endif diff --git a/xmake.lua b/xmake.lua index 054da0a14..ca4e1720e 100644 --- a/xmake.lua +++ b/xmake.lua @@ -33,6 +33,12 @@ option("rex_ini") add_defines("REX_OPTION_INI=1") option_end() +option("rex_json") + set_default(false) + set_description("Enable json config support for REX") + add_defines("REX_OPTION_JSON=1") +option_end() + option("rex_toml") set_default(false) set_description("Enable toml config support for REX") @@ -48,7 +54,11 @@ if has_config("skse_xbyak") then end if has_config("rex_ini") then - add_requires("simpleini", { configs = { convert = "none" }}) + add_requires("simpleini", { configs = { convert = "none" } }) +end + +if has_config("rex_json") then + add_requires("nlohmann_json") end if has_config("rex_toml") then @@ -74,12 +84,16 @@ target("commonlibsse", function() add_packages("simpleini", { public = true }) end + if has_config("rex_json") then + add_packages("nlohmann_json", { public = true }) + end + if has_config("rex_toml") then add_packages("toml++", { public = true }) end -- add options - add_options("skyrim_ae", "skse_xbyak", "rex_ini", "rex_toml", { public = true }) + add_options("skyrim_ae", "skse_xbyak", "rex_ini", "rex_json", "rex_toml", { public = true }) -- add system links add_syslinks("advapi32", "bcrypt", "d3d11", "d3dcompiler", "dbghelp", "dxgi", "ole32", "shell32", "user32", "version") From 5e597e86f93da31275781bc4b0dcc553dc441b72 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Tue, 12 Nov 2024 16:43:04 -0700 Subject: [PATCH 03/24] feat: REX json impl --- include/REX/REX/JSON.h | 15 +-- src/REX/REX.cpp | 270 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 277 insertions(+), 8 deletions(-) diff --git a/include/REX/REX/JSON.h b/include/REX/REX/JSON.h index ff1aee468..54d4c7e9e 100644 --- a/include/REX/REX/JSON.h +++ b/include/REX/REX/JSON.h @@ -10,9 +10,9 @@ namespace REX::JSON void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); void StoreSaveImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); template - void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault); + void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_path); template - void SettingSaveImpl(void* a_file, T& a_value, T& a_valueDefault); + void SettingSaveImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_path); } class SettingStore : @@ -35,23 +35,24 @@ namespace REX::JSON public TSetting { public: - Setting(T a_default) : - TSetting(a_default) + Setting(std::string_view a_path, T a_default) : + TSetting(a_default), + m_path(a_path) {} public: virtual void Load(void* a_file) override { - detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault); + detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, m_path); } virtual void Save(void* a_file) override { - detail::SettingSaveImpl(a_file, this->m_value, this->m_valueDefault); + detail::SettingSaveImpl(a_file, this->m_value, this->m_valueDefault, m_path); } private: - // std::string_view m_path; + std::string_view m_path; }; template diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index e7dfd42e2..921604f5c 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -286,8 +286,276 @@ void REX::INI::detail::SettingSaveImpl( #endif #ifdef REX_OPTION_JSON -//# include +# include +void REX::JSON::detail::StoreLoadImpl( + [[maybe_unused]] std::string_view& a_fileBase, + [[maybe_unused]] std::string_view& a_fileUser, + [[maybe_unused]] std::vector& a_settings) +{ + if (std::filesystem::exists(a_fileBase)) { + std::ifstream file{ a_fileBase.data() }; + try { + auto result = nlohmann::json::parse(file); + for (auto setting : a_settings) { + setting->Load(&result); + } + } catch (const std::exception& e) { + SKSE::log::error("{}", e.what()); + } + } + + if (std::filesystem::exists(a_fileUser)) { + std::ifstream file{ a_fileUser.data() }; + try { + auto result = nlohmann::json::parse(file); + for (auto setting : a_settings) { + setting->Load(&result); + } + } catch (const std::exception& e) { + SKSE::log::error("{}", e.what()); + } + } +} + +void REX::JSON::detail::StoreSaveImpl( + [[maybe_unused]] std::string_view& a_fileBase, + [[maybe_unused]] std::string_view& a_fileUser, + [[maybe_unused]] std::vector& a_settings) +{ + nlohmann::json output{}; + if (std::filesystem::exists(a_fileBase)) { + std::ifstream file{ a_fileBase.data() }; + output = nlohmann::json::parse(file); + } + + for (auto& setting : a_settings) { + setting->Save(&output); + } + + std::ofstream file{ a_fileBase.data(), std::ios::trunc }; + file << output.dump(4); +} + +template <> +void REX::JSON::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] bool& a_value, + [[maybe_unused]] bool& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + a_value = file->value(a_path, a_valueDefault); +} + +template <> +void REX::JSON::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] bool& a_value, + [[maybe_unused]] bool& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + (*file)[a_path] = a_value; +} + +template <> +void REX::JSON::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] float& a_value, + [[maybe_unused]] float& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + a_value = file->value(a_path, a_valueDefault); +} + +template <> +void REX::JSON::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] float& a_value, + [[maybe_unused]] float& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + (*file)[a_path] = a_value; +} + +template <> +void REX::JSON::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] double& a_value, + [[maybe_unused]] double& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + a_value = file->value(a_path, a_valueDefault); +} + +template <> +void REX::JSON::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] double& a_value, + [[maybe_unused]] double& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + (*file)[a_path] = a_value; +} + +template <> +void REX::JSON::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int8_t& a_value, + [[maybe_unused]] std::int8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + a_value = file->value(a_path, a_valueDefault); +} + +template <> +void REX::JSON::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int8_t& a_value, + [[maybe_unused]] std::int8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + (*file)[a_path] = a_value; +} + +template <> +void REX::JSON::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int16_t& a_value, + [[maybe_unused]] std::int16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + a_value = file->value(a_path, a_valueDefault); +} + +template <> +void REX::JSON::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int16_t& a_value, + [[maybe_unused]] std::int16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + (*file)[a_path] = a_value; +} + +template <> +void REX::JSON::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int32_t& a_value, + [[maybe_unused]] std::int32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + a_value = file->value(a_path, a_valueDefault); +} + +template <> +void REX::JSON::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::int32_t& a_value, + [[maybe_unused]] std::int32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + (*file)[a_path] = a_value; +} + +template <> +void REX::JSON::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint8_t& a_value, + [[maybe_unused]] std::uint8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + a_value = file->value(a_path, a_valueDefault); +} + +template <> +void REX::JSON::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint8_t& a_value, + [[maybe_unused]] std::uint8_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + (*file)[a_path] = a_value; +} + +template <> +void REX::JSON::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint16_t& a_value, + [[maybe_unused]] std::uint16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + a_value = file->value(a_path, a_valueDefault); +} + +template <> +void REX::JSON::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint16_t& a_value, + [[maybe_unused]] std::uint16_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + (*file)[a_path] = a_value; +} + +template <> +void REX::JSON::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint32_t& a_value, + [[maybe_unused]] std::uint32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + a_value = file->value(a_path, a_valueDefault); +} + +template <> +void REX::JSON::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::uint32_t& a_value, + [[maybe_unused]] std::uint32_t& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + (*file)[a_path] = a_value; +} + +template <> +void REX::JSON::detail::SettingLoadImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::string& a_value, + [[maybe_unused]] std::string& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + a_value = file->value(a_path, a_valueDefault); +} + +template <> +void REX::JSON::detail::SettingSaveImpl( + [[maybe_unused]] void* a_file, + [[maybe_unused]] std::string& a_value, + [[maybe_unused]] std::string& a_valueDefault, + [[maybe_unused]] std::string_view& a_path) +{ + auto file = static_cast(a_file); + (*file)[a_path] = a_value; +} #endif #ifdef REX_OPTION_TOML From e0d9e739b427bf2c188827196a2bd7285676cfae Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Tue, 12 Nov 2024 17:37:09 -0700 Subject: [PATCH 04/24] fix: disable REX toml Save functions don't have the energy for this right now --- src/REX/REX.cpp | 82 +++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 921604f5c..4a0b7fd13 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -571,8 +571,8 @@ void REX::TOML::detail::StoreLoadImpl( for (auto& setting : a_settings) { setting->Load(&result); } - } catch (const toml::parse_error& e) { - SKSE::log::error("{}", e.description()); + } catch (const std::exception& e) { + SKSE::log::error("{}", e.what()); } try { @@ -580,8 +580,8 @@ void REX::TOML::detail::StoreLoadImpl( for (auto& setting : a_settings) { setting->Load(&result); } - } catch (const toml::parse_error& e) { - SKSE::log::error("{}", e.description()); + } catch (const std::exception& e) { + SKSE::log::error("{}", e.what()); } } @@ -590,27 +590,24 @@ void REX::TOML::detail::StoreSaveImpl( [[maybe_unused]] std::string_view& a_fileUser, [[maybe_unused]] std::vector& a_settings) { - toml::parse_result output{}; - try { - output = toml::parse_file(a_fileBase); - } catch ([[maybe_unused]] const toml::parse_error& e) { - // ignore - } - - for (auto& setting : a_settings) { - setting->Save(&output); - } - - std::ofstream fileBase; - fileBase.open(a_fileBase, std::ios::ate | std::ios::trunc); - fileBase << toml::toml_formatter{ output }; - fileBase.close(); + // toml::parse_result output{}; + // try { + // output = toml::parse_file(a_fileBase); + // } catch ([[maybe_unused]] const std::exception& e) { + // // ignore + // } + // + // for (auto& setting : a_settings) { + // setting->Save(&output); + // } + // + // std::ofstream file{ a_fileBase.data(), std::ios::trunc }; + // file << output; } template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - + [[maybe_unused]] void* a_file, [[maybe_unused]] bool& a_value, [[maybe_unused]] bool& a_valueDefault, [[maybe_unused]] std::string_view& a_path) @@ -628,8 +625,8 @@ void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] bool& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { - auto file = static_cast(a_file); - file->insert_or_assign(a_path, a_value); + // auto file = static_cast(a_file); + // file->insert_or_assign(a_path, a_value); } template <> @@ -652,8 +649,8 @@ void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] float& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { - auto file = static_cast(a_file); - file->insert_or_assign(a_path, a_value); + // auto file = static_cast(a_file); + // file->insert_or_assign(a_path, a_value); } template <> @@ -676,8 +673,8 @@ void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] double& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { - auto file = static_cast(a_file); - file->insert_or_assign(a_path, a_value); + // auto file = static_cast(a_file); + // file->insert_or_assign(a_path, a_value); } template <> @@ -695,14 +692,13 @@ void REX::TOML::detail::SettingLoadImpl( template <> void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - + [[maybe_unused]] void* a_file, [[maybe_unused]] std::int8_t& a_value, [[maybe_unused]] std::int8_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { - auto file = static_cast(a_file); - file->insert_or_assign(a_path, a_value); + // auto file = static_cast(a_file); + // file->insert_or_assign(a_path, a_value); } template <> @@ -725,8 +721,8 @@ void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] std::int16_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { - auto file = static_cast(a_file); - file->insert_or_assign(a_path, a_value); + // auto file = static_cast(a_file); + // file->insert_or_assign(a_path, a_value); } template <> @@ -749,8 +745,8 @@ void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] std::int32_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { - auto file = static_cast(a_file); - file->insert_or_assign(a_path, a_value); + // auto file = static_cast(a_file); + // file->insert_or_assign(a_path, a_value); } template <> @@ -773,8 +769,8 @@ void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] std::uint8_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { - auto file = static_cast(a_file); - file->insert_or_assign(a_path, a_value); + // auto file = static_cast(a_file); + // file->insert_or_assign(a_path, a_value); } template <> @@ -797,8 +793,8 @@ void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] std::uint16_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { - auto file = static_cast(a_file); - file->insert_or_assign(a_path, a_value); + // auto file = static_cast(a_file); + // file->insert_or_assign(a_path, a_value); } template <> @@ -821,8 +817,8 @@ void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] std::uint32_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { - auto file = static_cast(a_file); - file->insert_or_assign(a_path, a_value); + // auto file = static_cast(a_file); + // file->insert_or_assign(a_path, a_value); } template <> @@ -845,7 +841,7 @@ void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] std::string& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { - auto file = static_cast(a_file); - file->insert_or_assign(a_path, a_value); + // auto file = static_cast(a_file); + // file->insert_or_assign(a_path, a_value); } #endif From 8b03e42a20a41d040053555621a0bee4a4171d29 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Tue, 12 Nov 2024 18:07:46 -0700 Subject: [PATCH 05/24] refactor: remove maybe_unused tags, unused args --- include/REX/REX/INI.h | 8 +- include/REX/REX/JSON.h | 8 +- include/REX/REX/TOML.h | 8 +- src/REX/REX.cpp | 461 +++++++++++++++++++---------------------- 4 files changed, 226 insertions(+), 259 deletions(-) diff --git a/include/REX/REX/INI.h b/include/REX/REX/INI.h index e455eee73..e1f03d563 100644 --- a/include/REX/REX/INI.h +++ b/include/REX/REX/INI.h @@ -8,11 +8,11 @@ namespace REX::INI namespace detail { void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); - void StoreSaveImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); + void StoreSaveImpl(std::string_view& a_fileBase, std::vector& a_settings); template void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_section, std::string_view& a_key); template - void SettingSaveImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_section, std::string_view& a_key); + void SettingSaveImpl(void* a_file, T& a_value, std::string_view& a_section, std::string_view& a_key); } class SettingStore : @@ -26,7 +26,7 @@ namespace REX::INI virtual void Save() override { - detail::StoreSaveImpl(m_fileBase, m_fileUser, m_settings); + detail::StoreSaveImpl(m_fileBase, m_settings); } }; @@ -49,7 +49,7 @@ namespace REX::INI virtual void Save(void* a_file) override { - detail::SettingSaveImpl(a_file, this->m_value, this->m_valueDefault, m_section, m_key); + detail::SettingSaveImpl(a_file, this->m_value, m_section, m_key); } private: diff --git a/include/REX/REX/JSON.h b/include/REX/REX/JSON.h index 54d4c7e9e..866d9bbbc 100644 --- a/include/REX/REX/JSON.h +++ b/include/REX/REX/JSON.h @@ -8,11 +8,11 @@ namespace REX::JSON namespace detail { void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); - void StoreSaveImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); + void StoreSaveImpl(std::string_view& a_fileBase, std::vector& a_settings); template void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_path); template - void SettingSaveImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_path); + void SettingSaveImpl(void* a_file, T& a_value, std::string_view& a_path); } class SettingStore : @@ -26,7 +26,7 @@ namespace REX::JSON virtual void Save() override { - detail::StoreSaveImpl(m_fileBase, m_fileUser, m_settings); + detail::StoreSaveImpl(m_fileBase, m_settings); } }; @@ -48,7 +48,7 @@ namespace REX::JSON virtual void Save(void* a_file) override { - detail::SettingSaveImpl(a_file, this->m_value, this->m_valueDefault, m_path); + detail::SettingSaveImpl(a_file, this->m_value, m_path); } private: diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index 862313bc8..f81673dab 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -8,11 +8,11 @@ namespace REX::TOML namespace detail { void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); - void StoreSaveImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); + void StoreSaveImpl(std::string_view& a_fileBase, std::vector& a_settings); template void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_path); template - void SettingSaveImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_path); + void SettingSaveImpl(void* a_file, T& a_value, std::string_view& a_path); } class SettingStore : @@ -26,7 +26,7 @@ namespace REX::TOML virtual void Save() override { - detail::StoreSaveImpl(m_fileBase, m_fileUser, m_settings); + detail::StoreSaveImpl(m_fileBase, m_settings); } }; @@ -48,7 +48,7 @@ namespace REX::TOML virtual void Save(void* a_file) override { - detail::SettingSaveImpl(a_file, this->m_value, this->m_valueDefault, m_path); + detail::SettingSaveImpl(a_file, this->m_value, m_path); } private: diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 4a0b7fd13..bb38bf976 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -6,9 +6,9 @@ # include void REX::INI::detail::StoreLoadImpl( - [[maybe_unused]] std::string_view& a_fileBase, - [[maybe_unused]] std::string_view& a_fileUser, - [[maybe_unused]] std::vector& a_settings) + std::string_view& a_fileBase, + std::string_view& a_fileUser, + std::vector& a_settings) { CSimpleIniA ini; ini.SetUnicode(true); @@ -28,9 +28,8 @@ void REX::INI::detail::StoreLoadImpl( } void REX::INI::detail::StoreSaveImpl( - [[maybe_unused]] std::string_view& a_fileBase, - [[maybe_unused]] std::string_view& a_fileUser, - [[maybe_unused]] std::vector& a_settings) + std::string_view& a_fileBase, + std::vector& a_settings) { CSimpleIniA ini; ini.SetUnicode(true); @@ -46,11 +45,11 @@ void REX::INI::detail::StoreSaveImpl( template <> void REX::INI::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] bool& a_value, - [[maybe_unused]] bool& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + bool& a_value, + bool& a_valueDefault, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); a_value = file->GetBoolValue(a_section.data(), a_key.data(), a_valueDefault); @@ -58,11 +57,10 @@ void REX::INI::detail::SettingLoadImpl( template <> void REX::INI::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] bool& a_value, - [[maybe_unused]] bool& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + bool& a_value, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); file->SetBoolValue(a_section.data(), a_key.data(), a_value); @@ -70,11 +68,11 @@ void REX::INI::detail::SettingSaveImpl( template <> void REX::INI::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] float& a_value, - [[maybe_unused]] float& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + float& a_value, + float& a_valueDefault, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); a_value = static_cast(file->GetDoubleValue(a_section.data(), a_key.data(), a_valueDefault)); @@ -82,11 +80,10 @@ void REX::INI::detail::SettingLoadImpl( template <> void REX::INI::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] float& a_value, - [[maybe_unused]] float& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + float& a_value, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); file->SetDoubleValue(a_section.data(), a_key.data(), a_value); @@ -94,11 +91,11 @@ void REX::INI::detail::SettingSaveImpl( template <> void REX::INI::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] double& a_value, - [[maybe_unused]] double& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + double& a_value, + double& a_valueDefault, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); a_value = file->GetDoubleValue(a_section.data(), a_key.data(), a_valueDefault); @@ -106,11 +103,10 @@ void REX::INI::detail::SettingLoadImpl( template <> void REX::INI::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] double& a_value, - [[maybe_unused]] double& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + double& a_value, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); file->SetDoubleValue(a_section.data(), a_key.data(), a_value); @@ -118,11 +114,11 @@ void REX::INI::detail::SettingSaveImpl( template <> void REX::INI::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int8_t& a_value, - [[maybe_unused]] std::int8_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::int8_t& a_value, + std::int8_t& a_valueDefault, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); @@ -130,11 +126,10 @@ void REX::INI::detail::SettingLoadImpl( template <> void REX::INI::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int8_t& a_value, - [[maybe_unused]] std::int8_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::int8_t& a_value, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); file->SetLongValue(a_section.data(), a_key.data(), a_value); @@ -142,11 +137,11 @@ void REX::INI::detail::SettingSaveImpl( template <> void REX::INI::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int16_t& a_value, - [[maybe_unused]] std::int16_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::int16_t& a_value, + std::int16_t& a_valueDefault, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); @@ -154,11 +149,10 @@ void REX::INI::detail::SettingLoadImpl( template <> void REX::INI::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int16_t& a_value, - [[maybe_unused]] std::int16_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::int16_t& a_value, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); file->SetLongValue(a_section.data(), a_key.data(), a_value); @@ -166,11 +160,11 @@ void REX::INI::detail::SettingSaveImpl( template <> void REX::INI::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int32_t& a_value, - [[maybe_unused]] std::int32_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::int32_t& a_value, + std::int32_t& a_valueDefault, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); @@ -178,11 +172,10 @@ void REX::INI::detail::SettingLoadImpl( template <> void REX::INI::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int32_t& a_value, - [[maybe_unused]] std::int32_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::int32_t& a_value, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); file->SetLongValue(a_section.data(), a_key.data(), a_value); @@ -190,11 +183,11 @@ void REX::INI::detail::SettingSaveImpl( template <> void REX::INI::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint8_t& a_value, - [[maybe_unused]] std::uint8_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::uint8_t& a_value, + std::uint8_t& a_valueDefault, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); @@ -202,11 +195,10 @@ void REX::INI::detail::SettingLoadImpl( template <> void REX::INI::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint8_t& a_value, - [[maybe_unused]] std::uint8_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::uint8_t& a_value, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); file->SetLongValue(a_section.data(), a_key.data(), a_value); @@ -214,11 +206,11 @@ void REX::INI::detail::SettingSaveImpl( template <> void REX::INI::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint16_t& a_value, - [[maybe_unused]] std::uint16_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::uint16_t& a_value, + std::uint16_t& a_valueDefault, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); @@ -226,11 +218,10 @@ void REX::INI::detail::SettingLoadImpl( template <> void REX::INI::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint16_t& a_value, - [[maybe_unused]] std::uint16_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::uint16_t& a_value, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); file->SetLongValue(a_section.data(), a_key.data(), a_value); @@ -238,11 +229,11 @@ void REX::INI::detail::SettingSaveImpl( template <> void REX::INI::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint32_t& a_value, - [[maybe_unused]] std::uint32_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::uint32_t& a_value, + std::uint32_t& a_valueDefault, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); @@ -250,11 +241,10 @@ void REX::INI::detail::SettingLoadImpl( template <> void REX::INI::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint32_t& a_value, - [[maybe_unused]] std::uint32_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::uint32_t& a_value, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); file->SetLongValue(a_section.data(), a_key.data(), a_value); @@ -262,11 +252,11 @@ void REX::INI::detail::SettingSaveImpl( template <> void REX::INI::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::string& a_value, - [[maybe_unused]] std::string& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::string& a_value, + std::string& a_valueDefault, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); a_value = file->GetValue(a_section.data(), a_key.data(), a_valueDefault.c_str()); @@ -274,11 +264,10 @@ void REX::INI::detail::SettingLoadImpl( template <> void REX::INI::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::string& a_value, - [[maybe_unused]] std::string& a_valueDefault, - [[maybe_unused]] std::string_view& a_section, - [[maybe_unused]] std::string_view& a_key) + void* a_file, + std::string& a_value, + std::string_view& a_section, + std::string_view& a_key) { auto file = static_cast(a_file); file->SetValue(a_section.data(), a_key.data(), a_value.c_str()); @@ -289,9 +278,9 @@ void REX::INI::detail::SettingSaveImpl( # include void REX::JSON::detail::StoreLoadImpl( - [[maybe_unused]] std::string_view& a_fileBase, - [[maybe_unused]] std::string_view& a_fileUser, - [[maybe_unused]] std::vector& a_settings) + std::string_view& a_fileBase, + std::string_view& a_fileUser, + std::vector& a_settings) { if (std::filesystem::exists(a_fileBase)) { std::ifstream file{ a_fileBase.data() }; @@ -319,9 +308,8 @@ void REX::JSON::detail::StoreLoadImpl( } void REX::JSON::detail::StoreSaveImpl( - [[maybe_unused]] std::string_view& a_fileBase, - [[maybe_unused]] std::string_view& a_fileUser, - [[maybe_unused]] std::vector& a_settings) + std::string_view& a_fileBase, + std::vector& a_settings) { nlohmann::json output{}; if (std::filesystem::exists(a_fileBase)) { @@ -339,10 +327,10 @@ void REX::JSON::detail::StoreSaveImpl( template <> void REX::JSON::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] bool& a_value, - [[maybe_unused]] bool& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + bool& a_value, + bool& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); a_value = file->value(a_path, a_valueDefault); @@ -350,10 +338,9 @@ void REX::JSON::detail::SettingLoadImpl( template <> void REX::JSON::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] bool& a_value, - [[maybe_unused]] bool& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + bool& a_value, + std::string_view& a_path) { auto file = static_cast(a_file); (*file)[a_path] = a_value; @@ -361,10 +348,10 @@ void REX::JSON::detail::SettingSaveImpl( template <> void REX::JSON::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] float& a_value, - [[maybe_unused]] float& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + float& a_value, + float& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); a_value = file->value(a_path, a_valueDefault); @@ -372,10 +359,9 @@ void REX::JSON::detail::SettingLoadImpl( template <> void REX::JSON::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] float& a_value, - [[maybe_unused]] float& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + float& a_value, + std::string_view& a_path) { auto file = static_cast(a_file); (*file)[a_path] = a_value; @@ -383,10 +369,10 @@ void REX::JSON::detail::SettingSaveImpl( template <> void REX::JSON::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] double& a_value, - [[maybe_unused]] double& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + double& a_value, + double& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); a_value = file->value(a_path, a_valueDefault); @@ -394,10 +380,9 @@ void REX::JSON::detail::SettingLoadImpl( template <> void REX::JSON::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] double& a_value, - [[maybe_unused]] double& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + double& a_value, + std::string_view& a_path) { auto file = static_cast(a_file); (*file)[a_path] = a_value; @@ -405,10 +390,10 @@ void REX::JSON::detail::SettingSaveImpl( template <> void REX::JSON::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int8_t& a_value, - [[maybe_unused]] std::int8_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::int8_t& a_value, + std::int8_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); a_value = file->value(a_path, a_valueDefault); @@ -416,10 +401,9 @@ void REX::JSON::detail::SettingLoadImpl( template <> void REX::JSON::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int8_t& a_value, - [[maybe_unused]] std::int8_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::int8_t& a_value, + std::string_view& a_path) { auto file = static_cast(a_file); (*file)[a_path] = a_value; @@ -427,10 +411,10 @@ void REX::JSON::detail::SettingSaveImpl( template <> void REX::JSON::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int16_t& a_value, - [[maybe_unused]] std::int16_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::int16_t& a_value, + std::int16_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); a_value = file->value(a_path, a_valueDefault); @@ -438,10 +422,9 @@ void REX::JSON::detail::SettingLoadImpl( template <> void REX::JSON::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int16_t& a_value, - [[maybe_unused]] std::int16_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::int16_t& a_value, + std::string_view& a_path) { auto file = static_cast(a_file); (*file)[a_path] = a_value; @@ -449,10 +432,10 @@ void REX::JSON::detail::SettingSaveImpl( template <> void REX::JSON::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int32_t& a_value, - [[maybe_unused]] std::int32_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::int32_t& a_value, + std::int32_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); a_value = file->value(a_path, a_valueDefault); @@ -460,10 +443,9 @@ void REX::JSON::detail::SettingLoadImpl( template <> void REX::JSON::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int32_t& a_value, - [[maybe_unused]] std::int32_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::int32_t& a_value, + std::string_view& a_path) { auto file = static_cast(a_file); (*file)[a_path] = a_value; @@ -471,10 +453,10 @@ void REX::JSON::detail::SettingSaveImpl( template <> void REX::JSON::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint8_t& a_value, - [[maybe_unused]] std::uint8_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::uint8_t& a_value, + std::uint8_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); a_value = file->value(a_path, a_valueDefault); @@ -482,10 +464,9 @@ void REX::JSON::detail::SettingLoadImpl( template <> void REX::JSON::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint8_t& a_value, - [[maybe_unused]] std::uint8_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::uint8_t& a_value, + std::string_view& a_path) { auto file = static_cast(a_file); (*file)[a_path] = a_value; @@ -493,10 +474,10 @@ void REX::JSON::detail::SettingSaveImpl( template <> void REX::JSON::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint16_t& a_value, - [[maybe_unused]] std::uint16_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::uint16_t& a_value, + std::uint16_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); a_value = file->value(a_path, a_valueDefault); @@ -504,10 +485,9 @@ void REX::JSON::detail::SettingLoadImpl( template <> void REX::JSON::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint16_t& a_value, - [[maybe_unused]] std::uint16_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::uint16_t& a_value, + std::string_view& a_path) { auto file = static_cast(a_file); (*file)[a_path] = a_value; @@ -515,10 +495,10 @@ void REX::JSON::detail::SettingSaveImpl( template <> void REX::JSON::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint32_t& a_value, - [[maybe_unused]] std::uint32_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::uint32_t& a_value, + std::uint32_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); a_value = file->value(a_path, a_valueDefault); @@ -526,10 +506,9 @@ void REX::JSON::detail::SettingLoadImpl( template <> void REX::JSON::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint32_t& a_value, - [[maybe_unused]] std::uint32_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::uint32_t& a_value, + std::string_view& a_path) { auto file = static_cast(a_file); (*file)[a_path] = a_value; @@ -537,10 +516,10 @@ void REX::JSON::detail::SettingSaveImpl( template <> void REX::JSON::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::string& a_value, - [[maybe_unused]] std::string& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::string& a_value, + std::string& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); a_value = file->value(a_path, a_valueDefault); @@ -548,10 +527,9 @@ void REX::JSON::detail::SettingLoadImpl( template <> void REX::JSON::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::string& a_value, - [[maybe_unused]] std::string& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::string& a_value, + std::string_view& a_path) { auto file = static_cast(a_file); (*file)[a_path] = a_value; @@ -562,9 +540,9 @@ void REX::JSON::detail::SettingSaveImpl( # include void REX::TOML::detail::StoreLoadImpl( - [[maybe_unused]] std::string_view& a_fileBase, - [[maybe_unused]] std::string_view& a_fileUser, - [[maybe_unused]] std::vector& a_settings) + std::string_view& a_fileBase, + std::string_view& a_fileUser, + std::vector& a_settings) { try { auto result = toml::parse_file(a_fileBase); @@ -587,13 +565,12 @@ void REX::TOML::detail::StoreLoadImpl( void REX::TOML::detail::StoreSaveImpl( [[maybe_unused]] std::string_view& a_fileBase, - [[maybe_unused]] std::string_view& a_fileUser, [[maybe_unused]] std::vector& a_settings) { // toml::parse_result output{}; // try { // output = toml::parse_file(a_fileBase); - // } catch ([[maybe_unused]] const std::exception& e) { + // } catch (const std::exception& e) { // // ignore // } // @@ -607,10 +584,10 @@ void REX::TOML::detail::StoreSaveImpl( template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] bool& a_value, - [[maybe_unused]] bool& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + bool& a_value, + bool& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { @@ -622,7 +599,6 @@ template <> void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] void* a_file, [[maybe_unused]] bool& a_value, - [[maybe_unused]] bool& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { // auto file = static_cast(a_file); @@ -631,10 +607,10 @@ void REX::TOML::detail::SettingSaveImpl( template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] float& a_value, - [[maybe_unused]] float& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + float& a_value, + float& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { @@ -646,7 +622,6 @@ template <> void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] void* a_file, [[maybe_unused]] float& a_value, - [[maybe_unused]] float& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { // auto file = static_cast(a_file); @@ -655,10 +630,10 @@ void REX::TOML::detail::SettingSaveImpl( template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] double& a_value, - [[maybe_unused]] double& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + double& a_value, + double& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { @@ -670,7 +645,6 @@ template <> void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] void* a_file, [[maybe_unused]] double& a_value, - [[maybe_unused]] double& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { // auto file = static_cast(a_file); @@ -679,10 +653,10 @@ void REX::TOML::detail::SettingSaveImpl( template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int8_t& a_value, - [[maybe_unused]] std::int8_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::int8_t& a_value, + std::int8_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { @@ -694,7 +668,6 @@ template <> void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] void* a_file, [[maybe_unused]] std::int8_t& a_value, - [[maybe_unused]] std::int8_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { // auto file = static_cast(a_file); @@ -703,10 +676,10 @@ void REX::TOML::detail::SettingSaveImpl( template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int16_t& a_value, - [[maybe_unused]] std::int16_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::int16_t& a_value, + std::int16_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { @@ -718,7 +691,6 @@ template <> void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] void* a_file, [[maybe_unused]] std::int16_t& a_value, - [[maybe_unused]] std::int16_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { // auto file = static_cast(a_file); @@ -727,10 +699,10 @@ void REX::TOML::detail::SettingSaveImpl( template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int32_t& a_value, - [[maybe_unused]] std::int32_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::int32_t& a_value, + std::int32_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { @@ -742,7 +714,6 @@ template <> void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] void* a_file, [[maybe_unused]] std::int32_t& a_value, - [[maybe_unused]] std::int32_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { // auto file = static_cast(a_file); @@ -751,10 +722,10 @@ void REX::TOML::detail::SettingSaveImpl( template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint8_t& a_value, - [[maybe_unused]] std::uint8_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::uint8_t& a_value, + std::uint8_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { @@ -766,7 +737,6 @@ template <> void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] void* a_file, [[maybe_unused]] std::uint8_t& a_value, - [[maybe_unused]] std::uint8_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { // auto file = static_cast(a_file); @@ -775,10 +745,10 @@ void REX::TOML::detail::SettingSaveImpl( template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint16_t& a_value, - [[maybe_unused]] std::uint16_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::uint16_t& a_value, + std::uint16_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { @@ -790,7 +760,6 @@ template <> void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] void* a_file, [[maybe_unused]] std::uint16_t& a_value, - [[maybe_unused]] std::uint16_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { // auto file = static_cast(a_file); @@ -799,10 +768,10 @@ void REX::TOML::detail::SettingSaveImpl( template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint32_t& a_value, - [[maybe_unused]] std::uint32_t& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::uint32_t& a_value, + std::uint32_t& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { @@ -814,7 +783,6 @@ template <> void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] void* a_file, [[maybe_unused]] std::uint32_t& a_value, - [[maybe_unused]] std::uint32_t& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { // auto file = static_cast(a_file); @@ -823,10 +791,10 @@ void REX::TOML::detail::SettingSaveImpl( template <> void REX::TOML::detail::SettingLoadImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::string& a_value, - [[maybe_unused]] std::string& a_valueDefault, - [[maybe_unused]] std::string_view& a_path) + void* a_file, + std::string& a_value, + std::string& a_valueDefault, + std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { @@ -838,7 +806,6 @@ template <> void REX::TOML::detail::SettingSaveImpl( [[maybe_unused]] void* a_file, [[maybe_unused]] std::string& a_value, - [[maybe_unused]] std::string& a_valueDefault, [[maybe_unused]] std::string_view& a_path) { // auto file = static_cast(a_file); From 9c9e481472451d022c1218453e127c6c495f2e6e Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Tue, 12 Nov 2024 18:08:32 -0700 Subject: [PATCH 06/24] fix: user config no longer overrides base config --- include/REX/REX/INI.h | 9 +++- include/REX/REX/JSON.h | 9 +++- include/REX/REX/Setting.h | 1 + include/REX/REX/TOML.h | 9 +++- src/REX/REX.cpp | 96 +++++++++++++++++++++++++-------------- 5 files changed, 85 insertions(+), 39 deletions(-) diff --git a/include/REX/REX/INI.h b/include/REX/REX/INI.h index e1f03d563..7ca4f4586 100644 --- a/include/REX/REX/INI.h +++ b/include/REX/REX/INI.h @@ -10,7 +10,7 @@ namespace REX::INI void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); void StoreSaveImpl(std::string_view& a_fileBase, std::vector& a_settings); template - void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_section, std::string_view& a_key); + void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, bool a_useDefault, std::string_view& a_section, std::string_view& a_key); template void SettingSaveImpl(void* a_file, T& a_value, std::string_view& a_section, std::string_view& a_key); } @@ -44,7 +44,12 @@ namespace REX::INI public: virtual void Load(void* a_file) override { - detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, m_section, m_key); + Load(a_file, true); + } + + virtual void Load(void* a_file, bool a_useDefault) override + { + detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, a_useDefault, m_section, m_key); } virtual void Save(void* a_file) override diff --git a/include/REX/REX/JSON.h b/include/REX/REX/JSON.h index 866d9bbbc..aa0b2804d 100644 --- a/include/REX/REX/JSON.h +++ b/include/REX/REX/JSON.h @@ -10,7 +10,7 @@ namespace REX::JSON void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); void StoreSaveImpl(std::string_view& a_fileBase, std::vector& a_settings); template - void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_path); + void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, bool a_useDefault, std::string_view& a_path); template void SettingSaveImpl(void* a_file, T& a_value, std::string_view& a_path); } @@ -43,7 +43,12 @@ namespace REX::JSON public: virtual void Load(void* a_file) override { - detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, m_path); + Load(a_file, true); + } + + virtual void Load(void* a_file, bool a_useDefault) override + { + detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, a_useDefault, m_path); } virtual void Save(void* a_file) override diff --git a/include/REX/REX/Setting.h b/include/REX/REX/Setting.h index f6217dd6b..32618262a 100644 --- a/include/REX/REX/Setting.h +++ b/include/REX/REX/Setting.h @@ -8,6 +8,7 @@ namespace REX { public: virtual void Load(void* a_file) = 0; + virtual void Load(void* a_file, bool a_useDefault) = 0; virtual void Save(void* a_file) = 0; }; diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index f81673dab..e56f94766 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -10,7 +10,7 @@ namespace REX::TOML void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); void StoreSaveImpl(std::string_view& a_fileBase, std::vector& a_settings); template - void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, std::string_view& a_path); + void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, bool a_useDefault, std::string_view& a_path); template void SettingSaveImpl(void* a_file, T& a_value, std::string_view& a_path); } @@ -43,7 +43,12 @@ namespace REX::TOML public: virtual void Load(void* a_file) override { - detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, m_path); + Load(a_file, true); + } + + virtual void Load(void* a_file, bool a_useDefault) override + { + detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, a_useDefault, m_path); } virtual void Save(void* a_file) override diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index bb38bf976..79ddb137a 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -22,7 +22,7 @@ void REX::INI::detail::StoreLoadImpl( if (ini.LoadFile(a_fileUser.data()) == SI_OK) { for (auto& setting : a_settings) { - setting->Load(&ini); + setting->Load(&ini, false); } } } @@ -48,11 +48,12 @@ void REX::INI::detail::SettingLoadImpl( void* a_file, bool& a_value, bool& a_valueDefault, + bool a_useDefault, std::string_view& a_section, std::string_view& a_key) { auto file = static_cast(a_file); - a_value = file->GetBoolValue(a_section.data(), a_key.data(), a_valueDefault); + a_value = file->GetBoolValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value); } template <> @@ -71,11 +72,12 @@ void REX::INI::detail::SettingLoadImpl( void* a_file, float& a_value, float& a_valueDefault, + bool a_useDefault, std::string_view& a_section, std::string_view& a_key) { auto file = static_cast(a_file); - a_value = static_cast(file->GetDoubleValue(a_section.data(), a_key.data(), a_valueDefault)); + a_value = static_cast(file->GetDoubleValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); } template <> @@ -94,11 +96,12 @@ void REX::INI::detail::SettingLoadImpl( void* a_file, double& a_value, double& a_valueDefault, + bool a_useDefault, std::string_view& a_section, std::string_view& a_key) { auto file = static_cast(a_file); - a_value = file->GetDoubleValue(a_section.data(), a_key.data(), a_valueDefault); + a_value = file->GetDoubleValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value); } template <> @@ -117,11 +120,12 @@ void REX::INI::detail::SettingLoadImpl( void* a_file, std::int8_t& a_value, std::int8_t& a_valueDefault, + bool a_useDefault, std::string_view& a_section, std::string_view& a_key) { auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); } template <> @@ -140,11 +144,12 @@ void REX::INI::detail::SettingLoadImpl( void* a_file, std::int16_t& a_value, std::int16_t& a_valueDefault, + bool a_useDefault, std::string_view& a_section, std::string_view& a_key) { auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); } template <> @@ -163,11 +168,12 @@ void REX::INI::detail::SettingLoadImpl( void* a_file, std::int32_t& a_value, std::int32_t& a_valueDefault, + bool a_useDefault, std::string_view& a_section, std::string_view& a_key) { auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); } template <> @@ -186,11 +192,12 @@ void REX::INI::detail::SettingLoadImpl( void* a_file, std::uint8_t& a_value, std::uint8_t& a_valueDefault, + bool a_useDefault, std::string_view& a_section, std::string_view& a_key) { auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); } template <> @@ -209,11 +216,12 @@ void REX::INI::detail::SettingLoadImpl( void* a_file, std::uint16_t& a_value, std::uint16_t& a_valueDefault, + bool a_useDefault, std::string_view& a_section, std::string_view& a_key) { auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); } template <> @@ -232,11 +240,12 @@ void REX::INI::detail::SettingLoadImpl( void* a_file, std::uint32_t& a_value, std::uint32_t& a_valueDefault, + bool a_useDefault, std::string_view& a_section, std::string_view& a_key) { auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); } template <> @@ -255,11 +264,12 @@ void REX::INI::detail::SettingLoadImpl( void* a_file, std::string& a_value, std::string& a_valueDefault, + bool a_useDefault, std::string_view& a_section, std::string_view& a_key) { auto file = static_cast(a_file); - a_value = file->GetValue(a_section.data(), a_key.data(), a_valueDefault.c_str()); + a_value = file->GetValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault.c_str() : a_value.c_str()); } template <> @@ -299,7 +309,7 @@ void REX::JSON::detail::StoreLoadImpl( try { auto result = nlohmann::json::parse(file); for (auto setting : a_settings) { - setting->Load(&result); + setting->Load(&result, false); } } catch (const std::exception& e) { SKSE::log::error("{}", e.what()); @@ -330,10 +340,11 @@ void REX::JSON::detail::SettingLoadImpl( void* a_file, bool& a_value, bool& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); - a_value = file->value(a_path, a_valueDefault); + a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); } template <> @@ -351,10 +362,11 @@ void REX::JSON::detail::SettingLoadImpl( void* a_file, float& a_value, float& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); - a_value = file->value(a_path, a_valueDefault); + a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); } template <> @@ -372,10 +384,11 @@ void REX::JSON::detail::SettingLoadImpl( void* a_file, double& a_value, double& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); - a_value = file->value(a_path, a_valueDefault); + a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); } template <> @@ -393,10 +406,11 @@ void REX::JSON::detail::SettingLoadImpl( void* a_file, std::int8_t& a_value, std::int8_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); - a_value = file->value(a_path, a_valueDefault); + a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); } template <> @@ -414,10 +428,11 @@ void REX::JSON::detail::SettingLoadImpl( void* a_file, std::int16_t& a_value, std::int16_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); - a_value = file->value(a_path, a_valueDefault); + a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); } template <> @@ -435,10 +450,11 @@ void REX::JSON::detail::SettingLoadImpl( void* a_file, std::int32_t& a_value, std::int32_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); - a_value = file->value(a_path, a_valueDefault); + a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); } template <> @@ -456,10 +472,11 @@ void REX::JSON::detail::SettingLoadImpl( void* a_file, std::uint8_t& a_value, std::uint8_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); - a_value = file->value(a_path, a_valueDefault); + a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); } template <> @@ -477,10 +494,11 @@ void REX::JSON::detail::SettingLoadImpl( void* a_file, std::uint16_t& a_value, std::uint16_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); - a_value = file->value(a_path, a_valueDefault); + a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); } template <> @@ -498,10 +516,11 @@ void REX::JSON::detail::SettingLoadImpl( void* a_file, std::uint32_t& a_value, std::uint32_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); - a_value = file->value(a_path, a_valueDefault); + a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); } template <> @@ -519,10 +538,11 @@ void REX::JSON::detail::SettingLoadImpl( void* a_file, std::string& a_value, std::string& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); - a_value = file->value(a_path, a_valueDefault); + a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); } template <> @@ -556,7 +576,7 @@ void REX::TOML::detail::StoreLoadImpl( try { auto result = toml::parse_file(a_fileUser); for (auto& setting : a_settings) { - setting->Load(&result); + setting->Load(&result, false); } } catch (const std::exception& e) { SKSE::log::error("{}", e.what()); @@ -587,11 +607,12 @@ void REX::TOML::detail::SettingLoadImpl( void* a_file, bool& a_value, bool& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_valueDefault); + a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); } } @@ -610,11 +631,12 @@ void REX::TOML::detail::SettingLoadImpl( void* a_file, float& a_value, float& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_valueDefault); + a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); } } @@ -633,11 +655,12 @@ void REX::TOML::detail::SettingLoadImpl( void* a_file, double& a_value, double& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_valueDefault); + a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); } } @@ -656,11 +679,12 @@ void REX::TOML::detail::SettingLoadImpl( void* a_file, std::int8_t& a_value, std::int8_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_valueDefault); + a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); } } @@ -679,11 +703,12 @@ void REX::TOML::detail::SettingLoadImpl( void* a_file, std::int16_t& a_value, std::int16_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_valueDefault); + a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); } } @@ -702,11 +727,12 @@ void REX::TOML::detail::SettingLoadImpl( void* a_file, std::int32_t& a_value, std::int32_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_valueDefault); + a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); } } @@ -725,11 +751,12 @@ void REX::TOML::detail::SettingLoadImpl( void* a_file, std::uint8_t& a_value, std::uint8_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_valueDefault); + a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); } } @@ -748,11 +775,12 @@ void REX::TOML::detail::SettingLoadImpl( void* a_file, std::uint16_t& a_value, std::uint16_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_valueDefault); + a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); } } @@ -771,11 +799,12 @@ void REX::TOML::detail::SettingLoadImpl( void* a_file, std::uint32_t& a_value, std::uint32_t& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_valueDefault); + a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); } } @@ -794,11 +823,12 @@ void REX::TOML::detail::SettingLoadImpl( void* a_file, std::string& a_value, std::string& a_valueDefault, + bool a_useDefault, std::string_view& a_path) { auto file = static_cast(a_file); if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_valueDefault); + a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); } } From ebfda8b7d4e085dbeb6f028286fa3c217826e019 Mon Sep 17 00:00:00 2001 From: Qudix <17361645+Qudix@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:29:14 -0600 Subject: [PATCH 07/24] feat: improve settings --- include/REX/REX/INI.h | 38 +- include/REX/REX/JSON.h | 38 +- include/REX/REX/Setting.h | 5 +- include/REX/REX/TOML.h | 38 +- include/SKSE/Impl/PCH.h | 3 +- src/REX/REX.cpp | 1024 +++++++++---------------------------- xmake.lua | 4 +- 7 files changed, 281 insertions(+), 869 deletions(-) diff --git a/include/REX/REX/INI.h b/include/REX/REX/INI.h index 7ca4f4586..2c378b42b 100644 --- a/include/REX/REX/INI.h +++ b/include/REX/REX/INI.h @@ -5,29 +5,21 @@ #ifdef REX_OPTION_INI namespace REX::INI { - namespace detail + namespace Impl { - void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); - void StoreSaveImpl(std::string_view& a_fileBase, std::vector& a_settings); template - void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, bool a_useDefault, std::string_view& a_section, std::string_view& a_key); + void SettingLoad(void* a_file, std::string_view a_section, std::string_view a_key, T& a_value, T& a_valueDefault); + template - void SettingSaveImpl(void* a_file, T& a_value, std::string_view& a_section, std::string_view& a_key); + void SettingSave(void* a_file, std::string_view a_section, std::string_view a_key, T& a_value); } class SettingStore : public TSettingStore { public: - virtual void Load() override - { - detail::StoreLoadImpl(m_fileBase, m_fileUser, m_settings); - } - - virtual void Save() override - { - detail::StoreSaveImpl(m_fileBase, m_settings); - } + virtual void Load() override; + virtual void Save() override; }; template @@ -42,19 +34,19 @@ namespace REX::INI {} public: - virtual void Load(void* a_file) override - { - Load(a_file, true); - } - - virtual void Load(void* a_file, bool a_useDefault) override + virtual void Load(void* a_data, bool a_isBase) override { - detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, a_useDefault, m_section, m_key); + if (a_isBase) { + Impl::SettingLoad(a_data, m_section, m_key, this->m_valueDefault, this->m_valueDefault); + this->SetValue(this->m_valueDefault); + } else { + Impl::SettingLoad(a_data, m_section, m_key, this->m_value, this->m_valueDefault); + } } - virtual void Save(void* a_file) override + virtual void Save(void* a_data) override { - detail::SettingSaveImpl(a_file, this->m_value, m_section, m_key); + Impl::SettingSave(a_data, m_section, m_key, this->m_value); } private: diff --git a/include/REX/REX/JSON.h b/include/REX/REX/JSON.h index aa0b2804d..5b64338f6 100644 --- a/include/REX/REX/JSON.h +++ b/include/REX/REX/JSON.h @@ -5,29 +5,21 @@ #ifdef REX_OPTION_JSON namespace REX::JSON { - namespace detail + namespace Impl { - void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); - void StoreSaveImpl(std::string_view& a_fileBase, std::vector& a_settings); template - void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, bool a_useDefault, std::string_view& a_path); + void SettingLoad(void* a_file, std::string_view a_path, T& a_value, T& a_valueDefault); + template - void SettingSaveImpl(void* a_file, T& a_value, std::string_view& a_path); + void SettingSave(void* a_file, std::string_view a_path, T& a_value); } class SettingStore : public TSettingStore { public: - virtual void Load() override - { - detail::StoreLoadImpl(m_fileBase, m_fileUser, m_settings); - } - - virtual void Save() override - { - detail::StoreSaveImpl(m_fileBase, m_settings); - } + virtual void Load() override; + virtual void Save() override; }; template @@ -41,19 +33,19 @@ namespace REX::JSON {} public: - virtual void Load(void* a_file) override - { - Load(a_file, true); - } - - virtual void Load(void* a_file, bool a_useDefault) override + virtual void Load(void* a_data, bool a_isBase) override { - detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, a_useDefault, m_path); + if (a_isBase) { + Impl::SettingLoad(a_data, m_path, this->m_valueDefault, this->m_valueDefault); + this->SetValue(this->m_valueDefault); + } else { + Impl::SettingLoad(a_data, m_path, this->m_value, this->m_valueDefault); + } } - virtual void Save(void* a_file) override + virtual void Save(void* a_data) override { - detail::SettingSaveImpl(a_file, this->m_value, m_path); + Impl::SettingSave(a_data, m_path, this->m_value); } private: diff --git a/include/REX/REX/Setting.h b/include/REX/REX/Setting.h index 32618262a..5d26eb572 100644 --- a/include/REX/REX/Setting.h +++ b/include/REX/REX/Setting.h @@ -7,9 +7,8 @@ namespace REX class ISetting { public: - virtual void Load(void* a_file) = 0; - virtual void Load(void* a_file, bool a_useDefault) = 0; - virtual void Save(void* a_file) = 0; + virtual void Load(void* a_data, bool a_isBase) = 0; + virtual void Save(void* a_data) = 0; }; class ISettingStore diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index e56f94766..4f08647c9 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -5,29 +5,21 @@ #ifdef REX_OPTION_TOML namespace REX::TOML { - namespace detail + namespace Impl { - void StoreLoadImpl(std::string_view& a_fileBase, std::string_view& a_fileUser, std::vector& a_settings); - void StoreSaveImpl(std::string_view& a_fileBase, std::vector& a_settings); template - void SettingLoadImpl(void* a_file, T& a_value, T& a_valueDefault, bool a_useDefault, std::string_view& a_path); + void SettingLoad(void* a_file, std::string_view a_path, T& a_value, T& a_valueDefault); + template - void SettingSaveImpl(void* a_file, T& a_value, std::string_view& a_path); + void SettingSave(void* a_file, std::string_view a_path, T& a_value); } class SettingStore : public TSettingStore { public: - virtual void Load() override - { - detail::StoreLoadImpl(m_fileBase, m_fileUser, m_settings); - } - - virtual void Save() override - { - detail::StoreSaveImpl(m_fileBase, m_settings); - } + virtual void Load() override; + virtual void Save() override; }; template @@ -41,19 +33,19 @@ namespace REX::TOML {} public: - virtual void Load(void* a_file) override - { - Load(a_file, true); - } - - virtual void Load(void* a_file, bool a_useDefault) override + virtual void Load(void* a_data, bool a_isBase) override { - detail::SettingLoadImpl(a_file, this->m_value, this->m_valueDefault, a_useDefault, m_path); + if (a_isBase) { + Impl::SettingLoad(a_data, m_path, this->m_valueDefault, this->m_valueDefault); + this->SetValue(this->m_valueDefault); + } else { + Impl::SettingLoad(a_data, m_path, this->m_value, this->m_valueDefault); + } } - virtual void Save(void* a_file) override + virtual void Save(void* a_data) override { - detail::SettingSaveImpl(a_file, this->m_value, m_path); + Impl::SettingSave(a_data, m_path, this->m_value); } private: diff --git a/include/SKSE/Impl/PCH.h b/include/SKSE/Impl/PCH.h index a29bbdd88..042487021 100644 --- a/include/SKSE/Impl/PCH.h +++ b/include/SKSE/Impl/PCH.h @@ -58,7 +58,8 @@ static_assert( std::is_integral_v && sizeof(std::time_t) == sizeof(std::size_t), "wrap std::time_t instead"); -#include "REX/REX.h" +#include "REX/REX/Enum.h" +#include "REX/REX/EnumSet.h" #include "REX/W32/KERNEL32.h" #include "REX/W32/USER32.h" diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 79ddb137a..51fdf087b 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -1,844 +1,280 @@ -#include "REX/REX.h" +#include "REX/REX/INI.h" +#include "REX/REX/JSON.h" +#include "REX/REX/TOML.h" #include "SKSE/Logger.h" #ifdef REX_OPTION_INI -# include - -void REX::INI::detail::StoreLoadImpl( - std::string_view& a_fileBase, - std::string_view& a_fileUser, - std::vector& a_settings) -{ - CSimpleIniA ini; - ini.SetUnicode(true); - ini.SetQuotes(true); +#include + +namespace REX::INI +{ + namespace Impl + { + template + void SettingLoad( + void* a_data, + std::string_view a_section, + std::string_view a_key, + T& a_value, + T& a_valueDefault) + { + const auto file = static_cast(a_data); + if (file->contains(a_section.data())) { + auto& section = (*file)[a_section.data()]; + if (section.contains(a_key.data())) { + if constexpr (std::is_same_v) + a_value = section[a_key.data()].as(); + else + a_value = section[a_key.data()].as(); + + return; + } + } - if (ini.LoadFile(a_fileBase.data()) == SI_OK) { - for (auto& setting : a_settings) { - setting->Load(&ini); + a_value = a_valueDefault; } - } - if (ini.LoadFile(a_fileUser.data()) == SI_OK) { - for (auto& setting : a_settings) { - setting->Load(&ini, false); + template void SettingLoad(void*, std::string_view, std::string_view, bool&, bool&); + template void SettingLoad(void*, std::string_view, std::string_view, float&, float&); + template void SettingLoad(void*, std::string_view, std::string_view, double&, double&); + template void SettingLoad(void*, std::string_view, std::string_view, std::uint8_t&, std::uint8_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::uint16_t&, std::uint16_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::uint32_t&, std::uint32_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::int8_t&, std::int8_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::int16_t&, std::int16_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::int32_t&, std::int32_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::string&, std::string&); + + template + void SettingSave( + void* a_data, + std::string_view a_section, + std::string_view a_key, + T& a_value) + { + auto& file = *static_cast(a_data); + if constexpr (std::is_same_v) + file[a_section.data()][a_key.data()] = (char)a_value; + else + file[a_section.data()][a_key.data()] = a_value; } - } -} - -void REX::INI::detail::StoreSaveImpl( - std::string_view& a_fileBase, - std::vector& a_settings) -{ - CSimpleIniA ini; - ini.SetUnicode(true); - ini.SetQuotes(true); - ini.LoadFile(a_fileBase.data()); - for (auto& setting : a_settings) { - setting->Save(&ini); + template void SettingSave(void*, std::string_view, std::string_view, bool&); + template void SettingSave(void*, std::string_view, std::string_view, float&); + template void SettingSave(void*, std::string_view, std::string_view, double&); + template void SettingSave(void*, std::string_view, std::string_view, std::uint8_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::uint16_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::uint32_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::int8_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::int16_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::int32_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::string&); } - ini.SaveFile(a_fileBase.data(), false); -} - -template <> -void REX::INI::detail::SettingLoadImpl( - void* a_file, - bool& a_value, - bool& a_valueDefault, - bool a_useDefault, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - a_value = file->GetBoolValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::INI::detail::SettingSaveImpl( - void* a_file, - bool& a_value, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - file->SetBoolValue(a_section.data(), a_key.data(), a_value); -} - -template <> -void REX::INI::detail::SettingLoadImpl( - void* a_file, - float& a_value, - float& a_valueDefault, - bool a_useDefault, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - a_value = static_cast(file->GetDoubleValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); -} - -template <> -void REX::INI::detail::SettingSaveImpl( - void* a_file, - float& a_value, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - file->SetDoubleValue(a_section.data(), a_key.data(), a_value); -} - -template <> -void REX::INI::detail::SettingLoadImpl( - void* a_file, - double& a_value, - double& a_valueDefault, - bool a_useDefault, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - a_value = file->GetDoubleValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::INI::detail::SettingSaveImpl( - void* a_file, - double& a_value, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - file->SetDoubleValue(a_section.data(), a_key.data(), a_value); -} - -template <> -void REX::INI::detail::SettingLoadImpl( - void* a_file, - std::int8_t& a_value, - std::int8_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); -} - -template <> -void REX::INI::detail::SettingSaveImpl( - void* a_file, - std::int8_t& a_value, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - file->SetLongValue(a_section.data(), a_key.data(), a_value); -} - -template <> -void REX::INI::detail::SettingLoadImpl( - void* a_file, - std::int16_t& a_value, - std::int16_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); -} - -template <> -void REX::INI::detail::SettingSaveImpl( - void* a_file, - std::int16_t& a_value, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - file->SetLongValue(a_section.data(), a_key.data(), a_value); -} - -template <> -void REX::INI::detail::SettingLoadImpl( - void* a_file, - std::int32_t& a_value, - std::int32_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); -} - -template <> -void REX::INI::detail::SettingSaveImpl( - void* a_file, - std::int32_t& a_value, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - file->SetLongValue(a_section.data(), a_key.data(), a_value); -} - -template <> -void REX::INI::detail::SettingLoadImpl( - void* a_file, - std::uint8_t& a_value, - std::uint8_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); -} - -template <> -void REX::INI::detail::SettingSaveImpl( - void* a_file, - std::uint8_t& a_value, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - file->SetLongValue(a_section.data(), a_key.data(), a_value); -} - -template <> -void REX::INI::detail::SettingLoadImpl( - void* a_file, - std::uint16_t& a_value, - std::uint16_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); -} + void SettingStore::Load() + { + ini::IniFileCaseInsensitive file; -template <> -void REX::INI::detail::SettingSaveImpl( - void* a_file, - std::uint16_t& a_value, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - file->SetLongValue(a_section.data(), a_key.data(), a_value); -} - -template <> -void REX::INI::detail::SettingLoadImpl( - void* a_file, - std::uint32_t& a_value, - std::uint32_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault : a_value)); -} - -template <> -void REX::INI::detail::SettingSaveImpl( - void* a_file, - std::uint32_t& a_value, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - file->SetLongValue(a_section.data(), a_key.data(), a_value); -} - -template <> -void REX::INI::detail::SettingLoadImpl( - void* a_file, - std::string& a_value, - std::string& a_valueDefault, - bool a_useDefault, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - a_value = file->GetValue(a_section.data(), a_key.data(), a_useDefault ? a_valueDefault.c_str() : a_value.c_str()); -} - -template <> -void REX::INI::detail::SettingSaveImpl( - void* a_file, - std::string& a_value, - std::string_view& a_section, - std::string_view& a_key) -{ - auto file = static_cast(a_file); - file->SetValue(a_section.data(), a_key.data(), a_value.c_str()); -} -#endif - -#ifdef REX_OPTION_JSON -# include - -void REX::JSON::detail::StoreLoadImpl( - std::string_view& a_fileBase, - std::string_view& a_fileUser, - std::vector& a_settings) -{ - if (std::filesystem::exists(a_fileBase)) { - std::ifstream file{ a_fileBase.data() }; - try { - auto result = nlohmann::json::parse(file); - for (auto setting : a_settings) { - setting->Load(&result); + if (std::filesystem::exists(m_fileBase)) { + file.load(m_fileBase.data()); + for (auto& setting : m_settings) { + setting->Load(&file, true); } - } catch (const std::exception& e) { - SKSE::log::error("{}", e.what()); } - } - if (std::filesystem::exists(a_fileUser)) { - std::ifstream file{ a_fileUser.data() }; - try { - auto result = nlohmann::json::parse(file); - for (auto setting : a_settings) { - setting->Load(&result, false); + if (std::filesystem::exists(m_fileUser)) { + file.load(m_fileUser.data()); + for (auto& setting : m_settings) { + setting->Load(&file, false); } - } catch (const std::exception& e) { - SKSE::log::error("{}", e.what()); } } -} - -void REX::JSON::detail::StoreSaveImpl( - std::string_view& a_fileBase, - std::vector& a_settings) -{ - nlohmann::json output{}; - if (std::filesystem::exists(a_fileBase)) { - std::ifstream file{ a_fileBase.data() }; - output = nlohmann::json::parse(file); - } - - for (auto& setting : a_settings) { - setting->Save(&output); - } - - std::ofstream file{ a_fileBase.data(), std::ios::trunc }; - file << output.dump(4); -} - -template <> -void REX::JSON::detail::SettingLoadImpl( - void* a_file, - bool& a_value, - bool& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::JSON::detail::SettingSaveImpl( - void* a_file, - bool& a_value, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - (*file)[a_path] = a_value; -} - -template <> -void REX::JSON::detail::SettingLoadImpl( - void* a_file, - float& a_value, - float& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::JSON::detail::SettingSaveImpl( - void* a_file, - float& a_value, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - (*file)[a_path] = a_value; -} - -template <> -void REX::JSON::detail::SettingLoadImpl( - void* a_file, - double& a_value, - double& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::JSON::detail::SettingSaveImpl( - void* a_file, - double& a_value, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - (*file)[a_path] = a_value; -} - -template <> -void REX::JSON::detail::SettingLoadImpl( - void* a_file, - std::int8_t& a_value, - std::int8_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::JSON::detail::SettingSaveImpl( - void* a_file, - std::int8_t& a_value, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - (*file)[a_path] = a_value; -} -template <> -void REX::JSON::detail::SettingLoadImpl( - void* a_file, - std::int16_t& a_value, - std::int16_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::JSON::detail::SettingSaveImpl( - void* a_file, - std::int16_t& a_value, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - (*file)[a_path] = a_value; -} - -template <> -void REX::JSON::detail::SettingLoadImpl( - void* a_file, - std::int32_t& a_value, - std::int32_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::JSON::detail::SettingSaveImpl( - void* a_file, - std::int32_t& a_value, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - (*file)[a_path] = a_value; -} - -template <> -void REX::JSON::detail::SettingLoadImpl( - void* a_file, - std::uint8_t& a_value, - std::uint8_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::JSON::detail::SettingSaveImpl( - void* a_file, - std::uint8_t& a_value, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - (*file)[a_path] = a_value; -} - -template <> -void REX::JSON::detail::SettingLoadImpl( - void* a_file, - std::uint16_t& a_value, - std::uint16_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::JSON::detail::SettingSaveImpl( - void* a_file, - std::uint16_t& a_value, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - (*file)[a_path] = a_value; -} - -template <> -void REX::JSON::detail::SettingLoadImpl( - void* a_file, - std::uint32_t& a_value, - std::uint32_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); -} - -template <> -void REX::JSON::detail::SettingSaveImpl( - void* a_file, - std::uint32_t& a_value, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - (*file)[a_path] = a_value; -} + void SettingStore::Save() + { + ini::IniFileCaseInsensitive file; -template <> -void REX::JSON::detail::SettingLoadImpl( - void* a_file, - std::string& a_value, - std::string& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - a_value = file->value(a_path, a_useDefault ? a_valueDefault : a_value); -} + file.load(m_fileBase.data()); + for (auto& setting : m_settings) { + setting->Save(&file); + } -template <> -void REX::JSON::detail::SettingSaveImpl( - void* a_file, - std::string& a_value, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - (*file)[a_path] = a_value; + file.save(m_fileBase.data()); + } } #endif -#ifdef REX_OPTION_TOML -# include +#ifdef REX_OPTION_JSON +# include -void REX::TOML::detail::StoreLoadImpl( - std::string_view& a_fileBase, - std::string_view& a_fileUser, - std::vector& a_settings) -{ - try { - auto result = toml::parse_file(a_fileBase); - for (auto& setting : a_settings) { - setting->Load(&result); +namespace REX::JSON +{ + namespace Impl + { + template + void SettingLoad( + void* a_data, + std::string_view a_path, + T& a_value, + T& a_valueDefault) + { + const auto& json = *static_cast(a_data); + if (a_path[0] == '/') + a_value = json.value(nlohmann::json::json_pointer(a_path.data()), a_valueDefault); + else + a_value = json.value(a_path, a_valueDefault); } - } catch (const std::exception& e) { - SKSE::log::error("{}", e.what()); - } - try { - auto result = toml::parse_file(a_fileUser); - for (auto& setting : a_settings) { - setting->Load(&result, false); + template void SettingLoad(void*, std::string_view, bool&, bool&); + template void SettingLoad(void*, std::string_view, float&, float&); + template void SettingLoad(void*, std::string_view, double&, double&); + template void SettingLoad(void*, std::string_view, std::uint8_t&, std::uint8_t&); + template void SettingLoad(void*, std::string_view, std::uint16_t&, std::uint16_t&); + template void SettingLoad(void*, std::string_view, std::uint32_t&, std::uint32_t&); + template void SettingLoad(void*, std::string_view, std::int8_t&, std::int8_t&); + template void SettingLoad(void*, std::string_view, std::int16_t&, std::int16_t&); + template void SettingLoad(void*, std::string_view, std::int32_t&, std::int32_t&); + template void SettingLoad(void*, std::string_view, std::string&, std::string&); + + template + void SettingSave( + void* a_data, + std::string_view a_path, + T& a_value) + { + auto& json = *static_cast(a_data); + if (a_path[0] == '/') + json[nlohmann::json::json_pointer(a_path.data())] = a_value; + else + json[a_path] = a_value; } - } catch (const std::exception& e) { - SKSE::log::error("{}", e.what()); - } -} - -void REX::TOML::detail::StoreSaveImpl( - [[maybe_unused]] std::string_view& a_fileBase, - [[maybe_unused]] std::vector& a_settings) -{ - // toml::parse_result output{}; - // try { - // output = toml::parse_file(a_fileBase); - // } catch (const std::exception& e) { - // // ignore - // } - // - // for (auto& setting : a_settings) { - // setting->Save(&output); - // } - // - // std::ofstream file{ a_fileBase.data(), std::ios::trunc }; - // file << output; -} -template <> -void REX::TOML::detail::SettingLoadImpl( - void* a_file, - bool& a_value, - bool& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); + template void SettingSave(void*, std::string_view, bool&); + template void SettingSave(void*, std::string_view, float&); + template void SettingSave(void*, std::string_view, double&); + template void SettingSave(void*, std::string_view, std::uint8_t&); + template void SettingSave(void*, std::string_view, std::uint16_t&); + template void SettingSave(void*, std::string_view, std::uint32_t&); + template void SettingSave(void*, std::string_view, std::int8_t&); + template void SettingSave(void*, std::string_view, std::int16_t&); + template void SettingSave(void*, std::string_view, std::int32_t&); + template void SettingSave(void*, std::string_view, std::string&); } -} - -template <> -void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] bool& a_value, - [[maybe_unused]] std::string_view& a_path) -{ - // auto file = static_cast(a_file); - // file->insert_or_assign(a_path, a_value); -} - -template <> -void REX::TOML::detail::SettingLoadImpl( - void* a_file, - float& a_value, - float& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); - } -} -template <> -void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] float& a_value, - [[maybe_unused]] std::string_view& a_path) -{ - // auto file = static_cast(a_file); - // file->insert_or_assign(a_path, a_value); -} + void SettingStore::Load() + { + if (std::filesystem::exists(m_fileBase)) { + std::ifstream file{ m_fileBase.data() }; + try { + auto result = nlohmann::json::parse(file); + for (auto setting : m_settings) { + setting->Load(&result, true); + } + } catch (const std::exception& e) { + SKSE::log::error("{}", e.what()); + } + } -template <> -void REX::TOML::detail::SettingLoadImpl( - void* a_file, - double& a_value, - double& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); + if (std::filesystem::exists(m_fileUser)) { + std::ifstream file{ m_fileUser.data() }; + try { + auto result = nlohmann::json::parse(file); + for (auto setting : m_settings) { + setting->Load(&result, false); + } + } catch (const std::exception& e) { + SKSE::log::error("{}", e.what()); + } + } } -} - -template <> -void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] double& a_value, - [[maybe_unused]] std::string_view& a_path) -{ - // auto file = static_cast(a_file); - // file->insert_or_assign(a_path, a_value); -} -template <> -void REX::TOML::detail::SettingLoadImpl( - void* a_file, - std::int8_t& a_value, - std::int8_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); - } -} - -template <> -void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int8_t& a_value, - [[maybe_unused]] std::string_view& a_path) -{ - // auto file = static_cast(a_file); - // file->insert_or_assign(a_path, a_value); -} - -template <> -void REX::TOML::detail::SettingLoadImpl( - void* a_file, - std::int16_t& a_value, - std::int16_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); - } -} + void SettingStore::Save() + { + nlohmann::json output{}; + if (std::filesystem::exists(m_fileBase)) { + std::ifstream file{ m_fileBase.data() }; + output = nlohmann::json::parse(file); + } -template <> -void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int16_t& a_value, - [[maybe_unused]] std::string_view& a_path) -{ - // auto file = static_cast(a_file); - // file->insert_or_assign(a_path, a_value); -} + for (auto& setting : m_settings) { + setting->Save(&output); + } -template <> -void REX::TOML::detail::SettingLoadImpl( - void* a_file, - std::int32_t& a_value, - std::int32_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); + std::ofstream file{ m_fileBase.data(), std::ios::trunc }; + file << output.dump(4); } } +#endif -template <> -void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::int32_t& a_value, - [[maybe_unused]] std::string_view& a_path) -{ - // auto file = static_cast(a_file); - // file->insert_or_assign(a_path, a_value); -} +#ifdef REX_OPTION_TOML +# define TOML_EXCEPTIONS 0 +# include -template <> -void REX::TOML::detail::SettingLoadImpl( - void* a_file, - std::uint8_t& a_value, - std::uint8_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); - } -} +namespace REX::TOML +{ + namespace Impl + { + template + void SettingLoad( + void* a_data, + std::string_view a_path, + T& a_value, + T& a_valueDefault) + { + const auto& table = *static_cast(a_data); + if (const auto node = table[toml::path(a_path)]) + a_value = node.value_or(a_valueDefault); + } -template <> -void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint8_t& a_value, - [[maybe_unused]] std::string_view& a_path) -{ - // auto file = static_cast(a_file); - // file->insert_or_assign(a_path, a_value); -} + template void SettingLoad(void*, std::string_view, bool&, bool&); + template void SettingLoad(void*, std::string_view, float&, float&); + template void SettingLoad(void*, std::string_view, double&, double&); + template void SettingLoad(void*, std::string_view, std::uint8_t&, std::uint8_t&); + template void SettingLoad(void*, std::string_view, std::uint16_t&, std::uint16_t&); + template void SettingLoad(void*, std::string_view, std::uint32_t&, std::uint32_t&); + template void SettingLoad(void*, std::string_view, std::int8_t&, std::int8_t&); + template void SettingLoad(void*, std::string_view, std::int16_t&, std::int16_t&); + template void SettingLoad(void*, std::string_view, std::int32_t&, std::int32_t&); + template void SettingLoad(void*, std::string_view, std::string&, std::string&); + + template + void SettingSave( + void* a_data, + std::string_view a_path, + T& a_value) + { + // TODO + } -template <> -void REX::TOML::detail::SettingLoadImpl( - void* a_file, - std::uint16_t& a_value, - std::uint16_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); + template void SettingSave(void*, std::string_view, bool&); + template void SettingSave(void*, std::string_view, float&); + template void SettingSave(void*, std::string_view, double&); + template void SettingSave(void*, std::string_view, std::uint8_t&); + template void SettingSave(void*, std::string_view, std::uint16_t&); + template void SettingSave(void*, std::string_view, std::uint32_t&); + template void SettingSave(void*, std::string_view, std::int8_t&); + template void SettingSave(void*, std::string_view, std::int16_t&); + template void SettingSave(void*, std::string_view, std::int32_t&); + template void SettingSave(void*, std::string_view, std::string&); } -} -template <> -void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint16_t& a_value, - [[maybe_unused]] std::string_view& a_path) -{ - // auto file = static_cast(a_file); - // file->insert_or_assign(a_path, a_value); -} + void SettingStore::Load() + { + if (auto result = toml::parse_file(m_fileBase)) { + for (auto& setting : m_settings) + setting->Load(&result.table(), true); + } -template <> -void REX::TOML::detail::SettingLoadImpl( - void* a_file, - std::uint32_t& a_value, - std::uint32_t& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); + if (auto result = toml::parse_file(m_fileUser)) { + for (auto& setting : m_settings) + setting->Load(&result.table(), false); + } } -} -template <> -void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::uint32_t& a_value, - [[maybe_unused]] std::string_view& a_path) -{ - // auto file = static_cast(a_file); - // file->insert_or_assign(a_path, a_value); -} - -template <> -void REX::TOML::detail::SettingLoadImpl( - void* a_file, - std::string& a_value, - std::string& a_valueDefault, - bool a_useDefault, - std::string_view& a_path) -{ - auto file = static_cast(a_file); - if (auto node = file->at_path(a_path)) { - a_value = node.value_or(a_useDefault ? a_valueDefault : a_value); + void SettingStore::Save() + { + // TODO } } - -template <> -void REX::TOML::detail::SettingSaveImpl( - [[maybe_unused]] void* a_file, - [[maybe_unused]] std::string& a_value, - [[maybe_unused]] std::string_view& a_path) -{ - // auto file = static_cast(a_file); - // file->insert_or_assign(a_path, a_value); -} #endif diff --git a/xmake.lua b/xmake.lua index ca4e1720e..403bf8d4e 100644 --- a/xmake.lua +++ b/xmake.lua @@ -54,7 +54,7 @@ if has_config("skse_xbyak") then end if has_config("rex_ini") then - add_requires("simpleini", { configs = { convert = "none" } }) + add_requires("inifile-cpp") end if has_config("rex_json") then @@ -81,7 +81,7 @@ target("commonlibsse", function() end if has_config("rex_ini") then - add_packages("simpleini", { public = true }) + add_packages("inifile-cpp", { public = true }) end if has_config("rex_json") then From b0860ba65010068f3fac6fb6a5638f443b0b6019 Mon Sep 17 00:00:00 2001 From: qudix Date: Wed, 13 Nov 2024 21:29:46 +0000 Subject: [PATCH 08/24] maintenance --- src/REX/REX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 51fdf087b..803296dec 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -5,7 +5,7 @@ #include "SKSE/Logger.h" #ifdef REX_OPTION_INI -#include +# include namespace REX::INI { From 402de9309a3013b7d0973a2a78f4e95f0b02bb28 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Wed, 13 Nov 2024 19:34:23 -0700 Subject: [PATCH 09/24] fix: revert ini library to simpleini inifile-cpp only accepts "true" and "false" for boolean values, so that's out --- src/REX/REX.cpp | 58 ++++++++++++++++++++++++++++--------------------- xmake.lua | 4 ++-- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 803296dec..a1c228071 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -5,12 +5,15 @@ #include "SKSE/Logger.h" #ifdef REX_OPTION_INI -# include +# include namespace REX::INI { namespace Impl { + template + constexpr bool is_long_integral_v = std::_Is_any_of_v, std::uint8_t, std::uint16_t, std::uint32_t, std::int8_t, std::int16_t, std::int32_t>; + template void SettingLoad( void* a_data, @@ -19,20 +22,16 @@ namespace REX::INI T& a_value, T& a_valueDefault) { - const auto file = static_cast(a_data); - if (file->contains(a_section.data())) { - auto& section = (*file)[a_section.data()]; - if (section.contains(a_key.data())) { - if constexpr (std::is_same_v) - a_value = section[a_key.data()].as(); - else - a_value = section[a_key.data()].as(); - - return; - } + const auto file = static_cast(a_data); + if constexpr (std::is_same_v) { + a_value = file->GetBoolValue(a_section.data(), a_key.data(), a_valueDefault); + } else if constexpr (std::is_floating_point_v) { + a_value = static_cast(file->GetDoubleValue(a_section.data(), a_key.data(), a_valueDefault)); + } else if constexpr (is_long_integral_v) { + a_value = static_cast(file->GetLongValue(a_section.data(), a_key.data(), a_valueDefault)); + } else if constexpr (std::is_same_v) { + a_value = file->GetValue(a_section.data(), a_key.data(), a_valueDefault.c_str()); } - - a_value = a_valueDefault; } template void SettingLoad(void*, std::string_view, std::string_view, bool&, bool&); @@ -53,11 +52,16 @@ namespace REX::INI std::string_view a_key, T& a_value) { - auto& file = *static_cast(a_data); - if constexpr (std::is_same_v) - file[a_section.data()][a_key.data()] = (char)a_value; - else - file[a_section.data()][a_key.data()] = a_value; + auto& file = *static_cast(a_data); + if constexpr (std::is_same_v) { + file.SetBoolValue(a_section.data(), a_key.data(), a_value); + } else if constexpr (std::is_floating_point_v) { + file.SetDoubleValue(a_section.data(), a_key.data(), a_value); + } else if constexpr (is_long_integral_v) { + file.SetLongValue(a_section.data(), a_key.data(), a_value); + } else if constexpr (std::is_same_v) { + file.SetValue(a_section.data(), a_key.data(), a_value.c_str()); + } } template void SettingSave(void*, std::string_view, std::string_view, bool&); @@ -74,17 +78,19 @@ namespace REX::INI void SettingStore::Load() { - ini::IniFileCaseInsensitive file; + CSimpleIniA file; + file.SetUnicode(true); + file.SetQuotes(true); if (std::filesystem::exists(m_fileBase)) { - file.load(m_fileBase.data()); + file.LoadFile(m_fileBase.data()); for (auto& setting : m_settings) { setting->Load(&file, true); } } if (std::filesystem::exists(m_fileUser)) { - file.load(m_fileUser.data()); + file.LoadFile(m_fileUser.data()); for (auto& setting : m_settings) { setting->Load(&file, false); } @@ -93,14 +99,16 @@ namespace REX::INI void SettingStore::Save() { - ini::IniFileCaseInsensitive file; + CSimpleIniA file; + file.SetUnicode(true); + file.SetQuotes(true); - file.load(m_fileBase.data()); + file.LoadFile(m_fileBase.data()); for (auto& setting : m_settings) { setting->Save(&file); } - file.save(m_fileBase.data()); + file.SaveFile(m_fileBase.data()); } } #endif diff --git a/xmake.lua b/xmake.lua index 403bf8d4e..cefbe713b 100644 --- a/xmake.lua +++ b/xmake.lua @@ -54,7 +54,7 @@ if has_config("skse_xbyak") then end if has_config("rex_ini") then - add_requires("inifile-cpp") + add_requires("simpleini") end if has_config("rex_json") then @@ -81,7 +81,7 @@ target("commonlibsse", function() end if has_config("rex_ini") then - add_packages("inifile-cpp", { public = true }) + add_packages("simpleini", { public = true }) end if has_config("rex_json") then From 04d5a27b9cd8784b0563e193010068ec1ca353df Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Wed, 13 Nov 2024 21:35:52 -0700 Subject: [PATCH 10/24] feat: migrate to toml11, add toml saving --- include/REX/REX/TOML.h | 22 ++++++---- src/REX/REX.cpp | 95 ++++++++++++++++++++++++++---------------- xmake.lua | 4 +- 3 files changed, 77 insertions(+), 44 deletions(-) diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index 4f08647c9..650e00ccb 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -8,10 +8,10 @@ namespace REX::TOML namespace Impl { template - void SettingLoad(void* a_file, std::string_view a_path, T& a_value, T& a_valueDefault); + void SettingLoad(void* a_file, std::string_view a_section, std::string_view a_key, T& a_value, T& a_valueDefault); template - void SettingSave(void* a_file, std::string_view a_path, T& a_value); + void SettingSave(void* a_file, std::string_view a_section, std::string_view a_key, T& a_value); } class SettingStore : @@ -29,27 +29,35 @@ namespace REX::TOML public: Setting(std::string_view a_path, T a_default) : TSetting(a_default), - m_path(a_path) + m_section(), + m_key(a_path) + {} + + Setting(std::string_view a_section, std::string_view a_key, T a_default) : + TSetting(a_default), + m_section(a_section), + m_key(a_key) {} public: virtual void Load(void* a_data, bool a_isBase) override { if (a_isBase) { - Impl::SettingLoad(a_data, m_path, this->m_valueDefault, this->m_valueDefault); + Impl::SettingLoad(a_data, m_section, m_key, this->m_valueDefault, this->m_valueDefault); this->SetValue(this->m_valueDefault); } else { - Impl::SettingLoad(a_data, m_path, this->m_value, this->m_valueDefault); + Impl::SettingLoad(a_data, m_section, m_key, this->m_value, this->m_valueDefault); } } virtual void Save(void* a_data) override { - Impl::SettingSave(a_data, m_path, this->m_value); + Impl::SettingSave(a_data, m_section, m_key, this->m_value); } private: - std::string_view m_path; + std::string_view m_section; + std::string_view m_key; }; template diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index a1c228071..79a8ac6ec 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -216,8 +216,7 @@ namespace REX::JSON #endif #ifdef REX_OPTION_TOML -# define TOML_EXCEPTIONS 0 -# include +# include namespace REX::TOML { @@ -226,63 +225,89 @@ namespace REX::TOML template void SettingLoad( void* a_data, - std::string_view a_path, + std::string_view a_section, + std::string_view a_key, T& a_value, T& a_valueDefault) { - const auto& table = *static_cast(a_data); - if (const auto node = table[toml::path(a_path)]) - a_value = node.value_or(a_valueDefault); + const auto& data = static_cast(a_data); + if (a_section.empty()) { + a_value = toml::find_or((*data), a_key.data(), a_valueDefault); + return; + } else if (data->contains(a_section.data())) { + a_value = toml::find_or((*data)[a_section.data()], a_key.data(), a_valueDefault); + return; + } + + a_value = a_valueDefault; } - template void SettingLoad(void*, std::string_view, bool&, bool&); - template void SettingLoad(void*, std::string_view, float&, float&); - template void SettingLoad(void*, std::string_view, double&, double&); - template void SettingLoad(void*, std::string_view, std::uint8_t&, std::uint8_t&); - template void SettingLoad(void*, std::string_view, std::uint16_t&, std::uint16_t&); - template void SettingLoad(void*, std::string_view, std::uint32_t&, std::uint32_t&); - template void SettingLoad(void*, std::string_view, std::int8_t&, std::int8_t&); - template void SettingLoad(void*, std::string_view, std::int16_t&, std::int16_t&); - template void SettingLoad(void*, std::string_view, std::int32_t&, std::int32_t&); - template void SettingLoad(void*, std::string_view, std::string&, std::string&); + template void SettingLoad(void*, std::string_view, std::string_view, bool&, bool&); + template void SettingLoad(void*, std::string_view, std::string_view, float&, float&); + template void SettingLoad(void*, std::string_view, std::string_view, double&, double&); + template void SettingLoad(void*, std::string_view, std::string_view, std::uint8_t&, std::uint8_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::uint16_t&, std::uint16_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::uint32_t&, std::uint32_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::int8_t&, std::int8_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::int16_t&, std::int16_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::int32_t&, std::int32_t&); + template void SettingLoad(void*, std::string_view, std::string_view, std::string&, std::string&); template void SettingSave( void* a_data, - std::string_view a_path, + std::string_view a_section, + std::string_view a_key, T& a_value) { - // TODO + auto& data = *static_cast(a_data); + if (a_section.empty()) { + data[a_key.data()] = a_value; + } else { + data[a_section.data()][a_key.data()] = a_value; + } } - template void SettingSave(void*, std::string_view, bool&); - template void SettingSave(void*, std::string_view, float&); - template void SettingSave(void*, std::string_view, double&); - template void SettingSave(void*, std::string_view, std::uint8_t&); - template void SettingSave(void*, std::string_view, std::uint16_t&); - template void SettingSave(void*, std::string_view, std::uint32_t&); - template void SettingSave(void*, std::string_view, std::int8_t&); - template void SettingSave(void*, std::string_view, std::int16_t&); - template void SettingSave(void*, std::string_view, std::int32_t&); - template void SettingSave(void*, std::string_view, std::string&); + template void SettingSave(void*, std::string_view, std::string_view, bool&); + template void SettingSave(void*, std::string_view, std::string_view, float&); + template void SettingSave(void*, std::string_view, std::string_view, double&); + template void SettingSave(void*, std::string_view, std::string_view, std::uint8_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::uint16_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::uint32_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::int8_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::int16_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::int32_t&); + template void SettingSave(void*, std::string_view, std::string_view, std::string&); } void SettingStore::Load() { - if (auto result = toml::parse_file(m_fileBase)) { - for (auto& setting : m_settings) - setting->Load(&result.table(), true); + if (auto result = toml::try_parse(m_fileBase.data()); result.is_ok()) { + for (auto& setting : m_settings) { + setting->Load(&result.unwrap(), true); + } } - if (auto result = toml::parse_file(m_fileUser)) { - for (auto& setting : m_settings) - setting->Load(&result.table(), false); + if (auto result = toml::try_parse(m_fileUser.data()); result.is_ok()) { + for (auto& setting : m_settings) { + setting->Load(&result.unwrap(), false); + } } } void SettingStore::Save() { - // TODO + toml::value output{}; + if (auto result = toml::try_parse(m_fileBase.data()); result.is_ok()) { + output = result.unwrap(); + } + + for (auto setting : m_settings) { + setting->Save(&output); + } + + std::ofstream file{ m_fileBase.data(), std::ios::trunc }; + file << toml::format(output); } } #endif diff --git a/xmake.lua b/xmake.lua index cefbe713b..51377eac9 100644 --- a/xmake.lua +++ b/xmake.lua @@ -62,7 +62,7 @@ if has_config("rex_json") then end if has_config("rex_toml") then - add_requires("toml++") + add_requires("toml11") end -- define targets @@ -89,7 +89,7 @@ target("commonlibsse", function() end if has_config("rex_toml") then - add_packages("toml++", { public = true }) + add_packages("toml11", { public = true }) end -- add options From 46b48f9ca601dcfec2046ed89bb113963561340b Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Wed, 13 Nov 2024 22:46:17 -0700 Subject: [PATCH 11/24] feat: add std::format specializations --- include/REX/REX/INI.h | 33 +++++++++++++++++++++++++++++++++ include/REX/REX/JSON.h | 33 +++++++++++++++++++++++++++++++++ include/REX/REX/TOML.h | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 101 insertions(+), 2 deletions(-) diff --git a/include/REX/REX/INI.h b/include/REX/REX/INI.h index 2c378b42b..308a1b2a3 100644 --- a/include/REX/REX/INI.h +++ b/include/REX/REX/INI.h @@ -84,4 +84,37 @@ namespace REX::INI template using Str = Setting; } + +namespace REX::INI::Impl +{ +# ifdef __cpp_lib_format + template + struct formatter : std::formatter + { + template + auto format(REX::INI::Setting a_setting, FormatContext& a_ctx) const + { + return std::formatter::format(a_setting.GetValue(), a_ctx); + } + }; +# endif +} + +# ifdef __cpp_lib_format +namespace std +{ + // clang-format off + template struct formatter, CharT> : REX::INI::Impl::formatter {}; + template struct formatter, CharT> : REX::INI::Impl::formatter {}; + template struct formatter, CharT> : REX::INI::Impl::formatter {}; + template struct formatter, CharT> : REX::INI::Impl::formatter {}; + template struct formatter, CharT> : REX::INI::Impl::formatter {}; + template struct formatter, CharT> : REX::INI::Impl::formatter {}; + template struct formatter, CharT> : REX::INI::Impl::formatter {}; + template struct formatter, CharT> : REX::INI::Impl::formatter {}; + template struct formatter, CharT> : REX::INI::Impl::formatter {}; + template struct formatter, CharT> : REX::INI::Impl::formatter {}; + // clang-format on +} +# endif #endif diff --git a/include/REX/REX/JSON.h b/include/REX/REX/JSON.h index 5b64338f6..f0148f62b 100644 --- a/include/REX/REX/JSON.h +++ b/include/REX/REX/JSON.h @@ -82,4 +82,37 @@ namespace REX::JSON template using Str = Setting; } + +namespace REX::JSON::Impl +{ +# ifdef __cpp_lib_format + template + struct formatter : std::formatter + { + template + auto format(REX::JSON::Setting a_setting, FormatContext& a_ctx) const + { + return std::formatter::format(a_setting.GetValue(), a_ctx); + } + }; +# endif +} + +# ifdef __cpp_lib_format +namespace std +{ + // clang-format off + template struct formatter, CharT> : REX::JSON::Impl::formatter {}; + template struct formatter, CharT> : REX::JSON::Impl::formatter {}; + template struct formatter, CharT> : REX::JSON::Impl::formatter {}; + template struct formatter, CharT> : REX::JSON::Impl::formatter {}; + template struct formatter, CharT> : REX::JSON::Impl::formatter {}; + template struct formatter, CharT> : REX::JSON::Impl::formatter {}; + template struct formatter, CharT> : REX::JSON::Impl::formatter {}; + template struct formatter, CharT> : REX::JSON::Impl::formatter {}; + template struct formatter, CharT> : REX::JSON::Impl::formatter {}; + template struct formatter, CharT> : REX::JSON::Impl::formatter {}; + // clang-format on +} +# endif #endif diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index 650e00ccb..5550f7528 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -27,10 +27,10 @@ namespace REX::TOML public TSetting { public: - Setting(std::string_view a_path, T a_default) : + Setting(std::string_view a_key, T a_default) : TSetting(a_default), m_section(), - m_key(a_path) + m_key(a_key) {} Setting(std::string_view a_section, std::string_view a_key, T a_default) : @@ -90,4 +90,37 @@ namespace REX::TOML template using Str = Setting; } + +namespace REX::TOML::Impl +{ +# ifdef __cpp_lib_format + template + struct formatter : std::formatter + { + template + auto format(REX::TOML::Setting a_setting, FormatContext& a_ctx) const + { + return std::formatter::format(a_setting.GetValue(), a_ctx); + } + }; +# endif +} + +# ifdef __cpp_lib_format +namespace std +{ + // clang-format off + template struct formatter, CharT> : REX::TOML::Impl::formatter {}; + template struct formatter, CharT> : REX::TOML::Impl::formatter {}; + template struct formatter, CharT> : REX::TOML::Impl::formatter {}; + template struct formatter, CharT> : REX::TOML::Impl::formatter {}; + template struct formatter, CharT> : REX::TOML::Impl::formatter {}; + template struct formatter, CharT> : REX::TOML::Impl::formatter {}; + template struct formatter, CharT> : REX::TOML::Impl::formatter {}; + template struct formatter, CharT> : REX::TOML::Impl::formatter {}; + template struct formatter, CharT> : REX::TOML::Impl::formatter {}; + template struct formatter, CharT> : REX::TOML::Impl::formatter {}; + // clang-format on +} +# endif #endif From abce9f6bbad0610d36d02a8366cebc7f26d9cb98 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 03:01:23 -0700 Subject: [PATCH 12/24] feat: better handling of toml paths --- include/REX/REX/TOML.h | 23 +++++--- src/REX/REX.cpp | 118 +++++++++++++++++++++++++++++------------ 2 files changed, 101 insertions(+), 40 deletions(-) diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index 5550f7528..a7e230c65 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -8,10 +8,10 @@ namespace REX::TOML namespace Impl { template - void SettingLoad(void* a_file, std::string_view a_section, std::string_view a_key, T& a_value, T& a_valueDefault); + void SettingLoad(void* a_file, std::list a_section, std::string_view a_key, T& a_value, T& a_valueDefault); template - void SettingSave(void* a_file, std::string_view a_section, std::string_view a_key, T& a_value); + void SettingSave(void* a_file, std::list a_section, std::string_view a_key, T& a_value); } class SettingStore : @@ -35,9 +35,20 @@ namespace REX::TOML Setting(std::string_view a_section, std::string_view a_key, T a_default) : TSetting(a_default), - m_section(a_section), + m_section(), m_key(a_key) - {} + { + if (!a_section.contains(".")) { + m_section.push_back(a_section); + } else { + std::size_t pos{ 0 }, idx{ 0 }; + while ((pos = a_section.find(".", idx)) != std::string_view::npos) { + m_section.push_back(a_section.substr(idx, pos)); + idx = pos + 1; + } + m_section.push_back(a_section.substr(idx)); + } + } public: virtual void Load(void* a_data, bool a_isBase) override @@ -56,8 +67,8 @@ namespace REX::TOML } private: - std::string_view m_section; - std::string_view m_key; + std::list m_section; + std::string_view m_key; }; template diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 79a8ac6ec..291ea1f72 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -222,62 +222,112 @@ namespace REX::TOML { namespace Impl { + static toml::value recurse_table(toml::value a_value, std::string_view a_section) + { + if (a_value.is_table()) { + for (auto& value : a_value.as_table()) { + if (value.first == a_section) { + return value.second; + } + } + } + return nullptr; + } + + static toml::value* expand_table(toml::value& a_value, toml::value* a_result, std::string_view a_section) + { + if (a_result && a_result->is_table()) { + for (auto& value : a_result->as_table()) { + if (value.first == a_section) { + return std::addressof(value.second); + } + } + (*a_result)[a_section.data()] = toml::table{}; + return std::addressof((*a_result)[a_section.data()]); + } else if (a_value.is_table()) { + for (auto& value : a_value.as_table()) { + if (value.first == a_section) { + return std::addressof(value.second); + } + } + a_value[a_section.data()] = toml::table{}; + return std::addressof(a_value[a_section.data()]); + } + return nullptr; + } + template void SettingLoad( - void* a_data, - std::string_view a_section, - std::string_view a_key, - T& a_value, - T& a_valueDefault) + void* a_data, + std::list a_section, + std::string_view a_key, + T& a_value, + T& a_valueDefault) { const auto& data = static_cast(a_data); if (a_section.empty()) { - a_value = toml::find_or((*data), a_key.data(), a_valueDefault); + auto& path = (*data); + a_value = toml::find_or(path, a_key.data(), a_valueDefault); return; - } else if (data->contains(a_section.data())) { - a_value = toml::find_or((*data)[a_section.data()], a_key.data(), a_valueDefault); + } else if (a_section.size() == 1) { + auto& path = (*data)[a_section.front().data()]; + a_value = toml::find_or(path, a_key.data(), a_valueDefault); + return; + } else { + toml::value path = (*data); + for (auto& section : a_section) { + path = recurse_table(path, section); + } + a_value = toml::find_or(path, a_key.data(), a_valueDefault); return; } - a_value = a_valueDefault; } - template void SettingLoad(void*, std::string_view, std::string_view, bool&, bool&); - template void SettingLoad(void*, std::string_view, std::string_view, float&, float&); - template void SettingLoad(void*, std::string_view, std::string_view, double&, double&); - template void SettingLoad(void*, std::string_view, std::string_view, std::uint8_t&, std::uint8_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::uint16_t&, std::uint16_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::uint32_t&, std::uint32_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::int8_t&, std::int8_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::int16_t&, std::int16_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::int32_t&, std::int32_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::string&, std::string&); + template void SettingLoad(void*, std::list, std::string_view, bool&, bool&); + template void SettingLoad(void*, std::list, std::string_view, float&, float&); + template void SettingLoad(void*, std::list, std::string_view, double&, double&); + template void SettingLoad(void*, std::list, std::string_view, std::uint8_t&, std::uint8_t&); + template void SettingLoad(void*, std::list, std::string_view, std::uint16_t&, std::uint16_t&); + template void SettingLoad(void*, std::list, std::string_view, std::uint32_t&, std::uint32_t&); + template void SettingLoad(void*, std::list, std::string_view, std::int8_t&, std::int8_t&); + template void SettingLoad(void*, std::list, std::string_view, std::int16_t&, std::int16_t&); + template void SettingLoad(void*, std::list, std::string_view, std::int32_t&, std::int32_t&); + template void SettingLoad(void*, std::list, std::string_view, std::string&, std::string&); template void SettingSave( - void* a_data, - std::string_view a_section, - std::string_view a_key, - T& a_value) + void* a_data, + std::list a_section, + std::string_view a_key, + T& a_value) { auto& data = *static_cast(a_data); if (a_section.empty()) { data[a_key.data()] = a_value; + } else if (a_section.size() == 1) { + data[a_section.front().data()][a_key.data()] = a_value; } else { - data[a_section.data()][a_key.data()] = a_value; + toml::value* path{ nullptr }; + for (auto& section : a_section) { + path = expand_table(data, path, section); + } + if (path) { + (*path)[a_key.data()] = a_value; + } } } - template void SettingSave(void*, std::string_view, std::string_view, bool&); - template void SettingSave(void*, std::string_view, std::string_view, float&); - template void SettingSave(void*, std::string_view, std::string_view, double&); - template void SettingSave(void*, std::string_view, std::string_view, std::uint8_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::uint16_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::uint32_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::int8_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::int16_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::int32_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::string&); + template void SettingSave(void*, std::list, std::string_view, bool&); + template void SettingSave(void*, std::list, std::string_view, float&); + template void SettingSave(void*, std::list, std::string_view, double&); + template void SettingSave(void*, std::list, std::string_view, std::uint8_t&); + template void SettingSave(void*, std::list, std::string_view, std::uint16_t&); + template void SettingSave(void*, std::list, std::string_view, std::uint32_t&); + template void SettingSave(void*, std::list, std::string_view, std::int8_t&); + template void SettingSave(void*, std::list, std::string_view, std::int16_t&); + template void SettingSave(void*, std::list, std::string_view, std::int32_t&); + template void SettingSave(void*, std::list, std::string_view, std::string&); } void SettingStore::Load() From c160aa5d315aaca5dedd58410cdf7af26cd5bfa8 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 08:38:05 -0700 Subject: [PATCH 13/24] fix: proper handling for long toml paths --- include/REX/REX/TOML.h | 8 +++++++- src/REX/REX.cpp | 41 ++++++++++++++++++----------------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index a7e230c65..7cc515e03 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -43,13 +43,19 @@ namespace REX::TOML } else { std::size_t pos{ 0 }, idx{ 0 }; while ((pos = a_section.find(".", idx)) != std::string_view::npos) { - m_section.push_back(a_section.substr(idx, pos)); + m_section.push_back(a_section.substr(idx, pos - idx)); idx = pos + 1; } m_section.push_back(a_section.substr(idx)); } } + Setting(std::initializer_list a_section, std::string_view a_key, T a_default) : + TSetting(a_default), + m_section(a_section), + m_key(a_key) + {} + public: virtual void Load(void* a_data, bool a_isBase) override { diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 291ea1f72..70e203b9d 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -222,19 +222,7 @@ namespace REX::TOML { namespace Impl { - static toml::value recurse_table(toml::value a_value, std::string_view a_section) - { - if (a_value.is_table()) { - for (auto& value : a_value.as_table()) { - if (value.first == a_section) { - return value.second; - } - } - } - return nullptr; - } - - static toml::value* expand_table(toml::value& a_value, toml::value* a_result, std::string_view a_section) + static toml::value* recurse_table(toml::value& a_value, toml::value* a_result, std::string_view a_section, bool a_create = false) { if (a_result && a_result->is_table()) { for (auto& value : a_result->as_table()) { @@ -242,18 +230,22 @@ namespace REX::TOML return std::addressof(value.second); } } - (*a_result)[a_section.data()] = toml::table{}; - return std::addressof((*a_result)[a_section.data()]); + if (a_create) { + (*a_result)[a_section.data()] = toml::table{}; + return std::addressof((*a_result)[a_section.data()]); + } } else if (a_value.is_table()) { for (auto& value : a_value.as_table()) { if (value.first == a_section) { return std::addressof(value.second); } } - a_value[a_section.data()] = toml::table{}; - return std::addressof(a_value[a_section.data()]); + if (a_create) { + a_value[a_section.data()] = toml::table{}; + return std::addressof(a_value[a_section.data()]); + } } - return nullptr; + return a_result; } template @@ -274,12 +266,15 @@ namespace REX::TOML a_value = toml::find_or(path, a_key.data(), a_valueDefault); return; } else { - toml::value path = (*data); + SKSE::log::debug("{}", a_section); + toml::value* path{ nullptr }; for (auto& section : a_section) { - path = recurse_table(path, section); + path = recurse_table(*data, path, section); + } + if (path) { + a_value = toml::find_or(*path, a_key.data(), a_valueDefault); + return; } - a_value = toml::find_or(path, a_key.data(), a_valueDefault); - return; } a_value = a_valueDefault; } @@ -310,7 +305,7 @@ namespace REX::TOML } else { toml::value* path{ nullptr }; for (auto& section : a_section) { - path = expand_table(data, path, section); + path = recurse_table(data, path, section, true); } if (path) { (*path)[a_key.data()] = a_value; From ee7778dff172368154835ce00b3b4596d356a11e Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 08:45:02 -0700 Subject: [PATCH 14/24] fix: remove temp debug output --- src/REX/REX.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 70e203b9d..3b8a3bb1c 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -266,7 +266,6 @@ namespace REX::TOML a_value = toml::find_or(path, a_key.data(), a_valueDefault); return; } else { - SKSE::log::debug("{}", a_section); toml::value* path{ nullptr }; for (auto& section : a_section) { path = recurse_table(*data, path, section); From 8b086e5e72d058ed079b6424c9fdbb8b384244b3 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 13:05:49 -0700 Subject: [PATCH 15/24] fix: toml save improvements empty tables are no longer serialized, fixed issues with naming due to string_view --- include/REX/REX/TOML.h | 28 +++++------ include/SKSE/Impl/PCH.h | 1 + src/REX/REX.cpp | 102 +++++++++++++++++++++++----------------- 3 files changed, 72 insertions(+), 59 deletions(-) diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index 7cc515e03..971127545 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -5,13 +5,16 @@ #ifdef REX_OPTION_TOML namespace REX::TOML { + using sec_t = std::vector; + using key_t = std::string; + namespace Impl { template - void SettingLoad(void* a_file, std::list a_section, std::string_view a_key, T& a_value, T& a_valueDefault); + void SettingLoad(void* a_file, sec_t a_section, key_t a_key, T& a_value, T& a_valueDefault); template - void SettingSave(void* a_file, std::list a_section, std::string_view a_key, T& a_value); + void SettingSave(void* a_file, sec_t a_section, key_t a_key, T& a_value); } class SettingStore : @@ -27,30 +30,23 @@ namespace REX::TOML public TSetting { public: - Setting(std::string_view a_key, T a_default) : + Setting(key_t a_key, T a_default) : TSetting(a_default), m_section(), m_key(a_key) {} - Setting(std::string_view a_section, std::string_view a_key, T a_default) : + Setting(std::string a_section, key_t a_key, T a_default) : TSetting(a_default), m_section(), m_key(a_key) { - if (!a_section.contains(".")) { - m_section.push_back(a_section); - } else { - std::size_t pos{ 0 }, idx{ 0 }; - while ((pos = a_section.find(".", idx)) != std::string_view::npos) { - m_section.push_back(a_section.substr(idx, pos - idx)); - idx = pos + 1; - } - m_section.push_back(a_section.substr(idx)); + for (const auto token : std::ranges::split_view { a_section, std::string_view{ "." } }) { + m_section.emplace_back(token.data(), token.size()); } } - Setting(std::initializer_list a_section, std::string_view a_key, T a_default) : + Setting(std::initializer_list a_section, key_t a_key, T a_default) : TSetting(a_default), m_section(a_section), m_key(a_key) @@ -73,8 +69,8 @@ namespace REX::TOML } private: - std::list m_section; - std::string_view m_key; + sec_t m_section; + key_t m_key; }; template diff --git a/include/SKSE/Impl/PCH.h b/include/SKSE/Impl/PCH.h index 042487021..af2a16c04 100644 --- a/include/SKSE/Impl/PCH.h +++ b/include/SKSE/Impl/PCH.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 3b8a3bb1c..deb0d65e3 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -222,7 +222,7 @@ namespace REX::TOML { namespace Impl { - static toml::value* recurse_table(toml::value& a_value, toml::value* a_result, std::string_view a_section, bool a_create = false) + static toml::value* recurse_table(toml::value* a_result, toml::value& a_value, std::string a_section, bool a_create) { if (a_result && a_result->is_table()) { for (auto& value : a_result->as_table()) { @@ -231,8 +231,8 @@ namespace REX::TOML } } if (a_create) { - (*a_result)[a_section.data()] = toml::table{}; - return std::addressof((*a_result)[a_section.data()]); + (*a_result)[a_section] = toml::table{}; + return std::addressof((*a_result)[a_section]); } } else if (a_value.is_table()) { for (auto& value : a_value.as_table()) { @@ -241,87 +241,102 @@ namespace REX::TOML } } if (a_create) { - a_value[a_section.data()] = toml::table{}; - return std::addressof(a_value[a_section.data()]); + a_value[a_section] = toml::table{}; + return std::addressof(a_value[a_section]); } } return a_result; } + static bool recurse_mark_implicit(toml::value& a_value) + { + bool result{ true }; + for (auto& kv : a_value.as_table()) { + if (kv.second.is_table()) { + if (!recurse_mark_implicit(kv.second)) + continue; + kv.second.as_table_fmt().fmt = toml::table_format::implicit; + } else { + return false; + } + } + return result; + } + template void SettingLoad( - void* a_data, - std::list a_section, - std::string_view a_key, - T& a_value, - T& a_valueDefault) + void* a_data, + sec_t a_section, + key_t a_key, + T& a_value, + T& a_valueDefault) { const auto& data = static_cast(a_data); if (a_section.empty()) { auto& path = (*data); - a_value = toml::find_or(path, a_key.data(), a_valueDefault); + a_value = toml::find_or(path, a_key, a_valueDefault); return; } else if (a_section.size() == 1) { - auto& path = (*data)[a_section.front().data()]; - a_value = toml::find_or(path, a_key.data(), a_valueDefault); + auto& path = (*data)[a_section.front()]; + a_value = toml::find_or(path, a_key, a_valueDefault); return; } else { toml::value* path{ nullptr }; for (auto& section : a_section) { - path = recurse_table(*data, path, section); + path = recurse_table(path, *data, section, false); } if (path) { - a_value = toml::find_or(*path, a_key.data(), a_valueDefault); + a_value = toml::find_or(*path, a_key, a_valueDefault); return; } } a_value = a_valueDefault; } - template void SettingLoad(void*, std::list, std::string_view, bool&, bool&); - template void SettingLoad(void*, std::list, std::string_view, float&, float&); - template void SettingLoad(void*, std::list, std::string_view, double&, double&); - template void SettingLoad(void*, std::list, std::string_view, std::uint8_t&, std::uint8_t&); - template void SettingLoad(void*, std::list, std::string_view, std::uint16_t&, std::uint16_t&); - template void SettingLoad(void*, std::list, std::string_view, std::uint32_t&, std::uint32_t&); - template void SettingLoad(void*, std::list, std::string_view, std::int8_t&, std::int8_t&); - template void SettingLoad(void*, std::list, std::string_view, std::int16_t&, std::int16_t&); - template void SettingLoad(void*, std::list, std::string_view, std::int32_t&, std::int32_t&); - template void SettingLoad(void*, std::list, std::string_view, std::string&, std::string&); + template void SettingLoad(void*, sec_t, key_t, bool&, bool&); + template void SettingLoad(void*, sec_t, key_t, float&, float&); + template void SettingLoad(void*, sec_t, key_t, double&, double&); + template void SettingLoad(void*, sec_t, key_t, std::uint8_t&, std::uint8_t&); + template void SettingLoad(void*, sec_t, key_t, std::uint16_t&, std::uint16_t&); + template void SettingLoad(void*, sec_t, key_t, std::uint32_t&, std::uint32_t&); + template void SettingLoad(void*, sec_t, key_t, std::int8_t&, std::int8_t&); + template void SettingLoad(void*, sec_t, key_t, std::int16_t&, std::int16_t&); + template void SettingLoad(void*, sec_t, key_t, std::int32_t&, std::int32_t&); + template void SettingLoad(void*, sec_t, key_t, std::string&, std::string&); template void SettingSave( - void* a_data, - std::list a_section, - std::string_view a_key, - T& a_value) + void* a_data, + sec_t a_section, + key_t a_key, + T& a_value) { auto& data = *static_cast(a_data); if (a_section.empty()) { - data[a_key.data()] = a_value; + data[a_key] = a_value; } else if (a_section.size() == 1) { - data[a_section.front().data()][a_key.data()] = a_value; + data[a_section.front()][a_key] = a_value; } else { toml::value* path{ nullptr }; for (auto& section : a_section) { - path = recurse_table(data, path, section, true); + path = recurse_table(path, data, section, true); } if (path) { - (*path)[a_key.data()] = a_value; + (*path)[a_key] = a_value; } } } - template void SettingSave(void*, std::list, std::string_view, bool&); - template void SettingSave(void*, std::list, std::string_view, float&); - template void SettingSave(void*, std::list, std::string_view, double&); - template void SettingSave(void*, std::list, std::string_view, std::uint8_t&); - template void SettingSave(void*, std::list, std::string_view, std::uint16_t&); - template void SettingSave(void*, std::list, std::string_view, std::uint32_t&); - template void SettingSave(void*, std::list, std::string_view, std::int8_t&); - template void SettingSave(void*, std::list, std::string_view, std::int16_t&); - template void SettingSave(void*, std::list, std::string_view, std::int32_t&); - template void SettingSave(void*, std::list, std::string_view, std::string&); + template void SettingSave(void*, sec_t, key_t, bool&); + template void SettingSave(void*, sec_t, key_t, float&); + template void SettingSave(void*, sec_t, key_t, double&); + template void SettingSave(void*, sec_t, key_t, std::uint8_t&); + template void SettingSave(void*, sec_t, key_t, std::uint16_t&); + template void SettingSave(void*, sec_t, key_t, std::uint32_t&); + template void SettingSave(void*, sec_t, key_t, std::int8_t&); + template void SettingSave(void*, sec_t, key_t, std::int16_t&); + template void SettingSave(void*, sec_t, key_t, std::int32_t&); + template void SettingSave(void*, sec_t, key_t, std::string&); } void SettingStore::Load() @@ -350,6 +365,7 @@ namespace REX::TOML setting->Save(&output); } + Impl::recurse_mark_implicit(output); std::ofstream file{ m_fileBase.data(), std::ios::trunc }; file << toml::format(output); } From e1833e09b6a61c4adb75677af687b1307281cf2e Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 20:06:09 +0000 Subject: [PATCH 16/24] maintenance --- include/REX/REX/TOML.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index 971127545..324e5dced 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -41,7 +41,7 @@ namespace REX::TOML m_section(), m_key(a_key) { - for (const auto token : std::ranges::split_view { a_section, std::string_view{ "." } }) { + for (const auto token : std::ranges::split_view{ a_section, std::string_view{ "." } }) { m_section.emplace_back(token.data(), token.size()); } } From bc02062274fef0bf3ca1ca6492c44dc2617a39c0 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 13:18:21 -0700 Subject: [PATCH 17/24] refactor: define config storage types --- include/REX/REX/INI.h | 13 +++-- include/REX/REX/JSON.h | 10 ++-- src/REX/REX.cpp | 122 +++++++++++++++++++++-------------------- 3 files changed, 76 insertions(+), 69 deletions(-) diff --git a/include/REX/REX/INI.h b/include/REX/REX/INI.h index 308a1b2a3..7db164efd 100644 --- a/include/REX/REX/INI.h +++ b/include/REX/REX/INI.h @@ -5,13 +5,16 @@ #ifdef REX_OPTION_INI namespace REX::INI { + using sec_t = std::string_view; + using key_t = std::string_view; + namespace Impl { template - void SettingLoad(void* a_file, std::string_view a_section, std::string_view a_key, T& a_value, T& a_valueDefault); + void SettingLoad(void* a_file, sec_t a_section, key_t a_key, T& a_value, T& a_valueDefault); template - void SettingSave(void* a_file, std::string_view a_section, std::string_view a_key, T& a_value); + void SettingSave(void* a_file, sec_t a_section, key_t a_key, T& a_value); } class SettingStore : @@ -27,7 +30,7 @@ namespace REX::INI public TSetting { public: - Setting(std::string_view a_section, std::string_view a_key, T a_default) : + Setting(sec_t a_section, key_t a_key, T a_default) : TSetting(a_default), m_section(a_section), m_key(a_key) @@ -50,8 +53,8 @@ namespace REX::INI } private: - std::string_view m_section; - std::string_view m_key; + sec_t m_section; + key_t m_key; }; template diff --git a/include/REX/REX/JSON.h b/include/REX/REX/JSON.h index f0148f62b..d51c98267 100644 --- a/include/REX/REX/JSON.h +++ b/include/REX/REX/JSON.h @@ -5,13 +5,15 @@ #ifdef REX_OPTION_JSON namespace REX::JSON { + using path_t = std::string_view; + namespace Impl { template - void SettingLoad(void* a_file, std::string_view a_path, T& a_value, T& a_valueDefault); + void SettingLoad(void* a_file, path_t a_path, T& a_value, T& a_valueDefault); template - void SettingSave(void* a_file, std::string_view a_path, T& a_value); + void SettingSave(void* a_file, path_t a_path, T& a_value); } class SettingStore : @@ -27,7 +29,7 @@ namespace REX::JSON public TSetting { public: - Setting(std::string_view a_path, T a_default) : + Setting(path_t a_path, T a_default) : TSetting(a_default), m_path(a_path) {} @@ -49,7 +51,7 @@ namespace REX::JSON } private: - std::string_view m_path; + path_t m_path; }; template diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index deb0d65e3..198034d6f 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -16,11 +16,11 @@ namespace REX::INI template void SettingLoad( - void* a_data, - std::string_view a_section, - std::string_view a_key, - T& a_value, - T& a_valueDefault) + void* a_data, + sec_t a_section, + key_t a_key, + T& a_value, + T& a_valueDefault) { const auto file = static_cast(a_data); if constexpr (std::is_same_v) { @@ -34,23 +34,23 @@ namespace REX::INI } } - template void SettingLoad(void*, std::string_view, std::string_view, bool&, bool&); - template void SettingLoad(void*, std::string_view, std::string_view, float&, float&); - template void SettingLoad(void*, std::string_view, std::string_view, double&, double&); - template void SettingLoad(void*, std::string_view, std::string_view, std::uint8_t&, std::uint8_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::uint16_t&, std::uint16_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::uint32_t&, std::uint32_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::int8_t&, std::int8_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::int16_t&, std::int16_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::int32_t&, std::int32_t&); - template void SettingLoad(void*, std::string_view, std::string_view, std::string&, std::string&); + template void SettingLoad(void*, sec_t, key_t, bool&, bool&); + template void SettingLoad(void*, sec_t, key_t, float&, float&); + template void SettingLoad(void*, sec_t, key_t, double&, double&); + template void SettingLoad(void*, sec_t, key_t, std::uint8_t&, std::uint8_t&); + template void SettingLoad(void*, sec_t, key_t, std::uint16_t&, std::uint16_t&); + template void SettingLoad(void*, sec_t, key_t, std::uint32_t&, std::uint32_t&); + template void SettingLoad(void*, sec_t, key_t, std::int8_t&, std::int8_t&); + template void SettingLoad(void*, sec_t, key_t, std::int16_t&, std::int16_t&); + template void SettingLoad(void*, sec_t, key_t, std::int32_t&, std::int32_t&); + template void SettingLoad(void*, sec_t, key_t, std::string&, std::string&); template void SettingSave( - void* a_data, - std::string_view a_section, - std::string_view a_key, - T& a_value) + void* a_data, + sec_t a_section, + key_t a_key, + T& a_value) { auto& file = *static_cast(a_data); if constexpr (std::is_same_v) { @@ -64,16 +64,16 @@ namespace REX::INI } } - template void SettingSave(void*, std::string_view, std::string_view, bool&); - template void SettingSave(void*, std::string_view, std::string_view, float&); - template void SettingSave(void*, std::string_view, std::string_view, double&); - template void SettingSave(void*, std::string_view, std::string_view, std::uint8_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::uint16_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::uint32_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::int8_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::int16_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::int32_t&); - template void SettingSave(void*, std::string_view, std::string_view, std::string&); + template void SettingSave(void*, sec_t, key_t, bool&); + template void SettingSave(void*, sec_t, key_t, float&); + template void SettingSave(void*, sec_t, key_t, double&); + template void SettingSave(void*, sec_t, key_t, std::uint8_t&); + template void SettingSave(void*, sec_t, key_t, std::uint16_t&); + template void SettingSave(void*, sec_t, key_t, std::uint32_t&); + template void SettingSave(void*, sec_t, key_t, std::int8_t&); + template void SettingSave(void*, sec_t, key_t, std::int16_t&); + template void SettingSave(void*, sec_t, key_t, std::int32_t&); + template void SettingSave(void*, sec_t, key_t, std::string&); } void SettingStore::Load() @@ -122,52 +122,54 @@ namespace REX::JSON { template void SettingLoad( - void* a_data, - std::string_view a_path, - T& a_value, - T& a_valueDefault) + void* a_data, + path_t a_path, + T& a_value, + T& a_valueDefault) { const auto& json = *static_cast(a_data); - if (a_path[0] == '/') + if (a_path[0] == '/') { a_value = json.value(nlohmann::json::json_pointer(a_path.data()), a_valueDefault); - else + } else { a_value = json.value(a_path, a_valueDefault); + } } - template void SettingLoad(void*, std::string_view, bool&, bool&); - template void SettingLoad(void*, std::string_view, float&, float&); - template void SettingLoad(void*, std::string_view, double&, double&); - template void SettingLoad(void*, std::string_view, std::uint8_t&, std::uint8_t&); - template void SettingLoad(void*, std::string_view, std::uint16_t&, std::uint16_t&); - template void SettingLoad(void*, std::string_view, std::uint32_t&, std::uint32_t&); - template void SettingLoad(void*, std::string_view, std::int8_t&, std::int8_t&); - template void SettingLoad(void*, std::string_view, std::int16_t&, std::int16_t&); - template void SettingLoad(void*, std::string_view, std::int32_t&, std::int32_t&); - template void SettingLoad(void*, std::string_view, std::string&, std::string&); + template void SettingLoad(void*, path_t, bool&, bool&); + template void SettingLoad(void*, path_t, float&, float&); + template void SettingLoad(void*, path_t, double&, double&); + template void SettingLoad(void*, path_t, std::uint8_t&, std::uint8_t&); + template void SettingLoad(void*, path_t, std::uint16_t&, std::uint16_t&); + template void SettingLoad(void*, path_t, std::uint32_t&, std::uint32_t&); + template void SettingLoad(void*, path_t, std::int8_t&, std::int8_t&); + template void SettingLoad(void*, path_t, std::int16_t&, std::int16_t&); + template void SettingLoad(void*, path_t, std::int32_t&, std::int32_t&); + template void SettingLoad(void*, path_t, std::string&, std::string&); template void SettingSave( - void* a_data, - std::string_view a_path, - T& a_value) + void* a_data, + path_t a_path, + T& a_value) { auto& json = *static_cast(a_data); - if (a_path[0] == '/') + if (a_path[0] == '/') { json[nlohmann::json::json_pointer(a_path.data())] = a_value; - else + } else { json[a_path] = a_value; + } } - template void SettingSave(void*, std::string_view, bool&); - template void SettingSave(void*, std::string_view, float&); - template void SettingSave(void*, std::string_view, double&); - template void SettingSave(void*, std::string_view, std::uint8_t&); - template void SettingSave(void*, std::string_view, std::uint16_t&); - template void SettingSave(void*, std::string_view, std::uint32_t&); - template void SettingSave(void*, std::string_view, std::int8_t&); - template void SettingSave(void*, std::string_view, std::int16_t&); - template void SettingSave(void*, std::string_view, std::int32_t&); - template void SettingSave(void*, std::string_view, std::string&); + template void SettingSave(void*, path_t, bool&); + template void SettingSave(void*, path_t, float&); + template void SettingSave(void*, path_t, double&); + template void SettingSave(void*, path_t, std::uint8_t&); + template void SettingSave(void*, path_t, std::uint16_t&); + template void SettingSave(void*, path_t, std::uint32_t&); + template void SettingSave(void*, path_t, std::int8_t&); + template void SettingSave(void*, path_t, std::int16_t&); + template void SettingSave(void*, path_t, std::int32_t&); + template void SettingSave(void*, path_t, std::string&); } void SettingStore::Load() From 585dcb60bf771260cd28836e0d606eb4592d1c70 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 13:20:22 -0700 Subject: [PATCH 18/24] refactor: tweak json output --- src/REX/REX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 198034d6f..4554eeb5b 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -212,7 +212,7 @@ namespace REX::JSON } std::ofstream file{ m_fileBase.data(), std::ios::trunc }; - file << output.dump(4); + file << std::setw(4) << output; } } #endif From cf2128cff50a07e533d84cb267fb9a503fbd1863 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 13:23:49 -0700 Subject: [PATCH 19/24] feat: add options to CMakeLists --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 370d6c12b..0a9406a17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.19) option(SKSE_SUPPORT_XBYAK "Enables trampoline support for Xbyak." OFF) +option(REX_OPTION_INI "Enables ini config support for REX." OFF) +option(REX_OPTION_JSON "Enables json config support for REX." OFF) +option(REX_OPTION_TOML "Enables toml config support for REX." OFF) option(SKYRIM_SUPPORT_AE "Enables support for Skyrim AE" OFF) project( From e1d1b0c7e790489cd529b82c5d2477f91a4435bd Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 13:32:59 -0700 Subject: [PATCH 20/24] fix: revert key type change --- include/REX/REX/TOML.h | 4 ++-- src/REX/REX.cpp | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index 324e5dced..21e03f47c 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -6,7 +6,7 @@ namespace REX::TOML { using sec_t = std::vector; - using key_t = std::string; + using key_t = std::string_view; namespace Impl { @@ -36,7 +36,7 @@ namespace REX::TOML m_key(a_key) {} - Setting(std::string a_section, key_t a_key, T a_default) : + Setting(std::string_view a_section, key_t a_key, T a_default) : TSetting(a_default), m_section(), m_key(a_key) diff --git a/src/REX/REX.cpp b/src/REX/REX.cpp index 4554eeb5b..f7103830a 100644 --- a/src/REX/REX.cpp +++ b/src/REX/REX.cpp @@ -224,7 +224,7 @@ namespace REX::TOML { namespace Impl { - static toml::value* recurse_table(toml::value* a_result, toml::value& a_value, std::string a_section, bool a_create) + static toml::value* recurse_table(toml::value* a_result, toml::value& a_value, const std::string& a_section, bool a_create) { if (a_result && a_result->is_table()) { for (auto& value : a_result->as_table()) { @@ -252,17 +252,17 @@ namespace REX::TOML static bool recurse_mark_implicit(toml::value& a_value) { - bool result{ true }; for (auto& kv : a_value.as_table()) { if (kv.second.is_table()) { - if (!recurse_mark_implicit(kv.second)) + if (!recurse_mark_implicit(kv.second)) { continue; + } kv.second.as_table_fmt().fmt = toml::table_format::implicit; } else { return false; } } - return result; + return true; } template @@ -276,11 +276,11 @@ namespace REX::TOML const auto& data = static_cast(a_data); if (a_section.empty()) { auto& path = (*data); - a_value = toml::find_or(path, a_key, a_valueDefault); + a_value = toml::find_or(path, a_key.data(), a_valueDefault); return; } else if (a_section.size() == 1) { auto& path = (*data)[a_section.front()]; - a_value = toml::find_or(path, a_key, a_valueDefault); + a_value = toml::find_or(path, a_key.data(), a_valueDefault); return; } else { toml::value* path{ nullptr }; @@ -288,7 +288,7 @@ namespace REX::TOML path = recurse_table(path, *data, section, false); } if (path) { - a_value = toml::find_or(*path, a_key, a_valueDefault); + a_value = toml::find_or(*path, a_key.data(), a_valueDefault); return; } } @@ -315,16 +315,16 @@ namespace REX::TOML { auto& data = *static_cast(a_data); if (a_section.empty()) { - data[a_key] = a_value; + data[a_key.data()] = a_value; } else if (a_section.size() == 1) { - data[a_section.front()][a_key] = a_value; + data[a_section.front()][a_key.data()] = a_value; } else { toml::value* path{ nullptr }; for (auto& section : a_section) { path = recurse_table(path, data, section, true); } if (path) { - (*path)[a_key] = a_value; + (*path)[a_key.data()] = a_value; } } } From c679be1b674f4c7d7b5dc172c2dcf5085d68b7b8 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 13:39:22 -0700 Subject: [PATCH 21/24] feat: add defines to CMakeLists --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a9406a17..a2f9a0002 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ cmake_minimum_required(VERSION 3.19) -option(SKSE_SUPPORT_XBYAK "Enables trampoline support for Xbyak." OFF) option(REX_OPTION_INI "Enables ini config support for REX." OFF) option(REX_OPTION_JSON "Enables json config support for REX." OFF) option(REX_OPTION_TOML "Enables toml config support for REX." OFF) +option(SKSE_SUPPORT_XBYAK "Enables trampoline support for Xbyak." OFF) option(SKYRIM_SUPPORT_AE "Enables support for Skyrim AE" OFF) project( @@ -42,6 +42,9 @@ target_compile_definitions( PUBLIC WINVER=0x0601 # windows 7, minimum supported version by skyrim special edition _WIN32_WINNT=0x0601 + "$<$:REX_OPTION_INI=1>" + "$<$:REX_OPTION_JSON=1>" + "$<$:REX_OPTION_TOML=1>" "$<$:SKSE_SUPPORT_XBYAK=1>" "$<$:SKYRIM_SUPPORT_AE=1>" ) From 30fe80560f88860cc3591de38aa8bcb90ce947d3 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 13:47:52 -0700 Subject: [PATCH 22/24] fix: sort xmake options --- xmake.lua | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/xmake.lua b/xmake.lua index 51377eac9..981e3848a 100644 --- a/xmake.lua +++ b/xmake.lua @@ -15,18 +15,6 @@ add_rules("mode.debug", "mode.releasedbg") includes("xmake-rules.lua") -- define options -option("skyrim_ae", function() - set_default(false) - set_description("Enable support for Skyrim AE") - add_defines("SKYRIM_SUPPORT_AE=1") -end) - -option("skse_xbyak", function() - set_default(false) - set_description("Enable trampoline support for Xbyak") - add_defines("SKSE_SUPPORT_XBYAK=1") -end) - option("rex_ini") set_default(false) set_description("Enable ini config support for REX") @@ -45,14 +33,22 @@ option("rex_toml") add_defines("REX_OPTION_TOML=1") option_end() +option("skyrim_ae", function() + set_default(false) + set_description("Enable support for Skyrim AE") + add_defines("SKYRIM_SUPPORT_AE=1") +end) + +option("skse_xbyak", function() + set_default(false) + set_description("Enable trampoline support for Xbyak") + add_defines("SKSE_SUPPORT_XBYAK=1") +end) + -- require packages add_requires("rsm-binary-io") add_requires("spdlog", { configs = { header_only = false, wchar = true, std_format = true } }) -if has_config("skse_xbyak") then - add_requires("xbyak") -end - if has_config("rex_ini") then add_requires("simpleini") end @@ -65,6 +61,10 @@ if has_config("rex_toml") then add_requires("toml11") end +if has_config("skse_xbyak") then + add_requires("xbyak") +end + -- define targets target("commonlibsse", function() -- set target kind @@ -76,10 +76,6 @@ target("commonlibsse", function() -- add packages add_packages("rsm-binary-io", "spdlog", { public = true }) - if has_config("skse_xbyak") then - add_packages("xbyak", { public = true }) - end - if has_config("rex_ini") then add_packages("simpleini", { public = true }) end @@ -92,8 +88,12 @@ target("commonlibsse", function() add_packages("toml11", { public = true }) end + if has_config("skse_xbyak") then + add_packages("xbyak", { public = true }) + end + -- add options - add_options("skyrim_ae", "skse_xbyak", "rex_ini", "rex_json", "rex_toml", { public = true }) + add_options("rex_ini", "rex_json", "rex_toml", "skyrim_ae", "skse_xbyak", { public = true }) -- add system links add_syslinks("advapi32", "bcrypt", "d3d11", "d3dcompiler", "dbghelp", "dxgi", "ole32", "shell32", "user32", "version") From 02a517e6eab53852b4031d5fe07d949d2dc4a747 Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Thu, 14 Nov 2024 13:56:45 -0700 Subject: [PATCH 23/24] fix: make xmake rex options consistent --- xmake.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/xmake.lua b/xmake.lua index 981e3848a..b94d8cbb3 100644 --- a/xmake.lua +++ b/xmake.lua @@ -15,23 +15,23 @@ add_rules("mode.debug", "mode.releasedbg") includes("xmake-rules.lua") -- define options -option("rex_ini") +option("rex_ini", function() set_default(false) set_description("Enable ini config support for REX") add_defines("REX_OPTION_INI=1") -option_end() +end) -option("rex_json") +option("rex_json", function() set_default(false) set_description("Enable json config support for REX") add_defines("REX_OPTION_JSON=1") -option_end() +end) -option("rex_toml") +option("rex_toml", function() set_default(false) set_description("Enable toml config support for REX") add_defines("REX_OPTION_TOML=1") -option_end() +end) option("skyrim_ae", function() set_default(false) From dcc6022f0950a31d2294228839d9bbe300b29562 Mon Sep 17 00:00:00 2001 From: Qudix <17361645+Qudix@users.noreply.github.com> Date: Thu, 14 Nov 2024 16:46:00 -0600 Subject: [PATCH 24/24] feat: simplify formatter's --- include/REX/REX/INI.h | 37 +++++++------------------------------ include/REX/REX/JSON.h | 37 +++++++------------------------------ include/REX/REX/TOML.h | 37 +++++++------------------------------ 3 files changed, 21 insertions(+), 90 deletions(-) diff --git a/include/REX/REX/INI.h b/include/REX/REX/INI.h index 7db164efd..315dfb89e 100644 --- a/include/REX/REX/INI.h +++ b/include/REX/REX/INI.h @@ -88,36 +88,13 @@ namespace REX::INI using Str = Setting; } -namespace REX::INI::Impl +template +struct std::formatter, CharT> : std::formatter { -# ifdef __cpp_lib_format - template - struct formatter : std::formatter + template + auto format(const REX::INI::Setting& a_setting, FormatContext& a_ctx) const { - template - auto format(REX::INI::Setting a_setting, FormatContext& a_ctx) const - { - return std::formatter::format(a_setting.GetValue(), a_ctx); - } - }; -# endif -} - -# ifdef __cpp_lib_format -namespace std -{ - // clang-format off - template struct formatter, CharT> : REX::INI::Impl::formatter {}; - template struct formatter, CharT> : REX::INI::Impl::formatter {}; - template struct formatter, CharT> : REX::INI::Impl::formatter {}; - template struct formatter, CharT> : REX::INI::Impl::formatter {}; - template struct formatter, CharT> : REX::INI::Impl::formatter {}; - template struct formatter, CharT> : REX::INI::Impl::formatter {}; - template struct formatter, CharT> : REX::INI::Impl::formatter {}; - template struct formatter, CharT> : REX::INI::Impl::formatter {}; - template struct formatter, CharT> : REX::INI::Impl::formatter {}; - template struct formatter, CharT> : REX::INI::Impl::formatter {}; - // clang-format on -} -# endif + return std::formatter::format(a_setting.GetValue(), a_ctx); + } +}; #endif diff --git a/include/REX/REX/JSON.h b/include/REX/REX/JSON.h index d51c98267..14b2e4ae6 100644 --- a/include/REX/REX/JSON.h +++ b/include/REX/REX/JSON.h @@ -85,36 +85,13 @@ namespace REX::JSON using Str = Setting; } -namespace REX::JSON::Impl +template +struct std::formatter, CharT> : std::formatter { -# ifdef __cpp_lib_format - template - struct formatter : std::formatter + template + auto format(const REX::JSON::Setting& a_setting, FormatContext& a_ctx) const { - template - auto format(REX::JSON::Setting a_setting, FormatContext& a_ctx) const - { - return std::formatter::format(a_setting.GetValue(), a_ctx); - } - }; -# endif -} - -# ifdef __cpp_lib_format -namespace std -{ - // clang-format off - template struct formatter, CharT> : REX::JSON::Impl::formatter {}; - template struct formatter, CharT> : REX::JSON::Impl::formatter {}; - template struct formatter, CharT> : REX::JSON::Impl::formatter {}; - template struct formatter, CharT> : REX::JSON::Impl::formatter {}; - template struct formatter, CharT> : REX::JSON::Impl::formatter {}; - template struct formatter, CharT> : REX::JSON::Impl::formatter {}; - template struct formatter, CharT> : REX::JSON::Impl::formatter {}; - template struct formatter, CharT> : REX::JSON::Impl::formatter {}; - template struct formatter, CharT> : REX::JSON::Impl::formatter {}; - template struct formatter, CharT> : REX::JSON::Impl::formatter {}; - // clang-format on -} -# endif + return std::formatter::format(a_setting.GetValue(), a_ctx); + } +}; #endif diff --git a/include/REX/REX/TOML.h b/include/REX/REX/TOML.h index 21e03f47c..8516479f7 100644 --- a/include/REX/REX/TOML.h +++ b/include/REX/REX/TOML.h @@ -104,36 +104,13 @@ namespace REX::TOML using Str = Setting; } -namespace REX::TOML::Impl +template +struct std::formatter, CharT> : std::formatter { -# ifdef __cpp_lib_format - template - struct formatter : std::formatter + template + auto format(const REX::TOML::Setting& a_setting, FormatContext& a_ctx) const { - template - auto format(REX::TOML::Setting a_setting, FormatContext& a_ctx) const - { - return std::formatter::format(a_setting.GetValue(), a_ctx); - } - }; -# endif -} - -# ifdef __cpp_lib_format -namespace std -{ - // clang-format off - template struct formatter, CharT> : REX::TOML::Impl::formatter {}; - template struct formatter, CharT> : REX::TOML::Impl::formatter {}; - template struct formatter, CharT> : REX::TOML::Impl::formatter {}; - template struct formatter, CharT> : REX::TOML::Impl::formatter {}; - template struct formatter, CharT> : REX::TOML::Impl::formatter {}; - template struct formatter, CharT> : REX::TOML::Impl::formatter {}; - template struct formatter, CharT> : REX::TOML::Impl::formatter {}; - template struct formatter, CharT> : REX::TOML::Impl::formatter {}; - template struct formatter, CharT> : REX::TOML::Impl::formatter {}; - template struct formatter, CharT> : REX::TOML::Impl::formatter {}; - // clang-format on -} -# endif + return std::formatter::format(a_setting.GetValue(), a_ctx); + } +}; #endif