Skip to content

Commit

Permalink
feat: improve setting related classes (#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
qudix authored Oct 4, 2023
1 parent 96ffde9 commit f5055f4
Show file tree
Hide file tree
Showing 9 changed files with 297 additions and 89 deletions.
8 changes: 4 additions & 4 deletions CommonLibSF/include/RE/I/INIPrefSettingCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@

namespace RE
{
class INIPrefSettingCollection : public INISettingCollection
class INIPrefSettingCollection :
public INISettingCollection // 000
{
public:
SF_RTTI_VTABLE(INIPrefSettingCollection);

virtual ~INIPrefSettingCollection(); // 000

[[nodiscard]] static INIPrefSettingCollection* GetSingleton()
{
REL::Relocation<INIPrefSettingCollection**> singleton{ REL::ID(885866) };
return *singleton;
}

virtual ~INIPrefSettingCollection();
};
static_assert(sizeof(INIPrefSettingCollection) == 0x160);
}
18 changes: 15 additions & 3 deletions CommonLibSF/include/RE/I/INISettingCollection.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
#pragma once

#include "RE/S/Setting.h"
#include "RE/S/SettingCollectionList.h"

namespace RE
{
class INISettingCollection : public SettingCollectionList<Setting>
class INISettingCollection :
public SettingCollectionList<Setting> // 000
{
public:
SF_RTTI_VTABLE(INISettingCollection);

virtual ~INISettingCollection(); // 000

[[nodiscard]] static INISettingCollection* GetSingleton()
{
REL::Relocation<INISettingCollection**> singleton{ REL::ID(885862) };
return *singleton;
}

virtual ~INISettingCollection();
[[nodiscard]] Setting* GetSetting(const std::string_view a_name)
{
for (const auto& setting : settings) {
if (setting->GetKey() == a_name) {
return setting;
}
}

return nullptr;
}
};
static_assert(sizeof(INISettingCollection) == 0x160);
}
24 changes: 21 additions & 3 deletions CommonLibSF/include/RE/R/RegSettingCollection.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
#pragma once

#include "RE/S/Setting.h"
#include "RE/S/SettingCollectionList.h"

namespace RE
{
class RegSettingCollection : public SettingCollectionList<Setting>
class RegSettingCollection :
public SettingCollectionList<Setting> // 000
{
public:
SF_RTTI_VTABLE(RegSettingCollection);

virtual ~RegSettingCollection();
virtual ~RegSettingCollection(); // 000

[[nodiscard]] static RegSettingCollection* GetSingleton()
{
REL::Relocation<RegSettingCollection**> singleton{ REL::ID(885510) };
return *singleton;
}

[[nodiscard]] Setting* GetSetting(const std::string_view a_name)
{
for (const auto& setting : settings) {
if (setting->GetKey() == a_name) {
return setting;
}
}

return nullptr;
}
};
static_assert(sizeof(RegSettingCollection) == 0x160);
}
237 changes: 237 additions & 0 deletions CommonLibSF/include/RE/S/Setting.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
#pragma once

namespace RE
{
class __declspec(novtable) Setting
{
public:
SF_RTTI_VTABLE(Setting);
// FIXME: MemoryManager unimplemented
// SF_HEAP_REDEFINE_NEW(Setting);

enum class Type
{
kNone = 0,
kBool,
kChar,
kUChar,
kInt,
kUInt,
kFloat,
kString,
kRGB,
kRGBA
};

Setting(const char* a_key, const bool a_value)
{
_key = a_key;
_value.b = _defaultValue.b = a_value;
}

Setting(const char* a_key, const std::int8_t a_value)
{
_key = a_key;
_value.c = _defaultValue.c = a_value;
}

Setting(const char* a_key, const std::uint8_t a_value)
{
_key = a_key;
_value.h = _defaultValue.h = a_value;
}

Setting(const char* a_key, const std::int32_t a_value)
{
_key = a_key;
_value.i = _defaultValue.i = a_value;
}

Setting(const char* a_key, const std::uint32_t a_value)
{
_key = a_key;
_value.u = _defaultValue.u = a_value;
}

Setting(const char* a_key, const float a_value)
{
_key = a_key;
_value.f = _defaultValue.f = a_value;
}

Setting(const char* a_key, const char* a_value)
{
_key = a_key;
_value.s = _defaultValue.s = _strdup(a_value);
}

virtual ~Setting() { stl::emplace_vtable(this); } // 00

// add
[[nodiscard]] virtual bool IsPrefSetting() { return false; } // 01

[[nodiscard]] auto GetKey() const noexcept
{
return _key ? _key : ""sv;
}

[[nodiscard]] auto GetType() const noexcept
{
if (_key) {
switch (_key[0]) {
case 'a': return Type::kRGBA;
case 'b': return Type::kBool;
case 'c': return Type::kChar;
case 'f': return Type::kFloat;
case 'h': return Type::kUChar;
case 'i': return Type::kInt;
case 'r': return Type::kRGB;
case 's': return Type::kString; // static
case 'S': return Type::kString; // dynamic
case 'u': return Type::kUInt;
}
}

return Type::kNone;
}

[[nodiscard]] auto GetBool(const bool a_default = false) const noexcept
{
assert(GetType() == Type::kBool);
return a_default ? _value.b : _defaultValue.b;
}

[[nodiscard]] auto GetChar(const bool a_default = false) const noexcept
{
assert(GetType() == Type::kChar);
return a_default ? _value.c : _defaultValue.c;
}

[[nodiscard]] auto GetFloat(const bool a_default = false) const noexcept
{
assert(GetType() == Type::kFloat);
return a_default ? _value.f : _defaultValue.f;
}

[[nodiscard]] auto GetInt(const bool a_default = false) const noexcept
{
assert(GetType() == Type::kInt);
return a_default ? _value.i : _defaultValue.i;
}

[[nodiscard]] auto GetString(const bool a_default = false) const noexcept
{
assert(GetType() == Type::kString);
if (!a_default && _value.s)
return std::string_view{ _value.s };
else if (_defaultValue.s)
return std::string_view{ _defaultValue.s };

return ""sv;
}

[[nodiscard]] auto GetUChar(const bool a_default = false) const noexcept
{
assert(GetType() == Type::kUChar);
return a_default ? _value.h : _defaultValue.h;
}

[[nodiscard]] auto GetUInt(const bool a_default = false) const noexcept
{
assert(GetType() == Type::kUInt);
return a_default ? _value.u : _defaultValue.u;
}

Setting& operator=(const bool a_value)
{
assert(GetType() == Type::kBool);
_value.b = a_value;
return *this;
}

Setting& operator=(const std::int8_t a_value)
{
assert(GetType() == Type::kChar);
_value.c = a_value;
return *this;
}

Setting& operator=(const std::uint8_t a_value)
{
assert(GetType() == Type::kUChar);
_value.h = a_value;
return *this;
}

Setting& operator=(const std::int32_t a_value)
{
assert(GetType() == Type::kInt);
_value.i = a_value;
return *this;
}

Setting& operator=(const std::uint32_t a_value)
{
assert(GetType() == Type::kUInt);
_value.u = a_value;
return *this;
}

Setting& operator=(const float a_value)
{
assert(GetType() == Type::kFloat);
_value.f = a_value;
return *this;
}

// TODO: Verify
/*
Setting& operator=(const char* a_value)
{
assert(GetType() == Type::kString);
_value.s = _strdup(a_value);
return *this;
}*/

private:
union Value
{
std::uint32_t a;
bool b;
std::int8_t c;
float f;
std::uint8_t h;
std::int32_t i;
std::uint32_t r;
char* s;
std::uint32_t u;
};
static_assert(sizeof(Value) == 0x8);

// member
Value _value; // 08
Value _defaultValue; // 10
const char* _key; // 18
};
static_assert(sizeof(Setting) == 0x20);

template <class T>
class SettingT :
public Setting
{
public:
virtual ~SettingT();

static REL::Relocation<T*> collection;
};

class GameSettingCollection;
class INIPrefSettingCollection;
class INISettingCollection;
class RegSettingCollection;

extern template class SettingT<GameSettingCollection>;
extern template class SettingT<INIPrefSettingCollection>;
extern template class SettingT<INISettingCollection>;
extern template class SettingT<RegSettingCollection>;
}
13 changes: 5 additions & 8 deletions CommonLibSF/include/RE/S/SettingCollection.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
#pragma once

#include "RE/B/BSTList.h"
#include "RE/S/Settings.h"

namespace RE
{
template <typename T>
class Setting;

template <class T>
class SettingCollection
{
public:
virtual ~SettingCollection();
virtual ~SettingCollection(); // 000

// add
virtual void Add(T* a_setting) = 0; // 01
Expand All @@ -28,9 +27,7 @@ namespace RE
char settingFile[260]; // 008
std::uint32_t pad10C; // 10C
void* handle; // 110
BSSimpleList<T> settings; // 118
std::uint64_t unk128; // 128
std::uint64_t unk130; // 130
};

extern template class SettingCollection<Setting>;
}
12 changes: 9 additions & 3 deletions CommonLibSF/include/RE/S/SettingCollectionList.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
#pragma once

#include "RE/B/BSTList.h"
#include "RE/S/SettingCollection.h"

namespace RE
{
template <typename T>
class SettingCollectionList : public SettingCollection<T>
template <class T>
class SettingCollectionList :
public SettingCollection<T> // 000
{
public:
virtual ~SettingCollectionList();
virtual ~SettingCollectionList(); // 000

// members
BSSimpleList<T*> settings; // 118
std::uint64_t unk128; // 128
std::uint64_t unk130; // 130
};
static_assert(sizeof(SettingCollectionList<Setting>) == 0x138);

extern template class SettingCollectionList<Setting>;
}
Loading

0 comments on commit f5055f4

Please sign in to comment.