Add settings API and specification

The details of the API are in the `/docs/specsSettings-API.md` file.

The enums do not list all available settings, more are to be added as
the settings API replaces inline QSettings calls.
This commit is contained in:
Vasily
2019-12-03 08:26:10 +01:00
committed by username223
parent 61fd3dde79
commit c1690056cc
13 changed files with 1131 additions and 5 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
#include "utils/setup.h"
#include "settings/settings.h"
INITIALIZE_EASYLOGGINGPP
@@ -40,7 +41,7 @@ int main( int argc, char* argv[] )
mainEventLoop.applicationName() );
advsettings::OverlayController::setAppSettings( &appSettings );
LOG( INFO ) << "Settings File: "
<< appSettings.fileName().toStdString();
<< settings::initializeAndGetSettingsPath();
QQmlEngine qmlEngine;
+5
View File
@@ -22,6 +22,7 @@
#include "utils/Matrix.h"
#include "openvr/overlay_utils.h"
#include "keyboard_input/input_sender.h"
#include "settings/settings.h"
// application namespace
namespace advsettings
@@ -1114,6 +1115,9 @@ void OverlayController::mainEventLoop()
LOG( INFO ) << "Received quit request.";
vr::VRSystem()->AcknowledgeQuit_Exiting(); // Let us buy some
// time just in case
settings::saveAllSettings();
m_moveCenterTabController.shutdown();
// Un-mute mic before Exiting VR, as it is set at system level Not
// Vr level.
@@ -1140,6 +1144,7 @@ void OverlayController::mainEventLoop()
{
LOG( DEBUG ) << "Dashboard deactivated";
m_dashboardVisible = false;
settings::saveChangedSettings();
}
break;
+63
View File
@@ -0,0 +1,63 @@
#pragma once
#include <QSettings>
#include "settings.h"
#include "settings_internal.h"
#include "setting_value.h"
namespace settings
{
class BoolSettingValue : public SettingValue
{
public:
BoolSettingValue( const BoolSetting setting,
const SettingCategory category,
const QtInfo qtInfo,
const bool defaultValue )
: SettingValue( category, qtInfo ), m_setting( setting ),
m_value( defaultValue )
{
const auto v = getQtSetting( SettingValue::category(),
SettingValue::qtInfo().settingName );
if ( isValidQVariant( v, QMetaType::Bool ) )
{
m_value = v.toBool();
}
}
void setValue( const bool value ) noexcept
{
m_value = value;
}
bool value() const noexcept
{
return m_value;
}
BoolSetting setting() const noexcept
{
return m_setting;
}
SettingCategory category() const noexcept
{
return SettingValue::category();
}
QtInfo qtInfo() const noexcept
{
return SettingValue::qtInfo();
}
void saveValue() override
{
saveQtSetting( SettingValue::category(),
SettingValue::qtInfo().settingName,
m_value );
}
private:
const BoolSetting m_setting;
bool m_value;
};
} // namespace settings
+63
View File
@@ -0,0 +1,63 @@
#pragma once
#include <QSettings>
#include "settings.h"
#include "settings_internal.h"
#include "setting_value.h"
namespace settings
{
class DoubleSettingValue : public SettingValue
{
public:
DoubleSettingValue( const DoubleSetting setting,
const SettingCategory category,
const QtInfo qtInfo,
const double defaultValue )
: SettingValue( category, qtInfo ), m_setting( setting ),
m_value( defaultValue )
{
const auto v = getQtSetting( SettingValue::category(),
SettingValue::qtInfo().settingName );
if ( isValidQVariant( v, QMetaType::Double ) )
{
m_value = v.toDouble();
}
}
void setValue( const double value ) noexcept
{
m_value = value;
}
double value() const noexcept
{
return m_value;
}
DoubleSetting setting() const noexcept
{
return m_setting;
}
SettingCategory category() const noexcept
{
return SettingValue::category();
}
QtInfo qtInfo() const noexcept
{
return SettingValue::qtInfo();
}
void saveValue() override
{
saveQtSetting( SettingValue::category(),
SettingValue::qtInfo().settingName,
m_value );
}
private:
const DoubleSetting m_setting;
double m_value;
};
} // namespace settings
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include "settings_internal.h"
namespace settings
{
class SettingValue
{
public:
SettingValue( const SettingCategory category, const QtInfo qtInfo ) noexcept
: m_category{ category }, m_qtInfo{ qtInfo }
{
}
virtual ~SettingValue() {}
[[nodiscard]] SettingCategory category() const noexcept
{
return m_category;
}
[[nodiscard]] QtInfo qtInfo() const noexcept
{
return m_qtInfo;
}
virtual void saveValue() = 0;
private:
const SettingCategory m_category;
const QtInfo m_qtInfo;
};
} // namespace settings
+76
View File
@@ -0,0 +1,76 @@
#include <utility>
#include <QSettings>
#include <easylogging++.h>
#include "../overlaycontroller.h"
#include "settings_controller.h"
namespace settings
{
SettingsController& getSettingsController()
{
static SettingsController s{};
return s;
}
void saveChangedSettings()
{
getSettingsController().saveChangedSettings();
}
void saveAllSettings()
{
LOG( INFO ) << "Saving all settings.";
getSettingsController().saveAllSettings();
LOG( INFO ) << "All settings saved.";
}
[[nodiscard]] bool getSetting( const BoolSetting setting )
{
return getSettingsController().getSetting<bool>( setting );
}
void setSetting( const BoolSetting setting, const bool value )
{
getSettingsController().setSetting( setting, value );
}
[[nodiscard]] double getSetting( const DoubleSetting setting )
{
return getSettingsController().getSetting<double>( setting );
}
void setSetting( const DoubleSetting setting, const double value )
{
getSettingsController().setSetting( setting, value );
}
[[nodiscard]] int getSetting( const IntSetting setting )
{
return getSettingsController().getSetting<int>( setting );
}
void setSetting( const IntSetting setting, const int value )
{
getSettingsController().setSetting( setting, value );
}
[[nodiscard]] std::string getSetting( const StringSetting setting )
{
return getSettingsController().getSetting<std::string>( setting );
}
void setSetting( const StringSetting setting, const std::string value )
{
getSettingsController().setSetting( setting, value );
}
std::string initializeAndGetSettingsPath()
{
// The static object is initialized the first time the function is called.
// Having a dedicated function for this allows more control over when this
// happens.
return getSettingsController().getSettingsFileName();
}
} // namespace settings
+93
View File
@@ -0,0 +1,93 @@
#pragma once
#include <string>
namespace settings
{
enum class BoolSetting
{
PLAYSPACE_lockXToggle,
PLAYSPACE_lockYToggle,
PLAYSPACE_lockZToggle,
PLAYSPACE_momentumSave,
PLAYSPACE_turnBindLeft,
PLAYSPACE_turnBindRight,
PLAYSPACE_turnBounds,
PLAYSPACE_moveShortcutLeft,
PLAYSPACE_moveShortcutRight,
PLAYSPACE_dragBounds,
PLAYSPACE_allowExternalEdits,
PLAYSPACE_oldStyleMotion,
PLAYSPACE_universeCenteredRotation,
PLAYSPACE_enableSeatedMotion,
APPLICATION_disableVersionCheck,
APPLICATION_previousShutdownSafe,
VIDEO_brightnessEnabled,
VIDEO_isOverlayMethodActive,
VIDEO_colorOverlayEnabled,
CHAPERONE_disableChaperone,
// LAST_ENUMERATOR must always be set to the last value
LAST_ENUMERATOR = CHAPERONE_disableChaperone,
};
enum class DoubleSetting
{
UTILITY_desktopWidth,
VIDEO_brightnessOpacityValue,
VIDEO_brightnessValue,
VIDEO_colorOverlayOpacity,
VIDEO_colorRed,
VIDEO_colorGreen,
VIDEO_colorBlue,
VIDEO_colorRedNew,
VIDEO_colorGreenNew,
VIDEO_colorBlueNew,
CHAPERONE_switchToBeginnerDistance,
CHAPERONE_hapticFeedbackDistance,
CHAPERONE_alarmSoundDistance,
CHAPERONE_showDashboardDistance,
CHAPERONE_fadeDistanceRemembered,
// LAST_ENUMERATOR must always be set to the last value
LAST_ENUMERATOR = CHAPERONE_fadeDistanceRemembered,
};
enum class StringSetting
{
KEYBOARDSHORTCUT_keyboardOne,
KEYBOARDSHORTCUT_keyboardTwo,
KEYBOARDSHORTCUT_keyboardThree,
// LAST_ENUMERATOR must always be set to the last value
LAST_ENUMERATOR = KEYBOARDSHORTCUT_keyboardThree,
};
enum class IntSetting
{
UTILITY_alarmHour,
UTILITY_alarmMinute,
// LAST_ENUMERATOR must always be set to the last value
LAST_ENUMERATOR = UTILITY_alarmMinute,
};
std::string initializeAndGetSettingsPath();
void saveChangedSettings();
void saveAllSettings();
[[nodiscard]] bool getSetting( const BoolSetting setting );
void setSetting( const BoolSetting setting, const bool value );
[[nodiscard]] double getSetting( const DoubleSetting setting );
void setSetting( const DoubleSetting setting, const double value );
[[nodiscard]] int getSetting( const IntSetting setting );
void setSetting( const IntSetting setting, const int value );
[[nodiscard]] std::string getSetting( const StringSetting setting );
void setSetting( const StringSetting setting, const std::string value );
} // namespace settings
+337
View File
@@ -0,0 +1,337 @@
#pragma once
#include <assert.h>
#include <array>
#include <vector>
#include <easylogging++.h>
#include "settings.h"
#include "setting_value.h"
#include "../utils/setup.h"
#include "specific_setting_value.h"
namespace settings
{
template <typename Enum, int ArraySize, typename Value>
void verifySettings( std::array<Value, ArraySize> v ) noexcept
{
for ( int settingIndex = 0; settingIndex < ( ArraySize - 1 );
++settingIndex )
{
// Having the enum values be in the correct location makes getting a
// value O(1) instead of O(n) due to array lookup vs traversal
// Also ensures that there are no mising values
const auto currentSetting
= v[static_cast<std::size_t>( settingIndex )].setting();
const auto settingCorrectlyLocated
= currentSetting == static_cast<Enum>( settingIndex );
if ( !settingCorrectlyLocated )
{
const auto enumName = typeid( Enum ).name();
const auto enumSettingNumber = static_cast<int>( currentSetting );
LOG( ERROR ) << enumName << ": at index '" << settingIndex
<< "' is incorrect. Current value: '"
<< enumSettingNumber
<< "'. Exiting "
"with error code "
<< ReturnErrorCode::SETTING_INCORRECT_INDEX << ".";
exit( ReturnErrorCode::SETTING_INCORRECT_INDEX );
}
}
LOG( DEBUG ) << "Settings for '" << typeid( Enum ).name() << "' verified.";
}
class SettingsController
{
public:
SettingsController()
{
verifySettings<BoolSetting, boolSettingSize>( m_boolSettings );
verifySettings<DoubleSetting, doubleSettingSize>( m_doubleSettings );
verifySettings<StringSetting, stringSettingsSize>( m_stringSettings );
verifySettings<IntSetting, intSettingsSize>( m_intSettings );
}
std::string getSettingsFileName() const noexcept
{
return getQSettings().fileName().toStdString();
}
void saveChangedSettings()
{
if ( m_changedSettings.empty() )
{
return;
}
for ( const auto setting : m_changedSettings )
{
setting->saveValue();
}
m_changedSettings.clear();
}
void saveAllSettings()
{
for ( auto& setting : m_boolSettings )
{
setting.saveValue();
}
}
template <typename ReturnType, typename Setting>
[[nodiscard]] ReturnType getSetting( const Setting setting ) const noexcept
{
const auto index = static_cast<std::size_t>( setting );
if constexpr ( std::is_same<Setting, BoolSetting>::value )
{
return m_boolSettings[index].value();
}
else if constexpr ( std::is_same<Setting, DoubleSetting>::value )
{
return m_doubleSettings[index].value();
}
else if constexpr ( std::is_same<Setting, IntSetting>::value )
{
return m_intSettings[index].value();
}
else if constexpr ( std::is_same<Setting, StringSetting>::value )
{
return m_stringSettings[index].value();
}
}
template <typename Setting, typename Type>
void setSetting( const Setting setting, const Type value ) noexcept
{
const auto index = static_cast<std::size_t>( setting );
if constexpr ( std::is_same<Setting, BoolSetting>::value )
{
auto& s = m_boolSettings[index];
s.setValue( value );
m_changedSettings.push_back( &s );
}
else if constexpr ( std::is_same<Setting, DoubleSetting>::value )
{
auto& s = m_doubleSettings[index];
s.setValue( value );
m_changedSettings.push_back( &s );
}
else if constexpr ( std::is_same<Setting, IntSetting>::value )
{
auto& s = m_intSettings[index];
s.setValue( value );
m_changedSettings.push_back( &s );
}
else if constexpr ( std::is_same<Setting, StringSetting>::value )
{
auto& s = m_stringSettings[index];
s.setValue( value );
m_changedSettings.push_back( &s );
}
}
private:
std::vector<SettingValue*> m_changedSettings{};
constexpr static auto boolSettingSize
= static_cast<int>( BoolSetting::LAST_ENUMERATOR ) + 1;
std::array<BoolSettingValue, boolSettingSize> m_boolSettings{
BoolSettingValue{ BoolSetting::PLAYSPACE_lockXToggle,
SettingCategory::Playspace,
QtInfo{ "lockXToggle" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_lockYToggle,
SettingCategory::Playspace,
QtInfo{ "lockYToggle" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_lockZToggle,
SettingCategory::Playspace,
QtInfo{ "lockZToggle" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_momentumSave,
SettingCategory::Playspace,
QtInfo{ "momentumSave" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_turnBindLeft,
SettingCategory::Playspace,
QtInfo{ "turnBindLeft" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_turnBindRight,
SettingCategory::Playspace,
QtInfo{ "turnBindRight" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_turnBounds,
SettingCategory::Playspace,
QtInfo{ "turnBounds" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_moveShortcutLeft,
SettingCategory::Playspace,
QtInfo{ "moveShortcutLeft" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_moveShortcutRight,
SettingCategory::Playspace,
QtInfo{ "moveShortcutRight" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_dragBounds,
SettingCategory::Playspace,
QtInfo{ "dragBounds" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_allowExternalEdits,
SettingCategory::Playspace,
QtInfo{ "allowExternalEdits" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_oldStyleMotion,
SettingCategory::Playspace,
QtInfo{ "oldStyleMotion" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_universeCenteredRotation,
SettingCategory::Playspace,
QtInfo{ "universeCenteredRotation" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_enableSeatedMotion,
SettingCategory::Playspace,
QtInfo{ "enableSeatedMotion" },
false },
BoolSettingValue{ BoolSetting::APPLICATION_disableVersionCheck,
SettingCategory::Application,
QtInfo{ "disableVersionCheck" },
false },
BoolSettingValue{ BoolSetting::APPLICATION_previousShutdownSafe,
SettingCategory::Application,
QtInfo{ "previousShutdownSafe" },
true },
BoolSettingValue{ BoolSetting::VIDEO_brightnessEnabled,
SettingCategory::Video,
QtInfo{ "brightnessEnabled" },
false },
BoolSettingValue{ BoolSetting::VIDEO_isOverlayMethodActive,
SettingCategory::Video,
QtInfo{ "isOverlayMethodActive" },
false },
BoolSettingValue{ BoolSetting::VIDEO_colorOverlayEnabled,
SettingCategory::Video,
QtInfo{ "colorOverlayEnabled" },
false },
BoolSettingValue{ BoolSetting::CHAPERONE_disableChaperone,
SettingCategory::Chaperone,
QtInfo{ "disableChaperone" },
false },
};
constexpr static auto doubleSettingSize
= static_cast<int>( DoubleSetting::LAST_ENUMERATOR ) + 1;
std::array<DoubleSettingValue, doubleSettingSize> m_doubleSettings{
DoubleSettingValue{ DoubleSetting::UTILITY_desktopWidth,
SettingCategory::Utility,
QtInfo{ "desktopWidth" },
4.0 },
DoubleSettingValue{ DoubleSetting::VIDEO_brightnessOpacityValue,
SettingCategory::Video,
QtInfo{ "brightnessOpacityValue" },
0.0 },
DoubleSettingValue{ DoubleSetting::VIDEO_brightnessValue,
SettingCategory::Video,
QtInfo{ "brightnessValue" },
1.0 },
DoubleSettingValue{ DoubleSetting::VIDEO_colorOverlayOpacity,
SettingCategory::Video,
QtInfo{ "colorOverlayOpacity" },
0.0 },
DoubleSettingValue{ DoubleSetting::VIDEO_colorRed,
SettingCategory::Video,
QtInfo{ "colorRed" },
1.0 },
DoubleSettingValue{ DoubleSetting::VIDEO_colorGreen,
SettingCategory::Video,
QtInfo{ "colorGreen" },
1.0 },
DoubleSettingValue{ DoubleSetting::VIDEO_colorBlue,
SettingCategory::Video,
QtInfo{ "colorBlue" },
1.0 },
DoubleSettingValue{ DoubleSetting::VIDEO_colorRedNew,
SettingCategory::Video,
QtInfo{ "colorRedNew" },
1.0 },
DoubleSettingValue{ DoubleSetting::VIDEO_colorGreenNew,
SettingCategory::Video,
QtInfo{ "colorGreenNew" },
1.0 },
DoubleSettingValue{ DoubleSetting::VIDEO_colorBlueNew,
SettingCategory::Video,
QtInfo{ "colorBlueNew" },
1.0 },
DoubleSettingValue{ DoubleSetting::CHAPERONE_switchToBeginnerDistance,
SettingCategory::Video,
QtInfo{ "switchToBeginnerDistance" },
0.5 },
DoubleSettingValue{ DoubleSetting::CHAPERONE_hapticFeedbackDistance,
SettingCategory::Video,
QtInfo{ "hapticFeedbackDistance" },
0.5 },
DoubleSettingValue{ DoubleSetting::CHAPERONE_alarmSoundDistance,
SettingCategory::Video,
QtInfo{ "alarmSoundDistance" },
0.5 },
DoubleSettingValue{ DoubleSetting::CHAPERONE_showDashboardDistance,
SettingCategory::Video,
QtInfo{ "showDashboardDistance" },
0.5 },
DoubleSettingValue{ DoubleSetting::CHAPERONE_fadeDistanceRemembered,
SettingCategory::Chaperone,
QtInfo{ "fadeDistanceRemembered" },
0.5 },
};
constexpr static auto stringSettingsSize
= static_cast<int>( StringSetting::LAST_ENUMERATOR ) + 1;
constexpr static auto discordDefaultMuteKeybinding = "^>m";
std::array<StringSettingValue, stringSettingsSize> m_stringSettings{
StringSettingValue{ StringSetting::KEYBOARDSHORTCUT_keyboardOne,
SettingCategory::KeyboardShortcut,
QtInfo{ "keyboardOne" },
discordDefaultMuteKeybinding },
StringSettingValue{ StringSetting::KEYBOARDSHORTCUT_keyboardTwo,
SettingCategory::KeyboardShortcut,
QtInfo{ "keyboardTwo" },
discordDefaultMuteKeybinding },
StringSettingValue{ StringSetting::KEYBOARDSHORTCUT_keyboardThree,
SettingCategory::KeyboardShortcut,
QtInfo{ "keyboardThree" },
discordDefaultMuteKeybinding },
};
constexpr static auto intSettingsSize
= static_cast<int>( IntSetting::LAST_ENUMERATOR ) + 1;
std::array<IntSettingValue, intSettingsSize> m_intSettings{
IntSettingValue{ IntSetting::UTILITY_alarmHour,
SettingCategory::Utility,
QtInfo{ "alarmHour" },
0 },
IntSettingValue{ IntSetting::UTILITY_alarmMinute,
SettingCategory::Utility,
QtInfo{ "alarmMinute" },
0 },
};
};
} // namespace settings
+90
View File
@@ -0,0 +1,90 @@
#pragma once
#include <QSettings>
#include <string>
#include <type_traits>
#include "../overlaycontroller.h"
namespace settings
{
enum class SettingCategory
{
Utility,
KeyboardShortcut,
Playspace,
Application,
Video,
Chaperone,
ChaperoneProfiles,
};
struct QtInfo
{
const std::string settingName;
};
[[nodiscard]] QSettings& getQSettings()
{
static QSettings s( QSettings::IniFormat,
QSettings::UserScope,
application_strings::applicationOrganizationName,
application_strings::applicationName );
return s;
}
[[nodiscard]] std::string getQtCategoryName( const SettingCategory category )
{
switch ( category )
{
case SettingCategory::Utility:
return "utilitiesSettings";
case SettingCategory::KeyboardShortcut:
return "keyboardShortcuts";
case SettingCategory::Playspace:
return "playspaceSettings";
case SettingCategory::Application:
return "applicationSettings";
case SettingCategory::Video:
return "videoSettings";
case SettingCategory::Chaperone:
return "chaperoneSettings";
case SettingCategory::ChaperoneProfiles:
return "chaperoneProfiles";
}
return "no-value";
}
[[nodiscard]] QVariant getQtSetting( const SettingCategory category,
const std::string qtSettingName )
{
getQSettings().beginGroup( getQtCategoryName( category ).c_str() );
const auto v = getQSettings().value( qtSettingName.c_str() );
getQSettings().endGroup();
return v;
}
void saveQtSetting( const SettingCategory category,
const std::string qtSettingName,
const QVariant value )
{
getQSettings().beginGroup( getQtCategoryName( category ).c_str() );
getQSettings().setValue( qtSettingName.c_str(), value );
getQSettings().endGroup();
}
[[nodiscard]] bool isValidQVariant( const QVariant v,
const QMetaType::Type type )
{
const auto savedSettingIsValid
= v.isValid() && !v.isNull() && ( v.userType() == type );
if ( savedSettingIsValid )
{
return true;
}
return false;
}
} // namespace settings
+130
View File
@@ -0,0 +1,130 @@
#pragma once
#include <type_traits>
#include "setting_value.h"
#include "settings.h"
namespace settings
{
template <typename Value, typename Setting>
class SpecificSettingValue : public SettingValue
{
public:
SpecificSettingValue( const Setting setting,
const SettingCategory category,
const QtInfo qtInfo,
const Value defaultValue )
: SettingValue( category, qtInfo ), m_setting( setting ),
m_value( defaultValue )
{
// Only allow explicitly defined types to curtail unintended behavior
constexpr auto isBool = std::is_same<Value, bool>::value;
constexpr auto isDouble = std::is_same<Value, double>::value;
constexpr auto isString = std::is_same<Value, std::string>::value;
constexpr auto isInt = std::is_same<Value, int>::value;
static_assert( isBool || isDouble || isString || isInt );
const auto v = getQtSetting( SettingValue::category(),
SettingValue::qtInfo().settingName );
QMetaType::Type type;
if constexpr ( std::is_same<Value, bool>::value )
{
type = QMetaType::Bool;
}
else if constexpr ( std::is_same<Value, double>::value )
{
type = QMetaType::Double;
}
else if constexpr ( std::is_same<Value, std::string>::value )
{
type = QMetaType::QString;
}
else if constexpr ( std::is_same<Value, int>::value )
{
type = QMetaType::Int;
}
if ( isValidQVariant( v, type ) )
{
if constexpr ( std::is_same<Value, bool>::value )
{
m_value = v.toBool();
}
else if constexpr ( std::is_same<Value, double>::value )
{
m_value = v.toDouble();
}
else if constexpr ( std::is_same<Value, std::string>::value )
{
m_value = v.toString().toStdString();
}
else if constexpr ( std::is_same<Value, int>::value )
{
m_value = v.toInt();
}
}
else
{
// If setting doesn't exist, create it automatically
saveValue();
}
}
void setValue( const Value value ) noexcept
{
m_value = value;
}
[[nodiscard]] Value value() const noexcept
{
return m_value;
}
[[nodiscard]] Setting setting() const noexcept
{
return m_setting;
}
[[nodiscard]] SettingCategory category() const noexcept
{
return SettingValue::category();
}
[[nodiscard]] QtInfo qtInfo() const noexcept
{
return SettingValue::qtInfo();
}
void saveValue() override
{
if constexpr ( !std::is_same<Value, std::string>::value )
{
saveQtSetting( SettingValue::category(),
SettingValue::qtInfo().settingName,
m_value );
}
else
{
// Special case for std::string because it can't be auto
// converted to QVariant
saveQtSetting( SettingValue::category(),
SettingValue::qtInfo().settingName,
m_value.c_str() );
}
}
private:
const Setting m_setting;
Value m_value;
};
using BoolSettingValue = SpecificSettingValue<bool, BoolSetting>;
using DoubleSettingValue = SpecificSettingValue<double, DoubleSetting>;
using IntSettingValue = SpecificSettingValue<int, IntSetting>;
using StringSettingValue = SpecificSettingValue<std::string, StringSetting>;
} // namespace settings
+1
View File
@@ -17,6 +17,7 @@ enum ReturnErrorCode
SUCCESS = 0,
GENERAL_FAILURE = -1,
OPENVR_INIT_ERROR = -2,
SETTING_INCORRECT_INDEX = -3,
};
struct CommandLineOptions