mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
cppkore uses string/wstring as StringBase while we use std::string/std::wstring as string/wstring. Changed all types in cppkore to String/WString instead.
264 lines
5.5 KiB
C++
264 lines
5.5 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include "ListBase.h"
|
|
#include "StringBase.h"
|
|
#include "ImmutableStringBase.h"
|
|
#include "File.h"
|
|
#include "BinaryReader.h"
|
|
#include "BinaryWriter.h"
|
|
|
|
namespace System
|
|
{
|
|
// Represents the type of setting we are using
|
|
enum class SettingType : char
|
|
{
|
|
Boolean = 'B',
|
|
Integer = 'I',
|
|
Integer64 = 'L',
|
|
String = 'S',
|
|
ProtectedString = 'P'
|
|
};
|
|
|
|
// Used to store a setting.
|
|
class SettingsObject
|
|
{
|
|
public:
|
|
SettingsObject();
|
|
SettingsObject(String Key, SettingType Type, uint8_t* Value);
|
|
~SettingsObject();
|
|
|
|
String Key;
|
|
SettingType Type;
|
|
|
|
union ValueUn
|
|
{
|
|
char* String;
|
|
bool Boolean;
|
|
uint32_t Integer;
|
|
uint64_t Integer64;
|
|
} Values;
|
|
|
|
SettingsObject& operator=(SettingsObject Rhs)
|
|
{
|
|
Key = Rhs.Key;
|
|
Type = Rhs.Type;
|
|
|
|
if (Type == SettingType::String || Type == SettingType::ProtectedString)
|
|
{
|
|
if (this->Values.String)
|
|
delete[] this->Values.String;
|
|
|
|
auto Len = strlen(Rhs.Values.String);
|
|
this->Values.String = new char[Len + 1]{};
|
|
std::memcpy(this->Values.String, Rhs.Values.String, Len);
|
|
}
|
|
else
|
|
{
|
|
this->Values.Integer64 = Rhs.Values.Integer64;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool operator==(SettingsObject Rhs)
|
|
{
|
|
// yes yes yes i know this is bad but it doesn't cause issues for me so who cares
|
|
return Key == Rhs.Key && Type == Rhs.Type;
|
|
}
|
|
};
|
|
|
|
// Reads and writes configuration files.
|
|
class Settings
|
|
{
|
|
public:
|
|
Settings() = default;
|
|
~Settings() = default;
|
|
|
|
|
|
_declspec(noinline) void SetBool(const imstring& Key, bool Value)
|
|
{
|
|
for (auto& Setting : _Settings)
|
|
{
|
|
if (Setting.Key == (const char*)Key)
|
|
{
|
|
Setting.Values.Boolean = Value;
|
|
}
|
|
}
|
|
_Settings.EmplaceBack(Key, SettingType::Boolean, (uint8_t*)&Value);
|
|
}
|
|
|
|
_declspec(noinline) void SetInt(const imstring& Key, uint32_t Value)
|
|
{
|
|
for (auto& Setting : _Settings)
|
|
{
|
|
if (Setting.Key == (const char*)Key)
|
|
{
|
|
Setting.Values.Integer = Value;
|
|
}
|
|
}
|
|
_Settings.EmplaceBack(Key, SettingType::Integer, (uint8_t*)&Value);
|
|
}
|
|
|
|
template<SettingType T, class V>
|
|
_declspec(noinline) void Set(const imstring& Key, V && Value)
|
|
{
|
|
for (auto& Setting : _Settings)
|
|
{
|
|
if (Setting.Key == (const char*)Key)
|
|
{
|
|
if constexpr (T == SettingType::Boolean)
|
|
Setting.Values.Boolean = Value;
|
|
else if constexpr (T == SettingType::Integer)
|
|
Setting.Values.Integer = Value;
|
|
else if constexpr (T == SettingType::Integer64)
|
|
Setting.Values.Integer64 = Value;
|
|
else if constexpr (T == SettingType::ProtectedString || T == SettingType::String)
|
|
{
|
|
if (Setting.Values.String != NULL)
|
|
delete[] Setting.Values.String;
|
|
|
|
if constexpr (std::is_same<V, String>::value)
|
|
{
|
|
Setting.Values.String = new char[Value.Length() + 1]{};
|
|
std::memcpy(Setting.Values.String, (const char*)Value, Value.Length());
|
|
}
|
|
else
|
|
{
|
|
auto Len = strlen(Value);
|
|
Setting.Values.String = new char[Len + 1]{};
|
|
std::memcpy(Setting.Values.String, Value, Len);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
if constexpr (T == SettingType::String)
|
|
_Settings.EmplaceBack(Key, T, (uint8_t*)Value.ToCString());
|
|
else
|
|
_Settings.EmplaceBack(Key, T, (uint8_t*)&Value);
|
|
|
|
}
|
|
|
|
template<const SettingType T>
|
|
_declspec(noinline) bool Has(const imstring& Key)
|
|
{
|
|
SettingsObject* Value = nullptr;
|
|
|
|
for (auto& Setting : _Settings)
|
|
{
|
|
if (Setting.Key == (const char*)Key)
|
|
{
|
|
Value = &Setting;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (Value != nullptr);
|
|
}
|
|
|
|
// for some reason the template one doesn't even check the type so what is the point in having it as a template?
|
|
bool Has(const imstring& Key)
|
|
{
|
|
SettingsObject* Value = nullptr;
|
|
|
|
for (auto& Setting : _Settings)
|
|
{
|
|
if (Setting.Key == (const char*)Key)
|
|
{
|
|
Value = &Setting;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (Value != nullptr);
|
|
}
|
|
|
|
template<const SettingType T>
|
|
_declspec(noinline) void Remove(const imstring& Key)
|
|
{
|
|
for (SettingsObject& Setting : _Settings)
|
|
{
|
|
if (Setting.Key == (const char*)Key)
|
|
{
|
|
Setting = SettingsObject();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return;
|
|
};
|
|
|
|
_declspec(noinline) bool GetBool(const imstring& Key)
|
|
{
|
|
SettingsObject* Value = nullptr;
|
|
|
|
for (auto& Setting : _Settings)
|
|
{
|
|
if (Setting.Key == (const char*)Key)
|
|
{
|
|
Value = &Setting;
|
|
break;
|
|
}
|
|
}
|
|
if (Value)
|
|
return Value->Values.Boolean;
|
|
|
|
return false;
|
|
}
|
|
|
|
template<const SettingType T>
|
|
_declspec(noinline) auto Get(const imstring& Key)
|
|
{
|
|
SettingsObject* Value = nullptr;
|
|
|
|
for (auto& Setting : _Settings)
|
|
{
|
|
if (Setting.Key == (const char*)Key)
|
|
{
|
|
Value = &Setting;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if constexpr (T == SettingType::Boolean)
|
|
{
|
|
if (Value)
|
|
return (bool)Value->Values.Boolean;
|
|
|
|
return (bool)false;
|
|
}
|
|
else if constexpr (T == SettingType::Integer)
|
|
{
|
|
if (Value)
|
|
return (uint32_t)Value->Values.Integer;
|
|
|
|
return (uint32_t)0;
|
|
}
|
|
else if constexpr (T == SettingType::Integer64)
|
|
{
|
|
if (Value)
|
|
return (uint64_t)Value->Values.Integer64;
|
|
|
|
return (uint64_t)0;
|
|
}
|
|
else if constexpr (T == SettingType::String || T == SettingType::ProtectedString)
|
|
{
|
|
if (Value)
|
|
return (String)Value->Values.String;
|
|
|
|
return (String)"";
|
|
}
|
|
}
|
|
|
|
// Load the config file from the specified path.
|
|
void Load(const String& Path);
|
|
// Save the config file to the specified path.
|
|
void Save(const String& Path);
|
|
|
|
private:
|
|
// Internal cached settings
|
|
List<SettingsObject> _Settings;
|
|
};
|
|
} |